Docker Composeエラー排查ガイド:よくある起動失敗を5分で解決するためのトラブルシューティング

「昨日までは動いていたのに…」
これは開発者の最も有名な最後の言葉の一つですが、Docker Composeを使っていると頻繁に遭遇します。赤文字のエラーメッセージ、再起動を繰り返すコンテナ、接続できないデータベース。
焦ってググって、Stack Overflowの適当なコマンドをコピペする前に、ちょっと待ってください。
Docker Composeのエラーにはパターンがあります。約90%の問題は、これから紹介する5つのパターンのいずれかに当てはまります。このガイドでは、エラーメッセージから原因を特定し、迅速に修正するための体系的なアプローチを紹介します。
3つの神器:まずこれを実行せよ
具体的なエラーを見る前に、デバッグの基本ツールを確認しましょう。
1. docker-compose ps
現在動いているコンテナの状態を確認します。
$ docker-compose ps
Name Command State Ports
----------------------------------------------------------------------
myapp_db_1 docker-entrypoint.sh ... Up 5432/tcp
myapp_web_1 npm start Exit 1StateがExitやRestartingになっていたら、そのコンテナが問題です。
2. docker-compose logs
問題のコンテナがなぜ死んだのか、遺言(ログ)を確認します。 -fでリアルタイム表示します。
# 全サービスのログ
docker-compose logs -f
# 特定のサービスのログ(例:web)
docker-compose logs -f web3. docker-compose config
設定ファイル(docker-compose.yml)の構文エラーや変数の展開状況を確認します。
docker-compose config「YAMLのインデントがずれていた」「環境変数が空だった」といった凡ミスはこれで見つかります。
エラーパターン1: ポートの競合
エラーメッセージ例:Error starting userland proxy: Bind for 0.0.0.0:8080 failed: port is already allocated
原因:
指定したポート(この例では8080)が、すでに他のプロセスに使われています。
- 前の
docker-compose upがゾンビプロセスとして残っている。 - ローカルで開発用サーバー(npm startなど)が動いている。
- 別のDockerコンテナが同じポートを使っている。
解決策:
- 犯人を見つける:
# Mac/Linux lsof -i :8080 # Windows netstat -ano | findstr :8080 - プロセスをキルする:
# Mac/Linux kill -9 <PID> # Dockerコンテナなら docker rm -f <コンテナID> - ポートを変更する:
どうしてもそのポートが必要なら、docker-compose.ymlでホスト側のポートを変えます。ports: - "8081:8080" # ホスト8081 -> コンテナ8080
エラーパターン2: ネットワークが見つからない
エラーメッセージ例:network my-network declared as external, but could not be foundService "app" uses an undefined network "my-network"
原因:external: trueと指定されたネットワークが存在しないか、スペルミスがあります。
解決策:
- ネットワーク一覧を確認:
docker network ls - ネットワークを作成:
外部ネットワークとして指定されているなら、手動で作る必要があります。docker network create my-network - 設定を見直す:
コンテナ間通信は、デフォルトで同じネットワークに属します。特殊な要件がない限り、networksセクションを削除してデフォルトネットワークを使うのも手です。
エラーパターン3: コンテナが即死する (Exited with code 1)
エラーメッセージ例:app_1 exited with code 1app_1 exited with code 0 (正常終了だが、デーモンとしては動いていない)
原因:
- コードにバグがあってクラッシュした。
- 起動コマンド(CMD/ENTRYPOINT)が間違っている。
- 必要な環境変数が足りない。
- Node.jsなどでフォアグラウンドプロセスがない(プロセス終了=コンテナ終了)。
解決策:
- ログを見る:
docker-compose logs appで理由が100%書いてあります。Error: Cannot find module 'express'ならnpm install忘れ。DB_HOST is not definedなら環境変数忘れ。
- 起動コマンドの確認:
DockerfileのCMDや、docker-compose.ymlのcommandを確認。npm startなどはOK。service nginx startのようなバックグラウンドで終了するコマンドはNG。コンテナはメインプロセスが終わると死にます。nginx -g "daemon off;"のようにフォアグラウンドで動かす必要があります。
エラーパターン4: ボリュームの権限エラー
エラーメッセージ例:EACCES: permission denied, mkdir '/app/node_modules'chown: changing ownership of '/var/lib/mysql/': Operation not permitted
原因:
ホスト側のボリュームをマウントした際、コンテナ内のユーザー(nodeやmysql)と、ホスト側のファイルの所有者(あなたのユーザーID)が一致せず、書き込み権限がない。特にLinuxで頻発します。
解決策:
- ホスト側の権限を緩める(開発環境向け):
chmod -R 777 ./data - ユーザーIDを合わせる:
docker-compose.ymlでuserを指定する。services: app: user: "${UID}:${GID}" # .envでUID=1000のように指定 - node_modules問題:
ホストのnode_modulesをマウントしないように、“ボリュームトリック”を使う。volumes: - .:/app - /app/node_modules # 名前なしボリュームをマウントしてホスト側を隠蔽
エラーパターン5: データベース接続拒否 (Connection Refused)
エラーメッセージ例:connect ECONNREFUSED 172.18.0.2:5432MongoNetworkError: failed to connect to server [db:27017]
原因:
アプリがデータベースより先に起動してしまい、データベースの準備ができる前に接続しようとした。
解決策:
これは非常に多い問題で、詳細な解決策が必要です。depends_onだけでは不十分です。
詳しくはこちらの記事(ヘルスチェック解説)を参照してください。要点はhealthcheckとcondition: service_healthyを使うことです。
上級編:デバッグ用コンテナとして入る
ログだけでは原因がわからない場合、コンテナの中に入って調査するのが一番です。
しかし、コンテナがすぐ死んでしまう場合、docker execで入る時間もありません。
そんな時は、entrypointを上書きして、とにかく起動し続けるようにします。
# 元のコマンドを無視して、ただのスリープ状態で起動
docker-compose run --rm --entrypoint sh app -c "sleep 3600"あるいはdocker-compose.ymlを一時的に書き換えます:
services:
app:
command: tail -f /dev/null # 何もしないで待機これでコンテナは死なないので、ゆっくり入って調査できます:
docker exec -it myapp_app_1 sh
# 中でコマンドを試す
npm start
# エラーが出るのを確認...まとめ:トラブルシューティングフローチャート
エラーに出会ったら、この順序でチェックしてください。
docker-compose ps:死んでるコンテナはどれ?docker-compose logs <service_name>:死因(エラーログ)は何?docker-compose config:設定ファイルは正しい?- 原因別対処:
- Port allocated -> プロセス停止 or ポート変更
- Network missng ->
network createor 設定見直し - Exit code 1 -> 起動コマンド、環境変数、コード修正
- Permission denied -> 権限変更 or ユーザーID指定
- Connection refused -> ヘルスチェック導入
このフローを身につければ、大抵のトラブルは5分以内に解決できます。エラーは敵ではなく、システムのどこが間違っているかを教えてくれる親切なメッセージです(ちょっと口が悪いですが)。
Docker Composeエラー排基完全フロー
よくあるエラー(ポート競合、ネットワーク、権限、依存関係)の排查手順と解決策
⏱️ Estimated time: 15 min
- 1
Step1: ステップ1:基本状況の確認(三種の神器)
1. コンテナ状態確認:docker-compose ps -a
→ StateがExitやRestartingになっているサービスを特定
2. ログ確認:docker-compose logs <service_name>
→ エラーメッセージを特定(Error、Exception、Panicなどのキーワードを探す)
3. 設定確認:docker-compose config
→ YAML構文エラーや環境変数の展開漏れを確認 - 2
Step2: ステップ2:エラーパターン別対処(ポートとネットワーク)
パターン1:Port already allocated
• 原因:ポートが使用中
• 対処:lsof -i :ポート番号 でプロセス特定して停止、またはports設定を変更
パターン2:Network not found / host not found
• 原因:ネットワーク未作成、またはサービス名解決失敗
• 対処:docker network lsで確認、docker network createで作成、サービス名が正しいか確認 - 3
Step3: ステップ3:エラーパターン別対処(コンテナ終了と権限)
パターン3:Exited with code 1 / 137
• 原因:アプリクラッシュ、メモリ不足、コマンド間違い
• 対処:ログの詳細確認、CMD/ENTRYPOINTの見直し、メモリ制限緩和
パターン4:Permission denied
• 原因:ボリュームマウント時のユーザーID不一致
• 対処:user: "${UID}:${GID}"を指定、またはホスト側フォルダの権限変更 - 4
Step4: ステップ4:高度なデバッグ(コンテナに入って調査)
コンテナがすぐ死んで入れない場合:
1. 起動コマンドを上書きして待機させる
docker-compose run --rm --entrypoint sh app -c "sleep 3600"
または command: tail -f /dev/null
2. コンテナに入る
docker exec -it <container_id> sh
3. 手動でコマンド実行して再現確認
npm start など
FAQ
ポート競合(Port already allocated)はどう直しますか?
2) 停止する:kill -9 PID または docker-compose down
3) 変更する:どうしても必要ならdocker-compose.ymlで "8081:8080" のようにホスト側ポートを変更します。
コンテナがすぐに終了(Exit code 0/1)してしまいます
よくある原因:
• エラーでクラッシュしている(Exit 1)→ コードや設定の修正
• バックグラウンド処理で終了している(Exit 0)→ コンテナはメインプロセスが終わると停止します。nginxやapacheなどはフォアグラウンドモード(daemon off)で動かす必要があります。
コンテナから別のコンテナに接続できません
2) 同じネットワークにいますか?(docker network inspectで確認)
3) 相手のコンテナは正常に起動していますか?(docker-compose ps)
4) 相手のポートは開いていますか?(必ずしもportsでホストに公開する必要はありませんが、Exposeされている必要があります)
ボリュームのpermission deniedエラーが出ます
対策:
• ホスト側のディレクトリ権限を777にする(開発環境のみ)
• docker-compose.ymlで user: "${UID}:${GID}" を指定して、実行ユーザーを合わせる
ログを見ても何も出力されずに終了します
• コマンドのパスは正しいか?
• スクリプトに実行権限(chmod +x)はあるか?
• シェルの改行コードはLFか?(Windowsで編集した場合CRLFになっていないか注意)
3 min read · 公開日: 2025年12月17日 · 更新日: 2026年1月22日
関連記事
Next.js ファイルアップロード完全ガイド:S3/Qiniu Cloud 署名付き URL 直接アップロード実践

Next.js ファイルアップロード完全ガイド:S3/Qiniu Cloud 署名付き URL 直接アップロード実践
Next.js Eコマース実践:カートと Stripe 決済の完全実装ガイド

Next.js Eコマース実践:カートと Stripe 決済の完全実装ガイド
Next.js ユニットテスト実践:Jest + React Testing Library 完全設定ガイド


コメント
GitHubアカウントでログインしてコメントできます