このトピックでは、パッケージマネージャを使用して Elastic Compute Service (ECS) インスタンス上に LNMP (Linux、Nginx、MySQL、PHP) スタックを構築する方法を順を追って説明します。Alibaba Cloud Linux、CentOS、Ubuntu を含む複数のオペレーティングシステムをサポートしています。手動でデプロイすることにより、設定ファイルのカスタマイズを複雑にしがちなビルド済みイメージの制限を克服できます。このアプローチにより、基盤環境を完全に制御し、WordPress や Magento などの動的 Web サイトの本番環境の要件を満たすためのセキュリティ強化が可能になります。
仕組み
|
操作手順
スムーズな操作のため、少なくとも 2 GiB のメモリを搭載した ECS インスタンスを推奨します。
ステップ 1:インスタンスの準備
インスタンスがインターネットからアクセスできるようにパブリック IP アドレスとセキュリティグループを設定し、潜在的なセキュリティ脆弱性にパッチを適用するためにシステムコンポーネントを更新します。
パブリックネットワークアクセスの設定
ご利用の ECS インスタンスにパブリック IP アドレスが割り当てられているか、Elastic IP Address (EIP) がバインドされていることを確認してください。詳細な手順については、「パブリック帯域幅の設定」をご参照ください。
セキュリティグループルールの追加
ご利用の ECS インスタンスに関連付けられているセキュリティグループで、TCP ポート 80 (HTTP アクセス用) のトラフィックを許可するインバウンドルールを追加します。詳細な手順については、「セキュリティグループルールの追加」をご参照ください。
システムとソフトウェアパッケージの更新
Alibaba Cloud Linux 3 / CentOS 8
ECS インスタンスにログインします。
ECS コンソール - インスタンス に移動します。上部のナビゲーションバーで、対象のリージョンとリソースグループを選択します。
インスタンスの詳細ページに移動し、[接続] をクリックして [ワークベンチ] を選択します。画面の指示に従ってログインし、ターミナルを開きます。
パッケージインデックスを更新し、すべてのパッケージを最新バージョンにアップグレードします。
sudo dnf update -y
Alibaba Cloud Linux 2 / CentOS 7
ECS インスタンスにログインします。
ECS コンソール - インスタンス に移動します。上部のナビゲーションバーで、対象のリージョンとリソースグループを選択します。
インスタンスの詳細ページで、[接続] をクリックし、ワークベンチ を選択します。画面の指示に従ってログインし、ターミナルを開きます。
すべてのパッケージを最新バージョンに更新します。
sudo yum update -y
Ubuntu
ECS インスタンスにログインします。
ECS コンソール - インスタンス に移動します。上部のナビゲーションバーで、対象のリージョンとリソースグループを選択します。
インスタンスの詳細ページで、[接続] をクリックし、ワークベンチ を選択します。画面の指示に従ってログインし、ターミナルを開きます。
すべてのパッケージを最新バージョンに更新します。
sudo apt update -y && sudo apt upgrade -y
ステップ 2:Nginx のインストールと設定
Nginx の公式リポジトリを追加し、Nginx をインストールします。
Alibaba Cloud Linux 3 / CentOS 8
# Nginx の公式リポジトリを追加します。 sudo tee /etc/yum.repos.d/nginx.repo <<-'EOF' [nginx-stable] name=nginx stable repo baseurl=https://nginx.org/packages/centos/8/$basearch/ gpgcheck=1 enabled=1 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true EOF # Nginx をインストールします。 sudo dnf -y install nginxAlibaba Cloud Linux 2 / CentOS 7
# Nginx の公式リポジトリを追加します。 sudo tee /etc/yum.repos.d/nginx.repo <<-'EOF' [nginx-stable] name=nginx stable repo baseurl=https://nginx.org/packages/centos/7/$basearch/ gpgcheck=1 enabled=1 gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true EOF # Nginx をインストールします。 sudo yum -y install nginxUbuntu
# Nginx の依存関係をインストールします。 sudo apt install -y curl gnupg2 ca-certificates lsb-release ubuntu-keyring # パッケージソースを検証するために、Nginx の公式署名キーをインポートします。 curl https://nginx.org/keys/nginx_signing.key | gpg --dearmor | sudo tee /usr/share/keyrings/nginx-archive-keyring.gpg >/dev/null # Nginx の APT リポジトリを設定します。 echo "deb [signed-by=/usr/share/keyrings/nginx-archive-keyring.gpg] http://nginx.org/packages/ubuntu `lsb_release -cs` nginx" | sudo tee /etc/apt/sources.list.d/nginx.list # Nginx をインストールします。 sudo apt update sudo apt install -y nginxNginx を起動し、起動時に自動的に開始するように設定します。
enable --nowフラグは、サービスを即座に開始し、起動時に自動的に開始するように設定します。sudo systemctl enable --now nginxNginx サービスを検証します。
curl http://127.0.0.1を実行します。ターミナルが Nginx のウェルカムページの HTML コードを出力した場合、インストールは成功です。
ステップ 3:MySQL のインストールとセキュリティ強化
MySQL をインストールして起動します。
Alibaba Cloud Linux 3 / CentOS 8
# Alibaba Cloud Linux 3 では、古い OpenSSL バージョンとの互換性のために compat-openssl10 が必要です。 if [ -f /etc/os-release ]; then . /etc/os-release if [ "$ID" = "alinux" ] && [ "$VERSION_ID" = "3" ]; then sudo yum install -y compat-openssl10 fi fi # MySQL 8.4 の YUM リポジトリを追加します。 sudo rpm -Uvh https://repo.mysql.com/mysql84-community-release-el8-1.noarch.rpm # MySQL サービスをインストールします。 sudo dnf install -y mysql-serverAlibaba Cloud Linux 2 / CentOS 7
# MySQL 8.4 のリポジトリを追加します。 sudo rpm -Uvh https://repo.mysql.com/mysql84-community-release-el7-1.noarch.rpm # MySQL サービスをインストールします。 sudo yum install -y mysql-serverUbuntu
# デフォルトの Ubuntu リポジトリには MySQL が含まれているため、直接インストールできます。 # Ubuntu 20.04 以降のバージョンでは、デフォルトで MySQL 8.0 がインストールされます。 # Ubuntu 18.04 以前のバージョンでは、デフォルトで MySQL 5.x がインストールされます。 sudo apt install -y mysql-serverMySQL を起動し、起動時に自動的に開始するように設定します。
Alibaba Cloud Linux / CentOS
sudo systemctl enable --now mysqldUbuntu
sudo systemctl enable --now mysqlセキュリティ強化を実行します。
MySQL のデフォルト設定は安全ではなく、匿名ユーザーやリモートでの root ログインが許可されています。付属のセキュリティスクリプトを実行して、これらの脆弱性に対処します。
初期 root パスワードを取得します。
このステップは、Ubuntu がデフォルトでパスワードなしの認証を使用するため、Alibaba Cloud Linux/CentOS にのみ適用されます。次のステップでこの一時パスワードを使用して root パスワードをリセットします。
# ログから一時パスワードを抽出して表示します。 sudo grep 'temporary password' /var/log/mysqld.log強化スクリプトを実行します。
コマンド
sudo mysql_secure_installationを実行し、プロンプトに従って推奨される設定を完了します:root パスワードのリセット:前のステップで取得した一時パスワードを使用してログインし、新しいパスワードを設定します。
少なくとも 12 文字以上で、大文字と小文字、数字、特殊記号を含む強力なパスワードを設定することを推奨します。
匿名ユーザーの削除:Y を入力します。
リモートでの root ログインの禁止:Y を入力します。
テストデータベースの削除:Y を入力します。
権限テーブルのリロード:Y を入力します。
ステップ 4:PHP のインストールと設定
PHP、PHP-FPM (Web リクエスト処理用)、および MySQL ドライバーをインストールします。
PHP リポジトリを追加し、PHP をインストールします。
Alibaba Cloud Linux 3 / CentOS 8
# PHP リポジトリを追加します。 cat > /etc/yum.repos.d/remi.repo << 'EOF' [remi] name=Remi\'s RPM Repository for Enterprise Linux 8 - x86_64 baseurl=https://rpms.remirepo.net/enterprise/8/remi/x86_64/ enabled=1 gpgcheck=1 gpgkey=https://rpms.remirepo.net/RPM-GPG-KEY-remi2024 [remi-safe] name=Remi Safe Repository baseurl=https://rpms.remirepo.net/enterprise/8/safe/x86_64/ enabled=1 gpgcheck=1 gpgkey=https://rpms.remirepo.net/RPM-GPG-KEY-remi2024 EOF # GPG キーをインポートします。 rpm --import https://rpms.remirepo.net/RPM-GPG-KEY-remi2024 # ツールをインストールし、モジュールを有効化します。 dnf install -y yum-utils # PHP をインストールします。 dnf install -y php php-fpm php-mysqlndAlibaba Cloud Linux 2 / CentOS 7
# Remi リポジトリをインストールします。 sudo yum install -y http://rpms.remirepo.net/enterprise/remi-release-7.rpm # yum-utils をインストールし、PHP 8.2 を有効化します。 sudo yum install -y yum-utils sudo yum-config-manager --enable remi-php82 # PHP、PHP-FPM、および MySQL 拡張機能をインストールします。 sudo yum install -y php php-fpm php-mysqlndUbuntu
# PPA 管理ツールをインストールします。 sudo apt install -y software-properties-common # ondrej/php PPA リポジトリを追加します。 sudo add-apt-repository -y ppa:ondrej/php # PHP 8.2、PHP-FPM、および MySQL 拡張機能をインストールします。 sudo apt install -y php8.2 php8.2-fpm php8.2-mysqlPHP-FPM を起動し、起動時に自動的に開始するように設定します。
Alibaba Cloud Linux / CentOS
sudo systemctl enable --now php-fpmUbuntu
sudo systemctl enable --now php8.2-fpm
ステップ 5:PHP 処理をサポートするための Nginx の設定
デフォルトでは、Nginx は静的 Web ページ (HTML や画像など) のみを提供できます。WordPress のような動的 Web サイトをサポートするには、.php ファイルのリクエストを処理のために PHP-FPM に転送するように Nginx を設定する必要があります。そうしないと、PHP ページにアクセスしようとしたときに、ファイルが直接ダウンロードされたり、表示に失敗したりする可能性があります。
Nginx の設定ファイルをバックアップします。
sudo cp /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.bakPHP サービスの通信アドレスを取得します。
Nginx はこのアドレスを使用して、PHP リクエストを処理のために PHP-FPM に転送します。
Alibaba Cloud Linux / CentOS
PHP_FPM_LISTEN=$(sudo sed -n 's/^\s*listen\s*=\s*//p' /etc/php-fpm.d/www.conf | head -n 1) echo "$PHP_FPM_LISTEN"Ubuntu
PHP_FPM_LISTEN=$(sudo sed -n 's/^\s*listen\s*=\s*//p' /etc/php/8.2/fpm/pool.d/www.conf | head -n 1) echo "$PHP_FPM_LISTEN".phpリクエストを PHP サービスに転送するように Nginx を設定します。前のステップの出力に基づいて、以下のコマンドの
<PHP_通信アドレス>を実際の通信アドレスに置き換えてから、コマンドを実行します:出力がファイルパスの場合 (例:
/run/php-fpm/www.sock):通信方法は UNIX ソケットです (ローカル通信のみで、パフォーマンスとセキュリティが向上します)。アドレス形式はunix:ファイルパスで、例えばunix:/run/php-fpm/www.sockのようになります。出力が IP アドレスとポートの場合 (例:
127.0.0.1:9000):通信方法は TCP です (ホスト間通信をサポートし、PHP-FPM と Nginx が別々のホストにデプロイされているシナリオに適しています)。これを直接通信アドレスとして使用できます。
sudo tee /etc/nginx/conf.d/default.conf <<-'EOF' server { listen 80; server_name localhost; root /usr/share/nginx/html; # デフォルトのインデックスファイルを設定します。 index index.php index.html index.htm; location / { try_files $uri $uri/ /index.php?$query_string; } # .php リクエストを PHP-FPM に転送します。 location ~ \.php$ { fastcgi_pass <PHP_通信アドレス>; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } } EOF設定ファイルを確認します。
sudo nginx -t出力にキーワード successful が含まれている場合、設定は正しいです。次のステップに進むことができます。
出力に failed が含まれている場合、設定は正しくありません。コマンド内のパスを正しく置き換えたか確認するか、次のコマンドを実行してバックアップから設定を復元してください:
sudo mv /etc/nginx/conf.d/default.conf.bak /etc/nginx/conf.d/default.conf
新しい設定を適用するために Nginx を再起動します。
sudo systemctl restart nginx
ステップ 6:LNMP スタックの検証
テストファイルを作成して、Nginx が PHP を処理できること、および PHP が MySQL データベースに接続できることを確認します。これにより、LNMP スタックのすべてのコンポーネントが正しく連携して動作していることを検証します。
Nginx の処理を検証します。
テストファイルの作成:
phpinfo()関数を含むファイルを生成して、PHP 環境の詳細な設定を表示します。echo "<?php phpinfo(); ?>" | sudo tee /usr/share/nginx/html/phpinfo.phpブラウザでの検証:
http://<ECS-public-IP-address>/phpinfo.phpにアクセスします。成功:ページが正しくレンダリングされ、PHP 環境に関する詳細情報が表示されます。
失敗:ページに
File not foundと表示されるか、ファイルが直接ダウンロードされます。
テストファイルのクリーンアップ:検証が成功した後、このファイルは必ず削除してください。
phpinfoページには機密情報が含まれており、公開されるとセキュリティリスクとなります。
PHP と MySQL の間の接続を検証します。
PHP スクリプトを作成して、PHP が mysqlnd 拡張機能を使用してデータベースに接続できるかどうかをテストします。
データベースとユーザーの作成
root アカウントで MySQL にログインします (ステップ 3 で設定したrootパスワードを入力します)。sudo mysql -u root -pmysql>プロンプトで、次のコマンドを実行してwebappという名前のデータベースとwebuserという名前のユーザーを作成し、そのデータベースに対するすべての権限を付与します。CREATE DATABASE webapp; /* <YourPassword> を強力なパスワードに置き換えてください。 */ CREATE USER 'webuser'@'localhost' IDENTIFIED BY '<YourPassword>'; GRANT ALL PRIVILEGES ON webapp.* TO 'webuser'@'localhost'; FLUSH PRIVILEGES; EXIT;データベース接続テストファイルの作成
以下のコマンドの<YourPassword>を前のステップで設定したユーザーパスワードに置き換えてから、コマンドを実行します。sudo tee /usr/share/nginx/html/test.php <<-'EOF' <?php $servername = "localhost"; $username = "webuser"; $password = "<YourPassword>"; $dbname = "webapp"; // 接続を作成 $conn = new mysqli($servername, $username, $password, $dbname); // 接続を確認 if ($conn->connect_error) { die("データベース接続に失敗しました: " . $conn->connect_error); } echo "データベース接続に成功しました!"; ?> EOFブラウザでの検証:http://<ECS-public-IP-address>/test.php にアクセスします。ページに データベース接続に成功しました! と表示されれば、テストは成功です。
テストファイルのクリーンアップ:このスクリプトにはデータベースのユーザー名とパスワードがプレーンテキストで含まれています。認証情報の漏洩を防ぐため、テスト後は直ちに削除する必要があります。
よくある質問
ブラウザがタイムアウトするか、「このサイトにアクセスできません」と表示される
これは通常、ネットワーク接続の問題です。以下の順序でトラブルシューティングを行ってください:
セキュリティグループ:インスタンスのセキュリティグループのインバウンドルールがポート 80 のトラフィックを許可しているか確認します。
ファイアウォール:オペレーティングシステムの内部ファイアウォール (例:
firewalldやufw) が無効になっているか、ポート 80 のトラフィックを許可するルールがあるか確認します。Nginx サービス:
sudo systemctl status nginxを実行して Nginx サービスが実行中か確認します。実行中でない場合は、sudo journalctl -xeu nginxでログを確認して問題を診断します。ポートの競合:ポート 80 が他のプログラムによって使用されていないか確認します。詳細なトラブルシューティング手順については、「ECS インスタンスのポート接続問題のトラブルシューティング」をご参照ください。
ブラウザに「502 Bad Gateway」と表示される
このエラーは、Nginx が PHP-FPM と正しく通信できないことを示しています。
PHP-FPM サービス:
sudo systemctl status php-fpm(Ubuntu の場合はphp8.2-fpm) を実行して、サービスが実行中か確認します。ソケットパス:Nginx 設定ファイルの
fastcgi_passディレクティブ内のunix:に続くパスが、PHP-FPM 設定ファイルのlistenパスと完全に一致していることを確認します。SELinux/AppArmor:CentOS/Alibaba Cloud Linux では、SELinux ポリシーが Nginx と PHP-FPM 間の通信をブロックしている可能性があります。
sestatusを実行してそのステータスを確認し、/var/log/audit/audit.logの拒否ログを確認します。ソケットの権限:ソケットファイルの権限を確認し、Nginx を実行しているユーザーが読み取りおよび書き込みアクセス権を持っていることを確認します。
MySQL へのリモートアクセスを許可するにはどうすればよいですか?
デフォルトでは、MySQL はリモートログインを禁止しています。有効にする必要がある場合は、root ユーザーのリモート接続を許可するのではなく、リモートアクセス専用のユーザーを作成することを推奨します。詳細な手順については、「リモート MySQL アクセス用のユーザーの追加」をご参照ください。