はじめに
EC2インスタンス上でNginxを動かしているけれど、「Webサイトが表示されない!」「設定変更したのに反映されない!」「502 Bad Gatewayエラーが頻発する…」といったトラブルに直面していませんか?
Nginxは非常に高性能で安定したWebサーバーですが、設定ミスやリソースの問題、バックエンドとの連携不備など、様々な原因で問題が発生することがあります。このような時、EC2インスタンスにSSHで入り、Linuxコマンドを駆使して調査するスキルが非常に重要になります。
この記事では、EC2上で動作するNginxのトラブルシューティングに焦点を当て、問題の原因を特定し解決するための具体的なLinuxコマンドと、その実践的な使用方法をステップバイステップで詳しく解説します。
Nginxトラブルシューティングの基本ステップとLinuxコマンド
問題解決の近道は、体系的に原因を切り分けていくことです。以下のステップで確認していきましょう。
ステップ1: Nginxプロセスの状態確認
まず、Nginxサービス自体が正常に動作しているかを確認します。
systemctl status nginx : Nginxサービスの稼働状況確認
何をするか?: Nginxサービスが起動しているか、エラーで停止していないか、最近のログの概要などを確認します。
どう使うか?:
sudo systemctl status nginx
実例と確認ポイント:
Active: active (running) と表示されれば、サービスは起動中です。
Active: failed (Result: exit-code) ... のように表示された場合は、Nginxが起動に失敗しています。ログに表示されたエラーメッセージや、後述する nginx -t で設定ファイルのエラーを確認しましょう。
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
Active: failed (Result: exit-code) since Tue 2025-05-06 20:00:00 JST; 5s ago
Process: 12345 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=1/FAILURE)
May 06 20:00:00 ip-172-31-0-10.ap-northeast-1.compute.internal systemd[1]: Starting A high performance web server and a reverse proxy server...
May 06 20:00:00 ip-172-31-0-10.ap-northeast-1.compute.internal nginx[12345]: nginx: [emerg] unknown directive "typo_directive" in /etc/nginx/conf.d/default.conf:5
May 06 20:00:00 ip-172-31-0-10.ap-northeast-1.compute.internal nginx[12345]: nginx: configuration file /etc/nginx/nginx.conf test failed
上記のように ExecStartPre で nginx -t が失敗している場合、設定ファイルに問題があることが示唆されます。
ps aux | grep nginx : Nginxプロセスの詳細確認
何をするか?: Nginxのマスタープロセスとワーカープロセスが実際に起動しているか、どのユーザーで実行されているかなどを確認します。
どう使うか?:
ps aux | grep nginx
実例と確認ポイント:
root 12301 0.0 0.1 12345 6789 ? Ss 19:50 0:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
nginx 12302 0.0 0.2 12378 7890 ? S 19:50 0:00 nginx: worker process
nginx 12303 0.0 0.2 12378 7890 ? S 19:50 0:00 nginx: worker process
master process と複数の worker process が表示されていれば正常です。
ワーカープロセスが起動していない場合、設定ミスやリソース不足の可能性があります。
ワーカープロセスの実行ユーザー(上記例では nginx)が、nginx.conf の user ディレクティブで指定したユーザーと一致しているか確認します。このユーザーがドキュメントルートやログファイルにアクセス権限を持っている必要があります。
nginx -t : 設定ファイルの構文チェック
何をするか?: Nginxの設定ファイル(nginx.conf およびインクルードされているファイル)に文法的な誤りがないかチェックします。Nginxを再起動/リロードする前に必ず実行しましょう。
どう使うか?:
sudo nginx -t
実例と確認ポイント:
正常な場合:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
エラーがある場合:
nginx: [emerg] directive "proxy_passs" is misspelled in /etc/nginx/conf.d/my_site.conf:15
nginx: configuration file /etc/nginx/nginx.conf test failed
エラーメッセージにファイル名と行番号が示されるので、該当箇所を修正します。上記例では proxy_passs というタイポがあります。
sudo systemctl restart nginx / sudo systemctl reload nginx : 設定の反映と動作確認
何をするか?: 設定ファイルを変更した後、Nginxに設定を再読み込みさせるか、サービスを再起動します。reload はサービスを停止せずに設定を反映できるため、可能な限りこちらを使用します。
どう使うか?:
sudo systemctl reload nginx # 推奨
または
sudo systemctl restart nginx
確認ポイント: コマンド実行後にエラーが表示されないか確認します。エラーが出た場合は、systemctl status nginx やエラーログで詳細を確認します。
ステップ2: Nginxログファイルの徹底調査
ログは問題解決の最大のヒントです。アクセスログとエラーログの両方を確認しましょう。ログファイルのパスは nginx.conf で確認できます(デフォルトは /var/log/nginx/ 配下)。
アクセスログ (access.log)
何をするか?: Nginxにどのようなリクエストが来て、Nginxがどのようなレスポンスを返したかを確認します。
どう使うか?:
リアルタイム監視:
tail -f /var/log/nginx/access.log
特定のエラーステータスコード (4xx, 5xx) を抽出:
grep " 404 " /var/log/nginx/access.log | less
grep " 502 " /var/log/nginx/access.log | tail -n 20 # 直近20件
特定のIPアドレスからのアクセスを確認:
grep "192.0.2.123" /var/log/nginx/access.log
実例と確認ポイント:
404 Not Found: リクエストされたファイルが存在しない。root ディレクティブのパスやファイル名を確認。
403 Forbidden: アクセス権限がない。ファイルパーミッションやNginxの設定 (allow/denyなど) を確認。
500 Internal Server Error: Nginx自体ではなく、連携しているアプリケーション (PHP-FPMなど) でエラーが発生している可能性が高い。アプリケーション側のログも確認。
502 Bad Gateway: リバースプロキシ構成で、バックエンドサーバーが応答しないか、不正な応答を返した。バックエンドの状態を確認。
504 Gateway Timeout: バックエンドサーバーの応答が遅すぎる。
エラーログ (error.log)
何をするか?: Nginx自体のエラー、設定ミス、バックエンドとの接続エラー、パーミッション関連のエラーなど、より詳細な問題の原因を探ります。
どう使うか?:
リアルタイム監視:
tail -f /var/log/nginx/error.log
特定のエラーメッセージを検索:
grep -i "permission denied" /var/log/nginx/error.log # 大文字小文字無視
grep "connect() failed" /var/log/nginx/error.log
grep "upstream timed out" /var/log/nginx/error.log
実例と確認ポイント:
[crit] ... connect() to unix:/run/php/php7.4-fpm.sock failed (13: Permission denied) while connecting to upstream: PHP-FPMとのソケットファイルのパーミッションに問題があることを示唆。ls -l /run/php/php7.4-fpm.sock でパーミッションを確認し、Nginxの実行ユーザーがアクセスできるように修正します。
[crit] ... SSL_CTX_use_PrivateKey_file("/etc/nginx/ssl/private.key") failed (SSL: error:0200100D:system library:fopen:Permission denied:fopen('/etc/nginx/ssl/private.key','r') error:20074002:BIO routines:file_ctrl:system lib error:140B0002:SSL routines:SSL_CTX_use_PrivateKey_file:system lib): SSL秘密鍵ファイルへのアクセス権限がない。ls -l /etc/nginx/ssl/private.key でパーミッションを確認し、Nginxの実行ユーザー(通常はrootで読み込み、ワーカープロセスは継承)が読めるようにします。通常、秘密鍵は所有者のみ読み取り可能 (chmod 600) ですが、Nginxのマスタープロセスはrootで起動し、その後ワーカープロセスが指定ユーザーに権限を落とすため、マスタープロセスが読めれば問題ありません。
[error] ... *1 open() "/var/www/html/favicon.ico" failed (2: No such file or directory): ドキュメントルートに指定されたファイルが存在しない。
ステップ3: 設定ファイル (nginx.conf と関連ファイル) の確認
Nginxの挙動は設定ファイルによって決まります。設定の不備がトラブルの原因となることは非常に多いです。
設定ファイルの場所とパーミッション
メイン設定ファイル: 通常 /etc/nginx/nginx.conf
サイトごとの設定ファイル: 通常 /etc/nginx/conf.d/*.conf や /etc/nginx/sites-available/, /etc/nginx/sites-enabled/ (シンボリックリンク)
どう使うか?:
ls -l /etc/nginx/nginx.conf
ls -lR /etc/nginx/conf.d/ # 再帰的に表示
Nginxの実行ユーザー(またはroot)がこれらのファイルを読み込めるか確認します。
nginx.conf (メイン設定ファイル) の確認ポイント
user nginx; : ワーカープロセスを実行するユーザー。このユーザーがドキュメントルートやログファイルなどにアクセスできる必要があります。
worker_processes auto; (または数値): CPUコア数に応じて適切に設定されているか。
worker_connections 1024; : 1ワーカープロセスあたりの最大同時接続数。
include /etc/nginx/conf.d/*.conf; : サイト別設定ファイルが正しくインクルードされているか。
サイト別設定ファイル (例: /etc/nginx/conf.d/my_site.conf) の確認ポイント
listen 80; / listen 443 ssl; : 正しいポートをリッスンしているか。IPv6の場合は listen [::]:80; など。
server_name example.com www.example.com; : 対象のドメイン名が正しく設定されているか。
root /var/www/html/my_site; : ドキュメントルートのパスは正しいか?
確認コマンド: ls -ld /var/www/html/my_site (ディレクトリの存在とパーミッション確認)
確認コマンド: ls -l /var/www/html/my_site/index.html (インデックスファイルの存在とパーミッション確認)
SSL/TLS設定 (HTTPSの場合):
ssl_certificate /etc/nginx/ssl/my_site.crt;
ssl_certificate_key /etc/nginx/ssl/my_site.key;
これらの証明書ファイルや秘密鍵ファイルのパスは正しいか? Nginxが読み取れるパーミッションになっているか?
確認コマンド: ls -l /etc/nginx/ssl/my_site.crt sudo ls -l /etc/nginx/ssl/my_site.key (秘密鍵は通常rootのみアクセス可能)
location ブロック:
PHPなどアプリケーションサーバーとの連携設定は正しいか? (例: fastcgi_pass)
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.4-fpm.sock; # または 127.0.0.1:9000
}
fastcgi_pass で指定したソケットファイルやTCPポートは正しいか? PHP-FPM側も同じ設定になっているか?
リバースプロキシ設定は正しいか? (例: proxy_pass)
location /app/ {
proxy_pass http://backend-server-ip:8080/;
}
proxy_pass のURLは正しいか? 末尾のスラッシュの有無で挙動が変わる点に注意。
実例: エラーログに open() "/usr/share/nginx/html/image.jpg" failed (2: No such file or directory) とあるが、設定ファイルで root /var/www/my_app; となっていた。ドキュメントルートの不一致。
ステップ4: ネットワーク関連の確認 (EC2内部とAWS環境)
Nginxの設定が正しくても、ネットワークの問題でアクセスできないことがあります。
EC2内部からの接続確認
何をするか?: NginxがEC2インスタンス内部で正しくポートをリッスンし、応答するか確認します。
どう使うか?:
Nginxがリッスンしているポートを確認:
sudo ss -tulnp | grep nginx
# 出力例 (80番と443番でリッスン)
# tcp LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=12302,fd=6))
# tcp LISTEN 0 511 0.0.0.0:443 0.0.0.0:* users:(("nginx",pid=12302,fd=8))
# tcp LISTEN 0 511 [::]:80 [::]:* users:(("nginx",pid=12302,fd=7))
# tcp LISTEN 0 511 [::]:443 [::]:* users:(("nginx",pid=12302,fd=9))
ここに表示されない場合、Nginxが起動していないか、listenディレクティブの設定ミス。
ローカルホストからの接続テスト:
curl -I http://localhost # HTTPの場合
curl -I http://127.0.0.1
curl -I -k https://localhost # HTTPSの場合 (-kで自己署名証明書エラーを無視)
ここで接続できない場合、Nginxの設定やプロセス自体に問題があります。
バックエンドへの接続確認 (リバースプロキシ構成の場合)
何をするか?: Nginxからリバースプロキシ先のバックエンドサーバーへ正常に通信できるか確認します。
どう使うか?:
EC2インスタンスのターミナルから実行します。
ping <バックエンドサーバーのIPアドレス>
curl -I http://<バックエンドサーバーのIPアドレス>:<バックエンドのポート>
# 例: curl -I http://10.0.1.50:8080
実例: curl でバックエンドに接続しようとすると Connection refused や No route to host となる場合、バックエンドサーバーが起動していない、ポートが開いていない、またはEC2インスタンスからバックエンドへのネットワーク経路 (セキュリティグループ、NACL、ルートテーブルなど) に問題があります。
ファイルディスクリプタ数の上限
何をするか?: Nginxは多くの接続を処理するため、ファイルディスクリプタを多数消費します。上限に達すると新規接続を受け付けられなくなります。
どう使うか?:
Nginxプロセスの上限確認 (PIDは ps aux | grep "nginx: worker process" などで特定):
cat /proc/<NginxワーカープロセスのPID>/limits | grep "Max open files"
OS全体の上限確認: ulimit -n (現在のセッション) または sysctl fs.file-max (システム全体)
Nginxエラーログに "too many open files" というエラーが出ていないか確認します。
対処: 必要に応じて nginx.conf の worker_rlimit_nofile ディレクティブでNginxの上限を引き上げるか、/etc/security/limits.conf などでOSレベルの上限を変更します。
ステップ5: AWS環境設定の確認
EC2インスタンスやNginxの設定が完璧でも、AWS側のネットワーク設定が原因で外部からアクセスできないことがあります。
セキュリティグループ:
EC2インスタンスにアタッチされているセキュリティグループの インバウンドルール を確認。
Nginxがリッスンしているポート (通常 TCP 80, TCP 443) が、適切な送信元 (例: インターネットからのアクセスなら 0.0.0.0/0 や ::/0) から許可されているか確認します。
ネットワークACL (NACL):
EC2インスタンスが所属するサブネットに関連付けられているNACLを確認。
インバウンドルールとアウトバウンドルールの両方で、Nginxが使用するポートのトラフィック (およびエフェメラルポートの戻りトラフィック) が許可されているか確認します。NACLはステートレスなので双方向の許可が必要です。
ルートテーブル:
EC2インスタンスがパブリックサブネットにある場合、ルートテーブルにインターネットゲートウェイ (0.0.0.0/0 -> igw-xxxxxx) へのルートがあるか確認します。
プライベートサブネットからNATゲートウェイ経由で外部と通信する場合なども同様にルートを確認します。
Elastic IP / Public IP:
インスタンスにパブリックIPアドレス (Elastic IPまたは自動割り当てパブリックIP) が正しく割り当てられているか、AWSコンソールで確認します。
DNS (Route 53など):
ドメイン名でアクセスしている場合、DNSレコードがEC2インスタンスの正しいパブリックIPアドレスを指しているか確認します。ローカルPCのターミナルから dig example.com や nslookup example.com を実行して確認できます。
よくあるNginxエラーメッセージと対処法 (Linuxコマンドでの確認)
ここでは、代表的なHTTPステータスコードと、その原因調査に役立つLinuxコマンドを紹介します。
403 Forbidden
原因: アクセス権限がない。
確認:
ドキュメントルートや対象ファイルのパーミッション: ls -ld /var/www/html/my_site, ls -l /var/www/html/my_site/secret.html (Nginx実行ユーザーが読み取れるか?ディレクトリの場合は実行権限も必要)
Nginx設定ファイルの allow/deny ディレクティブ。
インデックスファイル (index.html など) が存在しない、またはパーミッションがない (ディレクトリにアクセスしようとした場合)。Nginx設定で autoindex on; が有効ならファイル一覧が表示されることも。
SELinuxが有効な場合: getenforce で状態確認。sudo ausearch -m avc -ts recent や /var/log/audit/audit.log で拒否ログ確認。sudo setenforce 0 で一時的に無効化してテスト (非推奨、恒久的にはポリシー修正)。
404 Not Found
原因: リクエストされたリソースが見つからない。
確認:
Nginx設定ファイルの root ディレクティブのパスが正しいか。
実際にそのパスにファイルが存在するか: ls -l <rootで指定したパス>/<リクエストされたファイルパス>
シンボリックリンクの場合、リンク先が存在するか、パーミッションは適切か。
try_files ディレクティブの設定が意図通りか。
500 Internal Server Error
原因: サーバー内部で予期せぬエラー。多くはNginx自体ではなく、連携するバックエンドアプリケーション (PHP, Python, Node.jsなど) のエラー。
確認:
Nginxのエラーログ (/var/log/nginx/error.log): バックエンドからのエラーメッセージが記録されている場合がある。
バックエンドアプリケーションのログ: PHP-FPMなら /var/log/php7.4-fpm.log (バージョンによる)、Unicorn/Pumaならアプリケーションごとのログファイルなど。
502 Bad Gateway
原因: Nginxがリバースプロキシとして動作している際、バックエンドサーバーから無効な応答を受け取ったか、応答がなかった。
確認:
Nginxのエラーログ: バックエンドへの接続試行時のエラー詳細 (connect() failed, upstream prematurely closed connection など)。
バックエンドサーバーは起動しているか? (バックエンドサーバーのホストでプロセス確認)
Nginxからバックエンドサーバーへネットワーク的に到達可能か? (EC2インスタンスから ping <backend_ip>, curl http://<backend_ip>:<backend_port>)
バックエンドサーバーのポートは正しくリッスンしているか? (バックエンドサーバーのホストで ss -tulnp | grep <port>)
バックエンドアプリケーションのログ。
proxy_pass ディレクティブのURLが正しいか。
504 Gateway Timeout
原因: Nginxがバックエンドサーバーからの応答を待ったが、タイムアウト時間内に応答が得られなかった。
確認:
バックエンドサーバーの処理が非常に重い、またはハングアップしている。バックエンドのCPU、メモリ、ログを確認。
Nginxの設定でタイムアウト値 (proxy_connect_timeout, proxy_send_timeout, proxy_read_timeout, fastcgi_read_timeout など) が短すぎないか。
ネットワーク遅延が大きい。
それでも解決しないときは
Nginxのデバッグログを有効化する: nginx.conf の error_log ディレクティブでログレベルを debug に変更します (例: error_log /var/log/nginx/error.log debug;)。ただし、大量のログが出力されるため、問題解決後は元に戻しましょう。デバッグログを有効にするには、Nginxがデバッグオプション付きでコンパイルされている必要があります (nginx -V を実行し、出力の中に --with-debug が含まれているか確認します)。
高度なLinuxコマンド: strace -p <NginxワーカーPID> でシステムコールを追跡したり、lsof -i :80 -Pni や lsof -p <PID> でNginxが開いているファイルやソケットを確認したりすることも、原因究明の手がかりになることがあります(上級者向け)。
AWSサポート: どうしても解決しない場合は、AWSサポートに問い合わせることも検討しましょう。その際、ここまでの調査内容を伝えることで、よりスムーズなサポートが期待できます。
まとめ
EC2インスタンス上で稼働するNginxのトラブルシューティングは、一見難しそうに思えるかもしれません。しかし、今回紹介したLinuxコマンドを使いこなし、Nginxのプロセス状態、ログ、設定ファイル、そしてAWSのネットワーク環境を体系的に確認していくことで、多くの場合、原因を特定し解決に導くことができます。
重要なのは、慌てずに一つ一つ可能性を潰していくことと、ログをしっかり読む習慣をつけることです。この記事が、皆さんのNginxトラブルシューティングの一助となれば幸いです。