Core Media Lab記事一覧
開発・インフラ

【Difyエラー解決】VPS(Docker)環境で「502 Bad Gateway」が出る4大原因と復旧手順!メモリ不足・Nginx設定の直し方

【Difyエラー解決】VPS(Docker)環境で「502 Bad Gateway」が出る4大原因と復旧手順!メモリ不足・Nginx設定の直し方

VPS(仮想専用サーバー)にDockerを使って自分専用のDify(Community Edition)を構築したものの、ブラウザからアクセスした瞬間に「502 Bad Gateway(nginx)」という真っ白なエラー画面が表示されてログインできない——これはDifyのセルフホスト運用で最も多く発生する代表的なトラブルです。

さらに厄介なのは、「昨日までは普通に動いていたのに、ワークフローを実行したりアップデートしたりした直後から突然502エラーになった」というケースが少なくないことです。

結論からお伝えすると、DifyのDocker環境で発生する「502 Bad Gateway」の9割以上は、①起動直後のDBマイグレーション待ち、②VPSのメモリ不足(OOM Killerによる強制終了)、③Nginxコンテナの転送先IPずれ、④アップデート後の環境変数(.env)不整合の4つのいずれかが原因です。

本記事では、大切なワークフローやナレッジベースのデータを消すことなく、わずか30秒のコマンド診断で原因を特定し、最短でDifyを正常復旧させる具体的な手順をコピペで使えるコマンド付きで徹底解説します。

なぜDify(Docker環境)で「502 Bad Gateway」が出るのか?仕組みと4大原因

復旧作業に入る前に、「そもそもなぜ画面に『502 Bad Gateway(nginx)』と表示されるのか?」という裏側の仕組みを簡単に押さえておきましょう。ここを理解しておくと、今後エラーが起きても一瞬で原因を見抜けるようになります。

玄関口の「Nginx」は生きているが、裏側の「API」や「Web」が応答していない状態

Docker Composeで立ち上げたDifyは、1つの巨大なプログラムではなく、役割ごとに分かれた約9〜10個のコンテナ(小さな仮想サーバー群)が内部ネットワークで通信し合う構造になっています。

私たちがブラウザから http://VPSのIPアドレス にアクセスした際、最初に通信を受け取る「窓口(リバースプロキシ)」が docker-nginx-1(Nginxコンテナ) です。Nginxは受け取ったリクエストを、裏側で動いている以下の2つの主要コンテナへ振り分けています。

  • docker-web-1(ポート3000): Difyの画面表示(Next.jsフロントエンド)を担当
  • docker-api-1(ポート5001): ログイン認証、ワークフロー処理、DB連携などの頭脳(Pythonバックエンド)を担当

このうち、窓口である nginx コンテナは非常に軽量なため、サーバーが高負荷になってもほとんど落ちません。一方で、裏側の api や web コンテナはメモリやCPUを大量に消費します。何らかの理由で裏側の api または web コンテナが停止・準備中になり、窓口の nginx が「裏側に繋ごうとしたけれど返事がない!」とエラーを返している状態が「502 Bad Gateway」の正体です。

💡 Difyの初期構築手順や全体アーキテクチャを復習したい方はこちら:
・【完全ガイド】DifyをVPS(Docker)でセルフホスト構築する手順!無料枠の制限を突破し24時間AI自動化

Difyで「502 Bad Gateway」を引き起こす4大原因一覧

裏側のコンテナが応答しなくなる原因は、大きく分けて以下の4パターンに集約されます。

原因パターン 発生するタイミング 裏側で起きている現象
① DBマイグレーション実行中 初回構築や再起動・更新の直後(1〜3分以内) api コンテナがデータベースの初期構築(約200個のマイグレーション)を行っており、まだ通信受付を開始していない。
② VPSのメモリ不足(OOM) メモリ1GB〜2GB環境での起動時・RAG処理時 物理メモリ(RAM)が枯渇し、Linuxの防衛機能(OOM Killer)が重い api や web を強制終了(Exited 137)させた。
③ Nginxの転送先IPずれ 一部コンテナの再起動後・特定のDNS環境 api や web は正常に動いているのに、nginx が古いコンテナIPアドレスへ通信を送って接続拒否されている。
④ 更新後の設定(.env)不整合 git pull でバージョンアップした直後 新バージョンで追加された必須環境変数が .env に足りず、api や plugin_daemon がエラー停止している。

【30秒診断】まずはこの2つのコマンドで「どの原因か」を特定しよう

502エラーが出たとき、いきなり設定ファイルを書き換えたりサーバーを初期化したりするのは禁物です。まずはVPSへSSH接続し、以下の2つのコマンドを実行して「4つの原因のうちどれなのか」を確実に特定しましょう。

診断コマンド1:コンテナの生死を確認する(docker compose ps)

Difyをインストールしたディレクトリ(通常は ~/dify/docker)へ移動し、コンテナの稼働一覧を表示します。

# Difyのdockerディレクトリへ移動してステータスを確認
cd ~/dify/docker
sudo docker compose ps

出力された表の STATUS(状態)列 に注目してください。

  • docker-api-1 や docker-web-1 が Exited (137) になっている場合:
    ➔ 【原因②:メモリ不足(OOM Killer)】で確定です。終了コード 137(128 + SIGKILL:9)は、メモリ枯渇によってOSから強制キルされた証拠です。
  • Exited (1) や Restarting を繰り返している場合:
    ➔ 【原因④:設定ファイル(.env)不整合またはDB接続エラー】の可能性が高いです。
  • すべてのコンテナが Up(起動中)になっている場合:
    ➔ 【原因①:まだマイグレーション中】か、【原因③:Nginxの転送先IPずれ】のどちらかです。次の診断コマンド2へ進んでください。

診断コマンド2:APIとNginxの直近ログを確認する(docker compose logs)

すべてのコンテナが Up なのに502が出る場合は、api コンテナと nginx コンテナのログを末尾50行だけ表示して中身を確認します。

# APIコンテナのログをリアルタイム追跡(Ctrl + C で終了)
sudo docker compose logs --tail=50 -f api

# Nginxコンテナのエラーログを確認
sudo docker compose logs --tail=50 nginx
  • api のログに Running migrations や INFO [alembic.runtime.migration] が流れている場合:
    ➔ 【原因①:DBマイグレーション実行中】です。故障ではありません。
  • api は起動完了しているのに、nginx のログに connect() failed (111: Connection refused) や host not found in upstream が出ている場合:
    ➔ 【原因③:Nginxの転送先IPずれ・名前解決エラー】で確定です。

原因が特定できたら、次のセクションから該当する番号の復旧手順を実行していきましょう。

【原因別】Difyの「502 Bad Gateway」を確実に直す4つの復旧手順

ここからは、先ほどの診断で判明した原因(①〜④)ごとに、データを保持したまま安全に復旧させる具体的なコマンド手順を解説します。

対処法①:起動・更新直後の「DBマイグレーション待ち」の場合

sudo docker compose up -d を実行した直後(特に初回インストール時やバージョンアップ直後)は、docker-api-1 コンテナが裏側でPostgreSQLデータベースのテーブル構築・更新(マイグレーション)を順番に実行しています。

VPSのCPUスペックによっては、この処理が完了してWebサーバー(Gunicorn)のポート5001が開くまでに約1分〜3分ほどかかります。以下のコマンドでログを監視し、起動完了メッセージが出るまでそのまま待機してください。

# APIコンテナの起動完了をリアルタイムで確認する
cd ~/dify/docker
sudo docker compose logs -f api

ログの末尾に Listening at: http://0.0.0.0:5001 またはワーカーの起動完了ログが表示されたら、Ctrl + C でログ監視を抜けてブラウザを再読み込み(F5)してください。正常にログイン画面(または初期設定画面)が表示されます。

対処法②:メモリ不足(Exited 137 / OOM Killer)でコンテナが落ちている場合

sudo docker compose ps で Exited (137) が表示されていたり、OSのカーネルログ(sudo dmesg -T | grep -i -E 'oom|killed')に Out of memory: Killed process と記録されていたりする場合は、VPSの物理メモリ(RAM)が完全に不足しています。

応急処置として、ディスク容量の一部をメモリとして代用する「Swap(仮想メモリ)領域」を4GB追加してからDifyを再起動しましょう。

# 1. 現在のメモリとSwap状況を確認
free -h

# 2. Swapが0B(未設定)の場合は4GBのスワップファイルを作成・有効化
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

# 3. サーバー再起動後もSwapが維持されるよう設定を追記(未登録の場合のみ)
grep -q '/swapfile' /etc/fstab || echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

# 4. 停止していたDifyのコンテナ群を再起動
cd ~/dify/docker
sudo docker compose up -d

Swapを追加することで、一時的なメモリスパイク(負荷急増)が起きても即座にコンテナが強制終了されるのを防ぐことができます。

対処法③:Nginxコンテナの「転送先IPアドレスずれ」を解消する

docker-api-1 も docker-web-1 も正常に Up になっており、エラーログも出ていないのに「502 Bad Gateway」が消えない場合は、Nginxコンテナが記憶している転送先IPアドレスと、現在の api / web コンテナのIPアドレスがずれているのが原因です。

Docker環境では、api や web コンテナだけが再起動した際に内部IPアドレス(172.18.0.x など)が新しく振り直されることがあります。このとき、先に起動していた nginx コンテナが古いIPアドレスへ通信を送り続けてしまうことで502エラーが発生します。

手順A:まずはNginxコンテナの再起動を試す(推奨・一番安全)

ほとんどのケースでは、以下のコマンドで nginx コンテナを再起動し、名前解決(IPアドレスの取得)をやり直させるだけで即座に直ります。

# Nginxコンテナのみを再起動して内部IPを再認識させる
cd ~/dify/docker
sudo docker compose restart nginx

手順B:公式FAQの「IP直書き」よりも安全なDocker内部DNS確認

なお、Difyの公式GitHub FAQには「nginx/conf.d の設定ファイルを開き、http://api:5001 を http://172.18.0.x:5001(コンテナの直接IP)に書き換える」という対処法が記載されています。しかし、設定ファイルにIPアドレスを直接ハードコーディングすると、次回コンテナやVPSを再起動してIPが変わった瞬間に再び502エラーが発生してしまうため、長期運用ではおすすめできません。

もし sudo docker compose restart nginx でも解決しない場合は、コンテナネットワーク自体を一度きれいに張り直す以下のコマンドを実行してください(volumes 内のデータは消えません)。

# コンテナと内部ネットワークを一度閉じてから再構築・起動する
cd ~/dify/docker
sudo docker compose down
sudo docker compose up -d

対処法④:アップデート(git pull)直後の「.env」設定不整合を直す

Difyを最新バージョンへアップデートした直後から502エラーになる場合は、新しいバージョンで追加された環境変数(例:PLUGIN_DAEMON 関連や新しいストレージ設定など)が手元の .env ファイルに存在しないことによる起動エラーが原因です。

既存の .env をバックアップした上で、最新の .env.example をベースに設定を再適用しましょう。

cd ~/dify/docker

# 1. 現在の .env に設定している SECRET_KEY などの重要項目を確認して控える
grep -E 'SECRET_KEY|EXPOSE_NGINX_PORT' .env

# 2. 現在の .env をバックアップとして退避し、最新の .env.example をコピーする
cp .env .env.bak_$(date +%Y%m%d)
cp .env.example .env

# 3. 控えておいた SECRET_KEY 等を新しい .env に反映(nanoエディタで編集)
nano .env

# 4. 最新イメージを取得してコンテナを再起動
sudo docker compose pull
sudo docker compose up -d
💡 アップデート前の安全なフルバックアップ手順はこちら:
・【事故ゼロ】VPS(Docker)上のDify・n8nを安全にバックアップ&アップデートする完全手順

Swapを入れても502が再発するなら「メモリ4GB以上のVPS」への移行・スケールアップが必須

ここまで解説した対処法(特にSwap領域の追加)を行っても、以下のようなタイミングで再び「502 Bad Gateway」が頻発したり、画面の切り替わりが極端に重くなったりするケースがあります。

  • ナレッジベース(RAG)にPDFや長文テキストをアップロードしてインデックス処理(ベクトル化)を走らせたとき
  • 複数のステップを持つチャットフローやエージェントを同時実行したとき
  • 同じVPS上で「n8n」や「Pythonスクレイピング」を並列稼働させたとき

物理メモリ1GB〜2GBの限界と「スラッシング(速度低下)」の罠

現在のDify(特にプラグイン機構が導入された v1.0 以降)は、起動しているだけで約1.8GB〜2.5GB近いメモリを消費します。物理メモリが1GB〜2GBしかないVPSでSwap(ディスク上の仮想メモリ)に頼り切った運用を続けると、メモリとSSDの間でデータの入れ替えが絶え間なく発生する「スラッシング」という現象が起き、CPU使用率が100%に張り付いてタイムアウト(502 / 504エラー)を連発するようになります。

運用構成 推奨メモリ容量 安定性と502エラー発生リスク
メモリ 1GB プラン × 運用不可 Swapを設定しても起動直後やマイグレーション中に高確率で502エラーになる。
メモリ 2GB プラン(+Swap 4GB) △ 個人検証の最小ライン 軽いチャットボットなら動くが、RAG処理やアップデート時にメモリ枯渇リスクがある。
メモリ 4GB プラン(推奨) ◎ 公式要件クリア・安定 Dify公式の推奨スペックを満たし、RAGやn8nとの同居でも502エラーに悩まされず快適。

もし現在メモリ1GB〜2GBのサーバーで何度も502エラーに時間を奪われているのであれば、コントロールパネルから「メモリ4GBプラン」へプラン変更(スケールアップ)するか、最初からメモリ単価が安い高コスパな国内VPSへ乗り換えるのが最も確実な根本解決策です。

🚀 【徹底比較】メモリ4GBでも月額1,000円台から使える高コスパ国内VPSは?
Difyやn8nを502エラー知らずで快適・最安クラスで稼働できるおすすめVPS 3社の料金・スペック比較は、以下の記事で詳しくまとめています。

👉 【2026年最新】開発・自動化におすすめのVPS 3選を徹底比較!コストとスペックで選ぶ最適解

まとめ:Difyの502エラーはログを見れば怖くない!安定したVPS環境で自動化を回そう

本記事では、VPS(Docker)環境のDifyで「502 Bad Gateway」が発生する4つの原因と、データを消さずに最短で復旧する手順を解説しました。

  • まずは2つのコマンドで原因診断: sudo docker compose ps でコンテナの生死(特に Exited 137)を確認し、sudo docker compose logs でマイグレーション中かIPずれかを見極める。
  • 4つの原因に応じた的確な対処: ①起動直後なら1〜3分待つ、②メモリ不足なら4GBのSwapを追加する、③IPずれなら nginx を再起動する、④更新直後なら .env.example との差分を同期する。
  • 根本解決はメモリ4GB以上の確保: 頻繁なOOM Killer発動やスラッシングによるタイムアウトを防ぐには、Dify公式要件である「メモリ4GB以上」のVPS環境を整えるのが鉄則。

一度この切り分け手順を覚えておけば、万が一Difyが502エラーを出しても数分で冷静に復旧できるようになります。足元のサーバー環境を盤石に整えて、24時間止まらない快適なAI自動化パイプラインを運用していきましょう!

🚀 【メモリ不足を根本解決】Dify・AI自動化に最適な国内VPS 3選の比較を見る