Nginxのトラブルシューティング:Webサーバー問題に対する一般的なコマンドライン解決策

サービス状態、設定エラー、ログ、ポート、一般的な4xxや5xxの障害に対する実用的なNginxコマンドラインチェックを使用します。

Nginxのトラブルシューティング:Webサーバー問題に対する一般的なコマンドライン解決策

Nginxが壊れたとき、最初の数分間は通常、問題を絞り込むことに費やされます。サービスが停止していますか?設定変更に失敗しましたか?別のプロセスが既にポート80を使用していますか?Nginxは正常だがアップストリームアプリがダウンしていますか?コマンドラインは、正しい順序でチェックを実行すれば、迅速な答えを提供します。

私は最も破壊的でないコマンドから始めるのが好きです:ステータスの検査、設定のテスト、ログの読み取り、そしてその後にのみリロードまたは再起動を行います。再起動は有用な証拠を隠す可能性があるため、何を修正しているのかを把握した上でのみ修正として扱ってください。

必須のNginx管理コマンド

トラブルシューティングの最初のステップは、多くの場合、Nginxサービス自体の状態を確認することです。オペレーティングシステムによって、通常はsystemdまたはservice(SysVinit)のいずれかと対話します。

1. Nginxサービスの状態を確認する

Nginxが実行中か、停止しているか、または失敗しているかを知ることは重要です。statusコマンドはこの概要を提供します。

systemdを使用する場合(Ubuntu 16.04+、CentOS 7+などの最新のLinuxディストリビューションで一般的):

sudo systemctl status nginx

期待される出力(アクティブ/実行中):

● nginx.service - 高性能Webサーバーおよびリバースプロキシサーバー
   Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2023-10-24 10:00:00 UTC; 1h ago
     Docs: man:nginx(8)
 Main PID: 1234 (nginx)
    Tasks: 2 (limit: 4915)
   CGroup: /system.slice/nginx.service
           ├─1234 nginx: master process /usr/sbin/nginx -g daemon on;
           └─1235 nginx: worker process 

出力にActive: inactive (dead)またはActive: failedと表示されている場合、Nginxが現在トラフィックを処理していないことがわかります。それは理由を教えてくれません。次の手がかりは通常、設定テストまたはシステムジャーナルです。

sudo journalctl -u nginx -n 80 --no-pager

これにより、systemdからの起動失敗を含む最近のサービスログが表示されます。不明なディレクティブ、証明書ファイルの欠落、バインド失敗、または権限エラーに関するメッセージを探してください。

2. Nginxの起動、停止、およびリロード

状態を特定したら、それを管理する必要があります。必要に応じて以下のコマンドを使用してください:

アクション コマンド(systemctlを使用)
停止 サービス sudo systemctl stop nginx
起動 サービス sudo systemctl start nginx
再起動 サービス sudo systemctl restart nginx(停止してから再起動)
リロード 設定 sudo systemctl reload nginx(接続を切断せずに新しい設定を適用)

ベストプラクティス:restartよりもreloadを使用する 設定変更(仮想ホストやSSL証明書の更新など)を行う場合は、常にreloadを使用してください。これにより、既存の接続は中断されずに変更が適用されます。reloadが失敗した場合、またはワーカープロセスを完全にリセットする必要がある場合にのみrestartを使用してください。

リロードする前に、以下を実行してください:

sudo nginx -t && sudo systemctl reload nginx

このワンライナーパターンは、最も一般的な間違い、つまり壊れた設定をリロードして動作中のサーバーをダウンさせることを防ぎます。nginx -tが失敗した場合、リロードコマンドは実行されません。

設定ファイルの検証

Nginxの起動失敗や予期しない動作の最も一般的な原因は、設定ファイル(nginx.confまたは/etc/nginx/sites-available/内に含まれるファイル)の構文エラーです。Nginxは優れた組み込みテストユーティリティを提供しています。

3. 設定構文のテスト

-tフラグは、設定ファイルの構文エラーをテストし、設定ファイルのパスが有効かどうかをチェックします。

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は正確なファイルと行番号を指し示します。例えば、セミコロンの欠落:

nginx: [emerg] unknown directive "server_name example.com" in /etc/nginx/sites-enabled/default:15
nginx: configuration file /etc/nginx/nginx.conf test failed

この即時フィードバックにより、指定されたファイルの15行目に直接ジャンプしてタイプミスを修正できます。

報告された行は、Nginxが最終的に問題に気付いた場所にすぎない場合があります。欠落した}または;は数行前にある可能性があります。エラーが正常に見えるディレクティブを指している場合は、その上のブロックを検査してください。

4. アクティブな設定の表示

Nginxが現在実行している設定を正確に確認するには(特に複数の設定マージや複雑なインクルードの後)、-Tフラグ(大文字のT)を使用します:

sudo nginx -T

これにより、アクティブな設定全体が出力され、比較や詳細なレビューのためにファイルにパイプできます:

sudo nginx -T > current_nginx_config.txt

nginx -Tの出力を共有する際は注意してください。内部ホスト名、証明書パス、プロキシヘッダー、および場合によってはヘッダーとして渡されるシークレットが含まれる可能性があります。インシデント作業には最適ですが、チケットやチャットの場合は、最初に編集してください。

ポートとリスナーの確認

Nginxが起動せず、ログにbind() to 0.0.0.0:80 failedと表示される場合、別のプロセスが既にそのポートをリッスンしている可能性があります。

sudo ss -ltnp | grep -E ':80|:443'

典型的な出力は、ローカルアドレス、ポート、およびプロセス名を示します。Apache、Caddy、コンテナプロキシ、または古いNginxプロセスがポートを保持している場合、Nginxはそれにバインドできません。

サーバー自体からパブリックな動作を確認することもできます:

curl -I http://127.0.0.1
curl -Ik https://127.0.0.1

-Iはヘッダーのみを取得します。-kは証明書の検証を無視します。これは、ドメイン名に対して発行された証明書でlocalhostをテストする場合に便利です。別のマシンから、実際のホスト名もテストしてください:

curl -I https://example.com

localhostは機能するがパブリックホスト名が機能しない場合は、ファイアウォールルール、クラウドセキュリティグループ、DNS、ロードバランサー、またはCDN設定を確認してください。

DNSは個別に確認する価値があります。なぜなら、外部からは正常なNginxサーバーが壊れているように見える可能性があるからです:

dig +short example.com
dig +short www.example.com

返されたアドレスが期待するサーバーまたはロードバランサーであることを確認してください。サイトを最近移動した場合、古いDNSにより一部のユーザーが古いホストに送信され、自分のテストが新しいホストにヒットする可能性があります。

監視とログ分析

Nginxが正常に起動したが、正しくないページを提供したり、5xxエラーを返したりする場合、ログが主要な情報源になります。

5. 主要なログファイルの場所を特定する

デフォルトでは、Nginxログは通常/var/log/nginx/にあります。2つの重要なファイルは次のとおりです:

  • access.log:サーバーが処理したすべてのリクエストを記録します。IP、リクエスト時間、ステータスコード、要求されたリソースが含まれます。
  • error.log:操作中またはリクエスト処理中に発生した警告、通知、および重大なエラーを記録します。

6. tailを使用したリアルタイムログ監視

エラーが発生したときに監視するには、エラーログでフォロー(-f)オプションを指定してtailコマンドを使用します。

sudo tail -f /var/log/nginx/error.log

これは、新しくデプロイされたアプリケーションエンドポイントをテストする場合に非常に役立ちます。Nginxまたはアップストリームアプリケーションがエラーをスローしているかどうかをすぐに確認できます。

よりビジーなサーバーの場合は、新しいエラー行のみをフォローし、タイムスタンプを表示したままにします:

sudo tail -n 50 -f /var/log/nginx/error.log

次に、別のターミナルで失敗しているリクエストを再現します:

curl -I https://example.com/failing/path

このシンプルな2ターミナルワークフローは、ブラウザでクリックするよりも高速であることがよくあります。各リクエストとログエントリを直接一致させることができるからです。

7. アクセスログのステータスコード分析

高トラフィックの問題の場合、アクセスログをすばやくスキャンしてステータスコードを確認すると、問題が明らかになることがあります:

  • 4xxコード(クライアントエラー):多くの場合、リンク切れ、ファイルの欠落(404)、または権限の問題を示します。
  • 5xxコード(サーバーエラー):Nginx自体がリクエストを完了できなかったことを示します。多くの場合、アップストリーム接続のタイムアウト(502/504)または内部サーバー処理の失敗(500)が原因です。

grepを使用して特定のコードをフィルタリングします。例えば、すべての502 Bad Gatewayエラーを見つける:

sudo grep ' 502 ' /var/log/nginx/access.log | tail -n 20

簡単なステータスコードカウントにより、1つの不良URLに対処しているのか、より広範なインシデントに対処しているのかがわかります:

sudo awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head

一般的なパターン:

  • 404の急増は、多くの場合、デプロイパスの不良、静的ファイルの欠落、またはルートの変更を意味します。
  • 403は、多くの場合、ファイル権限、ディレクトリ権限、または意図的なアクセスルールを指します。
  • 502は、通常、Nginxがアップストリームサービスから有効な応答を取得できなかったことを意味します。
  • 504は、通常、アップストリームサービスが接続を受け入れたが、時間内に応答しなかったことを意味します。

アップストリームの障害については、アプリケーションサービスも確認してください:

sudo systemctl status myapp
sudo journalctl -u myapp -n 100 --no-pager

myappを実際のサービス名に置き換えてください。Nginxは、稼働していて到達可能なもののみをプロキシできます。

高度な診断:冗長性とプロセスID

8. デバッグログの強制(注意が必要)

非常に厄介な状況では、ログレベルを上げると、リクエスト処理に関するより詳細な情報が明らかになることがあります。これは、設定内のerror_logディレクティブをdebugに変更することで行われます。

警告: デバッグログは非常に大量のデータを非常に迅速に生成するため、パフォーマンスに深刻な影響を与えるため、アクティブなトラブルシューティングのためにのみ一時的に使用する必要があります。

ディレクティブを変更した後、変更を有効にするにはNginxをreloadまたはrestartする必要があります。

9. NginxマスタープロセスID(PID)を見つける

プロセスID(PID)は、実行中のマスタープロセスに特定のシグナルを送信する場合に便利です(例:systemctl以外でのグレースフルシャットダウンやグレースフルリロード)。PIDは通常、ファイル(通常は/var/run/nginx.pid)に保存されます。

cat /var/run/nginx.pid
# 出力例:1234

必要に応じてkillコマンドを使用できます(例:sudo kill -HUP 1234でPIDを使用してリロードを強制):

ほとんどのオペレーターは、サービス管理者を経由し、監査が容易なため、systemctl reload nginxを優先する必要があります。シグナルは、systemdがプロセスを管理していない最小限のシステム、コンテナ、または古いホストでは依然として有用です。

症状別の一般的なコマンドライン修正

設定編集後にNginxが失敗した場合:

sudo nginx -t
sudo journalctl -u nginx -n 80 --no-pager

報告されたファイルと行を修正し、リロードする前に再度テストします。

証明書更新後にHTTPSが失敗した場合:

sudo nginx -t
sudo ls -l /etc/letsencrypt/live/example.com/
sudo openssl x509 -in /etc/letsencrypt/live/example.com/fullchain.pem -noout -dates -subject

これにより、証明書ファイルが存在すること、およびサブジェクトと有効期限が確認されます。

静的ファイルが403を返す場合:

namei -l /var/www/example.com/index.html

namei -lは、パス内のすべてのディレクトリの権限を表示します。Nginxは親ディレクトリに対する実行権限とファイルに対する読み取り権限を必要とします。

リバースプロキシが502を返す場合:

sudo grep 'connect() failed' /var/log/nginx/error.log | tail
sudo ss -ltnp | grep 3000
curl -I http://127.0.0.1:3000

これにより、アップストリームがリッスンしているかどうか、およびローカルで応答するかどうかがチェックされます。

アップストリームがTCPポートではなくUnixソケットの場合、ソケットパスと権限を確認します:

sudo ls -l /run/myapp/myapp.sock
sudo grep -R "proxy_pass" /etc/nginx/sites-enabled /etc/nginx/conf.d

Nginxワーカーユーザーはソケットにアクセスする権限が必要です。多くのシステムでは、そのユーザーはwww-dataまたはnginxですが、所有権やグループを変更する前にnginx.confで確認してください。

断続的な障害の場合は、アクセスログで成功したリクエストと失敗したリクエストを比較します。少量のサンプルで十分なことがよくあります:

sudo grep ' 504 ' /var/log/nginx/access.log | tail -n 20
sudo grep ' 200 ' /var/log/nginx/access.log | tail -n 20

パス、ログ形式に含まれている場合はアップストリーム応答時間フィールド、または大量のリクエストをトリガーしている特定のクライアントIPのパターンを探します。

トラブルシューティングのワークフロー

Nginxの問題に直面した場合は、次の順序に従ってください:

  1. ステータスを確認sudo systemctl status nginx
  2. 設定をテスト:起動に失敗した場合は、sudo nginx -tを実行します。報告されたエラーを修正します。
  3. 再起動/リロード:設定が変更された場合は、sudo systemctl reload nginxを使用します。
  4. ログを監視:実行中だが壊れている場合は、問題を再現しながらsudo tail -f /var/log/nginx/error.logを使用します。
  5. アクセスを分析access.logを確認して、障害の性質(4xx対5xx)を示すステータスコードを確認します。

この順序により、推測を防ぐことができます。ステータスはNginxが実行中かどうかを示し、設定テストはロードできるかどうかを示し、ログは実際のリクエスト中に何が起こったかを示し、ローカルのcurlチェックはNginxの問題をアップストリームやネットワークの問題から分離します。

作業中は短いインシデントノートを残してください:実行したコマンド、確認された結果、行った変更。これにより、繰り返しのチェックを防ぎ、引き継ぎがはるかに容易になります。