言語を切り替える
テーマを切り替える

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 1

StateExitRestartingになっていたら、そのコンテナが問題です。

2. docker-compose logs

問題のコンテナがなぜ死んだのか、遺言(ログ)を確認します。 -fでリアルタイム表示します。

# 全サービスのログ
docker-compose logs -f

# 特定のサービスのログ(例:web)
docker-compose logs -f web

3. 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コンテナが同じポートを使っている。

解決策:

  1. 犯人を見つける:
    # Mac/Linux
    lsof -i :8080
    # Windows
    netstat -ano | findstr :8080
  2. プロセスをキルする:
    # Mac/Linux
    kill -9 <PID>
    # Dockerコンテナなら
    docker rm -f <コンテナID>
  3. ポートを変更する:
    どうしてもそのポートが必要なら、docker-compose.ymlでホスト側のポートを変えます。
    ports:
      - "8081:8080" # ホスト8081 -> コンテナ8080

エラーパターン2: ネットワークが見つからない

エラーメッセージ例:
network my-network declared as external, but could not be found
Service "app" uses an undefined network "my-network"

原因:
external: trueと指定されたネットワークが存在しないか、スペルミスがあります。

解決策:

  1. ネットワーク一覧を確認:
    docker network ls
  2. ネットワークを作成:
    外部ネットワークとして指定されているなら、手動で作る必要があります。
    docker network create my-network
  3. 設定を見直す:
    コンテナ間通信は、デフォルトで同じネットワークに属します。特殊な要件がない限り、networksセクションを削除してデフォルトネットワークを使うのも手です。

エラーパターン3: コンテナが即死する (Exited with code 1)

エラーメッセージ例:
app_1 exited with code 1
app_1 exited with code 0 (正常終了だが、デーモンとしては動いていない)

原因:

  • コードにバグがあってクラッシュした。
  • 起動コマンド(CMD/ENTRYPOINT)が間違っている。
  • 必要な環境変数が足りない。
  • Node.jsなどでフォアグラウンドプロセスがない(プロセス終了=コンテナ終了)。

解決策:

  1. ログを見る:
    docker-compose logs appで理由が100%書いてあります。
    • Error: Cannot find module 'express' なら npm install 忘れ。
    • DB_HOST is not defined なら環境変数忘れ。
  2. 起動コマンドの確認:
    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で頻発します。

解決策:

  1. ホスト側の権限を緩める(開発環境向け):
    chmod -R 777 ./data
  2. ユーザーIDを合わせる:
    docker-compose.ymlでuserを指定する。
    services:
      app:
        user: "${UID}:${GID}" # .envでUID=1000のように指定
  3. node_modules問題:
    ホストのnode_modulesをマウントしないように、“ボリュームトリック”を使う。
    volumes:
      - .:/app
      - /app/node_modules # 名前なしボリュームをマウントしてホスト側を隠蔽

エラーパターン5: データベース接続拒否 (Connection Refused)

エラーメッセージ例:
connect ECONNREFUSED 172.18.0.2:5432
MongoNetworkError: failed to connect to server [db:27017]

原因:
アプリがデータベースより先に起動してしまい、データベースの準備ができる前に接続しようとした。

解決策:
これは非常に多い問題で、詳細な解決策が必要です。depends_onだけでは不十分です。
詳しくはこちらの記事(ヘルスチェック解説)を参照してください。要点はhealthcheckcondition: 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
# エラーが出るのを確認...

まとめ:トラブルシューティングフローチャート

エラーに出会ったら、この順序でチェックしてください。

  1. docker-compose ps:死んでるコンテナはどれ?
  2. docker-compose logs <service_name>:死因(エラーログ)は何?
  3. docker-compose config:設定ファイルは正しい?
  4. 原因別対処
    • Port allocated -> プロセス停止 or ポート変更
    • Network missng -> network create or 設定見直し
    • Exit code 1 -> 起動コマンド、環境変数、コード修正
    • Permission denied -> 権限変更 or ユーザーID指定
    • Connection refused -> ヘルスチェック導入

このフローを身につければ、大抵のトラブルは5分以内に解決できます。エラーは敵ではなく、システムのどこが間違っているかを教えてくれる親切なメッセージです(ちょっと口が悪いですが)。

Docker Composeエラー排基完全フロー

よくあるエラー(ポート競合、ネットワーク、権限、依存関係)の排查手順と解決策

⏱️ Estimated time: 15 min

  1. 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. 2

    Step2: ステップ2:エラーパターン別対処(ポートとネットワーク)

    パターン1:Port already allocated
    • 原因:ポートが使用中
    • 対処:lsof -i :ポート番号 でプロセス特定して停止、またはports設定を変更

    パターン2:Network not found / host not found
    • 原因:ネットワーク未作成、またはサービス名解決失敗
    • 対処:docker network lsで確認、docker network createで作成、サービス名が正しいか確認
  3. 3

    Step3: ステップ3:エラーパターン別対処(コンテナ終了と権限)

    パターン3:Exited with code 1 / 137
    • 原因:アプリクラッシュ、メモリ不足、コマンド間違い
    • 対処:ログの詳細確認、CMD/ENTRYPOINTの見直し、メモリ制限緩和

    パターン4:Permission denied
    • 原因:ボリュームマウント時のユーザーID不一致
    • 対処:user: "${UID}:${GID}"を指定、またはホスト側フォルダの権限変更
  4. 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)はどう直しますか?
1) 犯人を見つける:lsof -i :8080 (Mac/Linux) または netstat -ano | findstr :8080 (Windows)
2) 停止する:kill -9 PID または docker-compose down
3) 変更する:どうしても必要ならdocker-compose.ymlで "8081:8080" のようにホスト側ポートを変更します。
コンテナがすぐに終了(Exit code 0/1)してしまいます
まずログを確認してください(docker-compose logs)。
よくある原因:
• エラーでクラッシュしている(Exit 1)→ コードや設定の修正
• バックグラウンド処理で終了している(Exit 0)→ コンテナはメインプロセスが終わると停止します。nginxやapacheなどはフォアグラウンドモード(daemon off)で動かす必要があります。
コンテナから別のコンテナに接続できません
1) サービス名を使っていますか?(localhostは使えません)
2) 同じネットワークにいますか?(docker network inspectで確認)
3) 相手のコンテナは正常に起動していますか?(docker-compose ps)
4) 相手のポートは開いていますか?(必ずしもportsでホストに公開する必要はありませんが、Exposeされている必要があります)
ボリュームのpermission deniedエラーが出ます
Linux環境でよく発生します。コンテナ内のユーザーIDとホスト側の所有者が異なるためです。
対策:
• ホスト側のディレクトリ権限を777にする(開発環境のみ)
• docker-compose.ymlで user: "${UID}:${GID}" を指定して、実行ユーザーを合わせる
ログを見ても何も出力されずに終了します
起動コマンド(ENTRYPOINT/CMD)自体が見つからないか、実行権限がない可能性があります。
• コマンドのパスは正しいか?
• スクリプトに実行権限(chmod +x)はあるか?
• シェルの改行コードはLFか?(Windowsで編集した場合CRLFになっていないか注意)

3 min read · 公開日: 2025年12月17日 · 更新日: 2026年1月22日

コメント

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

関連記事