LEMPソフトウェアスタックは、PHPで記述された動的WebページとWebアプリケーションの提供に使用できるソフトウェアのグループです。これは、Nginx(「 Engine-X」と発音)Webサーバーを備えたL ** inuxオペレーティングシステムを表す頭字語です。バックエンドデータはMySQLデータベースに保存されており、動的コンテンツはP**HPが処理を行います。
このガイドは、Ubuntu 20.04サーバーにLEMPスタックをインストールする方法を示します。Ubuntuオペレーティングシステムが最初の要件を処理します。ここでは、残りのコンポーネントを起動して実行する方法を説明します。
このチュートリアルを完了するには、Ubuntu 20.04サーバーに通常のroot以外のsudo
ユーザーとしてアクセス可能で、サーバーでファイアウォールが有効になっている必要があります。 これをセットアップするには、Ubuntu 20.04 初期サーバーセットアップ設定ガイドを参照してください。
サイト訪問者にWebページを表示するために、高性能なWebサーバーであるNginxを採用します。apt
パッケージマネージャーを使用して、このソフトウェアを入手します。
ここで初めてapt
を使用するので、サーバーのパッケージインデックスを更新することから始めます。 その後、apt install
を使用してNginxをインストールします。
- sudo apt update
- sudo apt install nginx
Nginxをインストールするか確認を求められたら、Y
を入力します。インストールが完了すると、Ubuntu 20.04サーバー上でNginx Webサーバーはアクティブになり、稼働します。
初期セットアップガイドでも推奨されているように、ufw
ファイアウォールを有効にしている場合は、Nginxへの接続を許可する必要があります。Nginxには、インストール時にufwアプリケーションプロファイルがいくつか登録されています。使用可能なUFWプロファイルを確認するには、次を実行します。
- sudo ufw app list
OutputAvailable applications:
Nginx Full
Nginx HTTP
Nginx HTTPS
OpenSSH
必要なトラフィックを許可しながら、最も制限の厳しいプロファイルを有効にすることをお勧めします。 このガイドではまだサーバーにSSLを設定していないため、ポート80
で通常のHTTPトラフィックを許可する設定にとどめます。
次を入力してこれを有効にします。
- sudo ufw allow 'Nginx HTTP'
次のコマンドを実行して、変更を確認できます。
- sudo ufw status
このコマンドの出力は、HTTPトラフィックが許可されていることを示します。
OutputStatus: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
Nginx HTTP ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
Nginx HTTP (v6) ALLOW Anywhere (v6)
新しいファイアウォールルールを追加したら、Webブラウザでサーバーのドメイン名またはパブリックIPアドレスにアクセスして、サーバーが稼働しているかテストします。
サーバーを指すドメイン名がなく、サーバーのパブリックIPアドレスがわからない場合は、次のコマンドを実行して見つけることができます。
- ip addr show eth0 | grep inet | awk '{ print $2; }' | sed 's/\/.*$//'
これにより、IPアドレスがいくつか出力されます。 Webブラウザでそれぞれを順番に試すことができます。
別の方法として、インターネット上の他の場所から表示されるアクセス可能なIPアドレスを確認できます。
- curl -4 icanhazip.com
Webブラウザで受け取ったアドレスを入力すると、Nginxのデフォルトのランディングページに移動します。
http://server_domain_or_IP
このページが表示されたら、Nginxが正常にインストールされ、WebサーバーのHTTPトラフィックが有効になっています。
Webサーバーを起動し実行したので、サイトのデータを保存および管理できるようにデータベースシステムをインストールする必要があります。MySQLはPHP環境で使用されている人気のデータベース管理システムです。
もう一度、apt
を使用してこのソフトウェアを取得およびインストールします。
- sudo apt install mysql-server
画面が表示されたら、Y
を入力してからENTER
キーを押して、インストールを確認します。
インストールが完了したら、MySQLがプリインストールされたセキュリティスクリプトを実行することをお勧めします。このスクリプトは、セキュリティに懸念のあるデフォルト設定の一部を削除し、データベースシステムへのアクセスをロックします。次を実行してインタラクティブスクリプトを起動します。
- sudo mysql_secure_installation
VALIDATE PASSWORD PLUGIN
を設定したいかを尋ねられます。
注: この機能を有効にするかどうかは、判断する余地があります。有効にすると、指定した条件に一致しないパスワードはエラーとしてMySQLによって拒否されます。検証機能を無効にすれば安全ですが、データベース資格情報に常に強力でユニークなパスワードを使用する必要があります。
「はい」の場合はY
と回答し、有効化せずに続行する場合は他の回答にしてください。
VALIDATE PASSWORD PLUGIN can be used to test passwords
and improve security. It checks the strength of password
and allows the users to set only those passwords which are
secure enough. Would you like to setup VALIDATE PASSWORD plugin?
Press y|Y for Yes, any other key for No:
「はい」に答えると、パスワード検証のレベルを選択するよう画面が表示されます。最強レベルに2
を入力すると、数字、大文字、小文字、特殊文字を含まないパスワードや、一般的な辞書に出てくる単語をベースにした文字をパスワードとして設定するとエラーとなることに注意してください。
There are three levels of password validation policy:
LOW Length >= 8
MEDIUM Length >= 8, numeric, mixed case, and special characters
STRONG Length >= 8, numeric, mixed case, special characters and dictionary file
Please enter 0 = LOW, 1 = MEDIUM and 2 = STRONG: 1
VALIDATE PASSWORD PLUGIN
を設定したかどうかに関わらず、サーバーから次にMySQLrootユーザーのパスワードを選択して確認するよう求められます。これはシステムrootと混同されません。データベースrootユーザーは、データベースシステム上の権限を持つ管理ユーザーです。MySQL rootユーザーのデフォルト認証方法はパスワードを使用しませんが、1つが設定されている場合でも、追加の安全対策としてここで強力なパスワードを定義する必要があります。この点については後でお話します。
パスワード検証を有効にした場合は、入力したrootパスワードのパスワード強度が表示されます。お使いのサーバーからそのパスワードで続行するかどうか尋ねられます。現在のパスワードでよければ、画面の表示でY
と入力します。
Estimated strength of the password: 100
Do you wish to continue with the password provided?(Press y|Y for Yes, any other key for No) : y
残りの質問については、画面の表示が現れるたびにY
を押してからENTER
キーを押します。これにより、一部の匿名ユーザーとテストデータベースを削除し、リモートrootログインを無効にし、MySQLが行なった変更をすぐに反映できるようにこれらの新しいルールをロードします。
完了したら、次を入力してMySQLコンソールにログインできるかどうかをテストします。
- sudo mysql
これにより、管理データベースユーザーrootとしてMySQLサーバーに接続することができます。このコマンドを実行する際にsudo
を使用することで推測されます。出力は次のようになります。
OutputWelcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 22
Server version: 8.0.19-0ubuntu5 (Ubuntu)
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
MySQLコンソールを終了するには、次のように入力します。
- exit
mysql_secure_installation
スクリプトを実行する際にパスワードを定義しているにもかかわらず、rootユーザーとして接続するためにパスワードを指定する必要がないことに注意してください。これは、管理者MySQLユーザーのデフォルトの認証方法が、password
ではなくunix_socketであるためです。これはセキュリティ上の問題のように見えるかもしれませんが、MySQLのrootユーザーとしてログインできるのは、sudo権限を持つシステムユーザーのみであり、コンソールから接続するか、同じ権限を持つアプリケーションを介して接続することができるため、データベースサーバーをより安全なものにしています。実用的な意味では、管理データベースのrootユーザーを使用してPHPアプリケーションから接続することができないということになります。root MySQLアカウントにパスワードを設定することは、デフォルトの認証方法がunix_socket
からpassword
に変更された場合のセーフガードとして機能します。``
セキュリティを強化するためには、特にサーバー上に複数のデータベースをホストしている場合は、データベースごとに拡張性の低い専用のユーザーアカウントを設定しておくとよいでしょう。
**注: **執筆時点では、ネイティブのMySQL PHPライブラリmysqlnd
は、MySQL 8のデフォルトの認証方法であるcaching_sha2_authentication
をサポートしていません。そのため、MySQL 8でPHPアプリケーションのデータベースユーザーを作成する際には、代わりにmysql_native_password
を使用するように設定されていることを確認する必要があります。ステップ6でその方法について説明します。
これで MySQL サーバーがインストールされ、セキュリティが確保されました。次に、LEMPスタックの最後のコンポーネント、PHPをインストールします。
コンテンツを提供するNginxがインストールされ、データを保存および管理するMySQLがインストールされました。今度はコードを処理し、Webサーバーに動的コンテンツを生成するPHPをインストールします。
ApacheがPHPインタプリタを各リクエストに組み込むのに対し、Nginxは、PHP処理を行い、PHPインタプリタ自体とWebサーバーとの懸け橋として動作する外部プログラムを必要とします。これにより、ほとんどのPHPベースのWebサイトで全体的なパフォーマンスが向上できますが、追加設定が必要です。「PHP fastCGIプロセスマネージャー」を表すphp-fpm
をインストールし、このソフトウェアにPHPリクエストを渡すよう、Nginxに指示します。また、PHPとMySQLベースのデータベースとの通信を可能にするPHPモジュールphp-mysql
も必要です。 コアとなるPHPパッケージは依存関係として自動的にインストールされます。
php-fpm
とphp-mysql
パッケージをインストールするには、次を実行します。
- sudo apt install php-fpm php-mysql
インストールするか確認を求められたら、Y
、ENTER
キーを押します。
これで、PHPコンポーネントがインストールされました。次に、Nginxを設定して使用します。
Nginx Webサーバーを使用する場合、server blocks(Apacheの仮想ホストに類似)を作成すると、詳細設定をカプセル化して、単一サーバーで複数のドメインのホストが可能になります。 このガイドでは、your_domainをドメイン名の例として使用します。 DigitalOceanを使用したドメイン名の設定の詳細については、DigitalOcean DNSの紹介をご覧ください。
Ubuntu 20.04のNginxには、デフォルトで有効になっているサーバーブロックが1つあり、/var/ www/html
内のディレクトリからドキュメントを提供するように設定されています。これは単一のサイトではうまく機能しますが、複数のサイトをホストしている場合は扱いにくいことがあります。var/www/html
を修正する代わりに、クライアントのリクエストが他のサイトと一致しない場合に表示されるデフォルトのディレクトリとして/var/www/html
をそのまま残し、/var/www
内にyour_domainWebサイトのディレクトリ構造を作成します。
your_domainのroot webディレクトリを次のように作成します。
- sudo mkdir /var/www/your_domain
次に、現在のシステムユーザーを参照する環境変数$USERでディレクトリの所有権を割り当てます。
- sudo chown -R $USER:$USER /var/www/your_domain
それから、お好みのコマンドラインエディタを使ってNginxのsites-available
ディレクトリでに新しい設定ファイルを開きます。 ここでは、nano
を使用します。
- sudo nano /etc/nginx/sites-available/your_domain
これにより、新しい空白ファイルを作成します。次のbare-bones 設定に貼り付けます。
server {
listen 80;
server_name your_domain www.your_domain;
root /var/www/your_domain;
index index.html index.htm index.php;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
これらの各ディレクティブとロケーションブロックの機能は次のとおりです。
listen
ーNginxがリッスンするポートを定義します。この場合、HTTPのデフォルトポートであるポート80
でリッスンします。root
— Webサイトが提供するファイルが保存されるドキュメントルートを定義します。index
— Nginxが優先するWebサイトのインデックスファイルの順位を定義します。PHPアプリケーションでメンテナンスランディングページを手早くセットアップできるように、index.html
ファイルの優先順位はindex.php
ファイルより高いのが一般的です。 アプリケーションニーズに合わせてこれらの設定を調整できます。server_name
— このサーバーブロックがどのドメイン名および/またはIPアドレスに応答するかを定義します。このディレクティブをサーバーのドメイン名またはパブリックIPアドレスに指定します。location /
— 最初のロケーションブロックに含まれるtry_files
は、URIリクエストに一致するファイル やディレクトリをチェックします。Nginxが該当するリソースを見つけられない場合、404エラーを返します。location ~ \.php$
ーこのロケーションブロックは、実際のPHP処理を行い、Nginxを設定ファイルfastcgi-php.conf
とソケットファイルphp7.4-fpm.sock
に接続します。php7.4-fpm.sockはphp-fpm
と関連付けされたソケットを宣言します。location ~ /\.ht
— 最後のロケーションブロックは、Nginxが処理しない.htaccess
ファイルを処理します。deny all
ディレクティブを追加することにより、.htaccess
ファイルがたまたまドキュメントルートを見つけても、訪問者がアクセスできないようにします。編集が完了したら、ファイルを保存して閉じます。 nano
を使用した場合は、CTRL + X
、Y
、ENTER
キーを押します。
Nginxのsites-enabled
ディレクトリから、設定ファイルにリンクして設定を有効化します。
- sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/
これは、Nginxが次回のリロード時にこの設定を使用するよう、Nginxに指示するものです。 次を入力して新しい設定に構文エラーがないかテストします。
- sudo nginx -t
エラーが報告された場合は、設定ファイルに戻って内容を再確認してから続行してください。
準備ができたら、Nginxをリロードして変更を反映します。
- sudo systemctl reload nginx
新しいWebサイトはアクティブになりましたが、Web root /var/www/your_domain
はまだ空です。同じ場所にindex.html
ファイルを作成し、バーチャルホストが期待通りに動作するかどうかテストます。
- nano /var/www/your_domain/index.html
このファイルに以下のコンテンツを含みます。
<html>
<head>
<title>your_domain website</title>
</head>
<body>
<h1>Hello World!</h1>
<p>This is the landing page of <strong>your_domain</strong>.</p>
</body>
</html>
次にブラウザから、server_name
ディレクティブ内の記載通り、サーバーのドメイン名またはIPアドレスへアクセスします。
http://server_domain_or_IP
以下のページが表示されます。
このページが表示されたら、お使いのNginxサーバーブロックが期待通りに動作していることを意味します。
このファイルは、index.php
ファイルを置き換えるために設定するまでの間、アプリケーションの一時的なランディングページとして残しておくことができます。設定したら、忘れずにindex.html
ファイルをドキュメントrootから削除するか、名前を変更してください。デフォルトではindex.php
ファイルよりも優先されます。
これでLEMPスタックの設定は完了です。次のステップでは、Nginxが新たに設定したWebサイトで.php
ファイルを実際に処理できるかテストするPHPスクリプトを作成します。
これでLEMPスタックは完全にセットアップされました。Nginxが問題なく php
ファイルをPHPプロセッサに渡せるか、検証テストを実施します。
これを行うには、ドキュメントrootにテストPHPファイルを作成します。テキストエディターで、ドキュメントルートに info.php
という名前の新しいファイルを開きます。
- nano /var/www/your_domain/info.php
新しいファイルに次の行を入力するか貼り付けます。 これは、サーバー情報を返す有効なPHPコードです。
<?php
phpinfo();
完了したら、CTRL
+X
、Y
、ENTER
キーの順に押してファイルを保存して閉じます。
これで、Webサイトに設定されているドメイン名またはパブリックIPアドレスの後に/info.php
を続けて、このページにアクセスすることができるようになりました。
http://server_domain_or_IP/info.php
サーバーに関する詳細情報が載ったWebページが表示されます。
このページ上のPHPサーバーに関する情報を確認した後は、作成したファイルにはPHP環境およびUbuntuサーバーに関する機密情報が含まれているため、削除しておいた方がよいでしょう。rm
を使用して、ファイルを削除できます。
- sudo rm /var/www/your_domain/info.php
後で必要になった場合は、いつでもこのファイルを再生成できます。
PHPがMySQLに接続してデータベースクエリを実行できるかどうかをテストしたい場合は、ダミーデータを含むテストテーブルを作成し、PHPスクリプトからそのコンテンツをクエリすることができます。その前に、テスト用のデータベースを作成し、それにアクセスできるように適切に設定された新しいMySQLユーザーを用意する必要があります。
執筆時点では、ネイティブのMySQL PHPライブラリであるmysqlnd
は、MySQL 8のデフォルトの認証方法であるcaching_sha2_authentication
をサポートしていません。PHPからMySQLデータベースに接続できるようにするためには、mysql_native_password
認証方法で新しいユーザーを作成する必要があります。
ここではexample_databaseという名前のデータベースと example_user という名前のユーザーを作成しますが、これらの名前は別の値に置き換えることができます。
まず、rootアカウントを使用して、MySQLコンソールに接続します。
- sudo mysql
新しいデータベースを作成するには、MySQLコンソールから以下のコマンドを実行します。
- CREATE DATABASE example_database;
これで、新しいユーザーを作成し、作成したカスタムデータベースに完全な権限を付与できます。
次のコマンドは、デフォルトの認証方法としてmysql_native_password
を使用して、example_user
という名前の新しいユーザーを作成します。 このユーザーのパスワードをpassword
として定義していますが、この値を自分で選択した安全なパスワードに置き換えておくとよいでしょう。
- CREATE USER 'example_user'@'%' IDENTIFIED WITH mysql_native_password BY 'password';
ここで、このユーザーにexample_database
データベースに対する権限を与える必要があります。
- GRANT ALL ON example_database.* TO 'example_user'@'%';
これにより、example_userユーザーにexample_databaseデータベースに対する完全な権限が与えられ、またこのユーザーによるサーバー上の他のデータベースの作成・変更を防ぎます。
以下を使用してMySQLシェルを終了します。
- exit
新しいユーザーが適切な権限を持っているかどうかは、MySQLコンソールに再度ログインしてテストすることができます。カスタムユーザーの資格を使用します。
- mysql -u example_user -p
このコマンドの -p
フラグに注意してください。これは、example_userユーザーを作成する際に使用したパスワードを要求します。MySQLコンソールにログインした後、example_databaseデータベースにアクセスできることを確認してください。
- SHOW DATABASES;
これにより、以下が出力されます。
Output+--------------------+
| Database |
+--------------------+
| example_database |
| information_schema |
+--------------------+
2 rows in set (0.000 sec)
次に、todo_listという名前のテストテーブルを作成します。MySQLコンソールから、次のステートメントを実行します。
- CREATE TABLE example_database.todo_list (
- item_id INT AUTO_INCREMENT,
- content VARCHAR(255),
- PRIMARY KEY(item_id)
- );
テストテーブルにコンテンツの数行を挿入します。異なる値を使用して、次のコマンドを数回繰り返したい場合があります。
- INSERT INTO example_database.todo_list (content) VALUES ("My first important item");
データが正常にテーブルに保存されたことを確認するには、以下を実行します。
- SELECT * FROM example_database.todo_list;
次の出力が表示されます。
Output+---------+--------------------------+
| item_id | content |
+---------+--------------------------+
| 1 | My first important item |
| 2 | My second important item |
| 3 | My third important item |
| 4 | and this one more thing |
+---------+--------------------------+
4 rows in set (0.000 sec)
テストテーブルに有効なデータがあることを確認した後、MySQLコンソールを終了できます。
- exit
これで、MySQLに接続してコンテンツにクエリを出すPHPスクリプトを作成することができます。お好みのエディタを使用して、カスタムWeb rootディレクトリに新しいPHPファイルを作成してください。ここでは、nano
を使用します。
- nano /var/www/your_domain/todo_list.php
次のPHPスクリプトは、MySQLデータベースに接続してtodo_listテーブルの内容をクエリし、結果をリストで表示します。データベース接続に問題がある場合、例外をスローします。このコンテンツをtodo_list.php
スクリプトにコピーします。
<?php
$user = "example_user";
$password = "password";
$database = "example_database";
$table = "todo_list";
try {
$db = new PDO("mysql:host=localhost;dbname=$database", $user, $password);
echo "<h2>TODO</h2><ol>";
foreach($db->query("SELECT content FROM $table") as $row) {
echo "<li>" . $row['content'] . "</li>";
}
echo "</ol>";
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
編集が完了したら、ファイルを保存して閉じます。
これで、ウェブサイトに設定されているドメイン名またはパブリックIPアドレスの後に、/todo_list.php
を続けて、このページにアクセスすることができます。
http://server_domain_or_IP/todo_list.php
ページが表示され、テストテーブルに挿入したコンテンツが表示されます。
これでPHP環境はあなたのMySQLサーバーと接続してやりとりする準備ができました。
このガイドでは、WebサーバーとしてNginxを、データベースシステムとしてMySQLを使用して、訪問者にPHP Webサイトやアプリケーションを提供するための柔軟な基盤を構築しました。
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Sign up for Infrastructure as a Newsletter.
Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.