Nginxで504 Gateway Timeoutが出たときの原因と解決方法|タイムアウトを順番に確認する

Nginxを使っているサイトで、突然「504 Gateway Timeout」と表示されることがあります。

504エラーは、Nginx自体が必ず壊れているという意味ではありません。多くの場合、Nginxが接続しているアプリケーションや別のサーバーから、決められた時間内に応答を受け取れなかったときに発生します。

そのため、設定をいきなり変更するよりも、Nginx → upstream → アプリケーション → データベースや外部サービスの順番で確認すると原因を切り分けやすくなります。

504 Gateway Timeoutとは?

504 Gateway Timeoutは、Nginxなどのゲートウェイやプロキシが、接続先のサーバーから時間内に応答を受け取れなかったときに返されるHTTPステータスコードです。

例えば、次のような構成を考えてみます。

ブラウザ
   ↓
Nginx
   ↓
アプリケーション
   ↓
データベース

ブラウザからNginxへリクエストが届いても、Nginxからアプリケーションへの処理が長時間終わらなければ、504が返されることがあります。

つまり、504が表示されたからといって、最初からNginxの設定だけを疑う必要はありません。

504エラーが出たときに確認する順番

基本的には次の順番で確認すると効率的です。

  1. Nginxが正常に動いているか
  2. upstreamのアプリケーションが動いているか
  3. upstreamのポートへ接続できるか
  4. Nginxのエラーログに何が出ているか
  5. アプリケーションの処理に時間がかかっていないか
  6. データベースや外部APIで時間がかかっていないか
  7. 必要に応じてタイムアウト設定を確認する

504の場合は、「接続できない」のか「接続できるが処理が終わらない」のかを分けて考えることが重要です。

Nginxが正常に動いているか確認する

まずNginx自体が正常に動いているか確認します。

sudo systemctl status nginx

正常に動作していれば、active (running) と表示されます。

設定ファイルに問題がないか確認する場合は、次のコマンドを使います。

sudo nginx -t

問題がなければ、次のような結果が表示されます。

syntax is ok
test is successful

設定ファイルを変更した直後から504が発生した場合は、ここを最初に確認しておくと安心です。

upstreamのアプリケーションが動いているか確認する

Nginxが正常でも、接続先のアプリケーションが停止していれば正常なレスポンスを返せません。

例えばNginxの設定が次のようになっているとします。

location / {
    proxy_pass http://127.0.0.1:3000;
}

この場合、Nginxはローカルの3000番ポートで動いているアプリケーションへ接続します。

まず、3000番ポートを使用しているプロセスが存在するか確認します。

sudo ss -lntp | grep :3000

何も表示されない場合は、アプリケーションが起動していない可能性があります。

アプリケーションのサービスがsystemdで管理されている場合は、例えば次のように確認します。

sudo systemctl status myapp

Dockerを使用している場合は、コンテナの状態も確認します。

docker ps

停止や再起動を繰り返しているコンテナがないか確認してください。

upstreamへ直接アクセスして確認する

Nginxを経由すると問題が分かりにくい場合は、upstreamへ直接アクセスしてみます。

例えば3000番ポートでアプリケーションが動いている場合は、

curl http://127.0.0.1:3000

を実行します。

ここですぐにレスポンスが返ってくるなら、アプリケーション自体は動作している可能性があります。

反対に、長時間待たされたり接続できなかったりする場合は、Nginxよりもupstream側に原因がある可能性が高くなります。

Nginxのエラーログを確認する

504の原因を調べるときは、Nginxのエラーログが重要です。

環境によって場所は異なりますが、一般的には次のように確認できます。

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

過去のログを確認する場合は、

sudo tail -n 100 /var/log/nginx/error.log

を使います。

例えばupstreamからの応答を待ってタイムアウトしている場合、upstream timed out などの情報が記録されることがあります。

ログに表示された内容を確認することで、単純な接続エラーなのか、処理時間の問題なのかを判断しやすくなります。

アプリケーションの処理が遅くなっていないか確認する

upstreamが起動していても、処理そのものに時間がかかっていれば504になることがあります。

例えば、

  • 大量のデータを処理している
  • データベースのクエリが遅い
  • 外部APIからの応答を待っている
  • ファイル処理に時間がかかっている
  • CPUやメモリが不足している

といったケースです。

アプリケーションのログも確認してみましょう。

systemdで管理しているサービスなら、

sudo journalctl -u myapp --since "30 minutes ago"

のように確認できます。

Dockerの場合は、

docker logs コンテナ名

でログを確認できます。

Nginxだけを見ていると原因を見逃すことがあるため、504が発生した時間帯のアプリケーションログも確認することが大切です。

データベースが原因になっていないか確認する

アプリケーションが動いていても、データベースへの問い合わせが遅くなれば504につながることがあります。

例えば、

ブラウザ
 ↓
Nginx
 ↓
アプリケーション
 ↓
MySQL

という構成の場合、MySQLの処理が長時間終わらなければ、最終的にNginxがタイムアウトする可能性があります。

この場合はNginxの設定だけを変更しても根本的な解決にはなりません。

データベースの負荷や遅いクエリ、ロックなども確認する必要があります。

Nginxのタイムアウト設定を確認する

upstreamの処理に時間がかかることが分かったら、Nginxのタイムアウト設定を確認します。

例えば、

proxy_read_timeout 60s;

のような設定があります。

これは、proxy先からのレスポンスを待つ時間に関係する設定です。

設定を確認する場合は、Nginxの設定ファイルを調べます。

sudo nginx -T | grep -n "proxy_read_timeout"

ただし、504が出るからといって、すぐにタイムアウト時間を長くすればよいわけではありません。

例えば本来数秒で終わる処理が突然数分かかっているのであれば、タイムアウトを延長するよりも、なぜ処理が遅くなったのかを調べるほうが重要です。

タイムアウトを変更する場合の注意点

どうしても長時間処理が必要なシステムでは、Nginx側のタイムアウトを調整することがあります。

例えば、

location / {
    proxy_pass http://127.0.0.1:3000;
    proxy_read_timeout 120s;
}

のように設定できます。

変更後は必ず設定を確認します。

sudo nginx -t

問題がなければ、

sudo systemctl reload nginx

で設定を反映します。

ただし、タイムアウトを極端に長くすると、接続が長時間残り続けてサーバーのリソースを消費する可能性があります。

そのため、原因を確認せずに大きな値へ変更するのは避けたほうが安全です。

504と502の違い

Nginxのトラブルでは、504と502を混同しやすいため注意が必要です。

エラー主な意味
502 Bad Gatewayupstreamから正常な応答を受け取れない
504 Gateway Timeoutupstreamからの応答を時間内に受け取れない

もちろん実際の原因は構成によって異なりますが、ざっくり分けると、502は「正常な応答を得られない」問題、504は「応答を待っているうちに時間切れになる」問題として考えると切り分けやすくなります。

504が発生したときの確認コマンド

最低限、次のコマンドを順番に確認してみましょう。

確認内容コマンド
Nginxの状態sudo systemctl status nginx
Nginx設定sudo nginx -t
ポート確認sudo ss -lntp
upstream確認curl http://127.0.0.1:3000
Nginxログsudo tail -n 100 /var/log/nginx/error.log
systemdログsudo journalctl -u myapp --since "30 minutes ago"
Docker確認docker ps
Dockerログdocker logs コンテナ名

ポート番号やサービス名は、自分の環境に合わせて変更してください。

504エラーを調べるときの注意点

Nginxだけを原因だと決めつけない

504が表示されても、原因がNginxとは限りません。

アプリケーション、データベース、外部API、サーバー負荷など、さまざまな場所で処理が遅くなっている可能性があります。

いきなり設定を大きく変更しない

proxy_read_timeoutなどを極端に長くすると、一時的に504が減ることがあります。

しかし、根本原因が残っていれば、サーバーの負荷がさらに高くなる可能性があります。

まずログとupstreamの状態を確認してから設定変更を検討しましょう。

設定変更後はnginx -tを実行する

Nginxの設定を変更した場合は、

sudo nginx -t

で構文を確認してからreloadします。

設定ミスによってNginx自体が正常に起動できなくなることを防ぐためにも、この確認は省略しないほうが安全です。

まとめ

Nginxの504 Gateway Timeoutは、Nginxそのものが停止しているとは限りません。

まず、

Nginx → upstream → ポート → ログ → アプリケーション → データベース

の順番で確認すると、原因を切り分けやすくなります。

特に重要なのは、upstreamへ直接アクセスしてみることと、504が発生した時間帯のNginx・アプリケーションログを確認することです。

タイムアウト設定を変更する方法もありますが、単純に待ち時間を長くするだけでは根本的な解決にならない場合があります。

Nginxの504 Gateway Timeoutは何が原因ですか?

Nginxが接続しているupstreamの応答が遅い、アプリケーションの処理に時間がかかっている、データベースや外部APIが遅延しているなど、さまざまな原因があります。

まずNginxのエラーログとupstreamの状態を確認すると原因を絞り込みやすくなります。

504と502は何が違いますか?

502はupstreamから正常な応答を受け取れない場合に発生することが多く、504はupstreamからの応答を待っている間にタイムアウトした場合に発生することが多いです。

proxy_read_timeoutを長くすれば504は解決しますか?

処理に時間がかかることが正当な原因であれば有効な場合があります。

ただし、アプリケーションやデータベースの処理が異常に遅くなっている場合は、タイムアウトを延長するだけでは根本的な解決になりません。

Docker環境でも504は発生しますか?

発生します。NginxからDockerコンテナ内のアプリケーションへ接続している構成では、コンテナ停止、アプリケーションの処理遅延、ポート設定などが原因になることがあります。

Nginxで502 Bad Gatewayが出たときの原因と解決方法|確認する順番を解説

Linuxのポートが開いているか確認する方法|ss・nc・curlで接続障害を切り分ける

Dockerコンテナが起動しないときの確認方法|docker ps・logsで原因を調べる手順

Linuxサーバーが重い・遅いときの原因と確認方法|CPU・メモリ・ディスクを順番に調べる

Linuxサーバーのメモリ不足を確認する方法|free・topで原因を調べる手順

LinuxのディスクI/Oが高いときの確認方法|サーバーが遅い原因を調べる手順

類似投稿