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

Docker Compose エラー排查マニュアル:5 大よくあるエラーの即効解決法

金曜日の午後 3 時半。コード提出の deadline まであと 2 時間。

ターミナルに赤いエラー——Error starting userland proxy: Bind for 0.0.0.0:8080 failed: port is already allocated。昨日まで問題なく動いていたのに、今日は起動しません。

Ctrl+C でやり直しても同じエラー。Google で「docker compose port already allocated」を検索し、Stack Overflow の記事を 5〜6 個試しました。Docker の再起動、コンテナ削除、ポート変更……画面のエラーは一切変わりません。

Docker Compose のエラーメッセージは数十行に及ぶことが多く、本当に重要な 1 行は 23 行目あたりに埋もれています。でも多くの人は 1 行目で慌ててしまいます。この記事では、ここ 2 年で踏んだ坑をまとめた Docker Compose の 5 大よくあるエラー を、「エラー特徴 → 原因 → 解決策」の順で解説します。読み終える頃には、エラーの 90% は 5 分以内に解決できる——どこから手を付けるかさえ分かれば——と実感できるはずです。

排查の基礎 — 3 つのコアツールを押さえる

いきなり個別のエラーに飛び込む前に、Docker Compose 問題排查の三種の神器を押さえましょう。この 3 コマンドは毎日十数回使っています。

ツール 1:docker-compose ps — 状態を素早く確認

どのコンテナが起動し、どれが落ちているかが一目で分かります。

docker-compose ps

State 列に注目してください。

  • Up — 正常稼働、ひとまず安心
  • Exit — 起動失敗、または実行中にクラッシュ
  • Restarting — 再起動を繰り返し、起動コマンドに問題あり

あるサービスが Exit 1 になっていたら、すぐログを確認する——これが私の鉄則です。

ツール 2:docker-compose logs — ログで手がかりを探す

排查の中心はここです。

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

# nginx だけ
docker-compose logs nginx

# リアルタイム追跡(tail -f 相当)
docker-compose logs -f

# 直近 100 行だけ
docker-compose logs --tail 100 nginx

Docker のログ出力は散らかりがちですが、90% のケースで本当のエラーは最後の数十行にあります。上に遡って ERRORfailedcannot などのキーワードを探してください。

ツール 3:docker inspect — 深掘り(必要なときだけ)

上の 2 つで解決しないときだけ使います。

# コンテナの完全な設定
docker inspect コンテナ名

# 状態だけ
docker inspect --format='{{.State.Status}}' コンテナ名

# IP アドレス
docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' コンテナ名

汎用排查フロー(これを覚えておく)

問題が起きても慌てず、この順番で進めましょう。

  1. docker-compose ps — どのサービスが落ちているか確認
  2. docker-compose logs [サービス名] — 具体的なエラーを確認
  3. docker inspect — 深掘り(多くの場合は不要)

準備が整いました。以下、5 つの高頻度エラーに入ります。

ポート競合 — 「port is already allocated」

このエラーは本当によく見ます。典型的なメッセージは次のとおりです。

Error starting userland proxy: Bind for 0.0.0.0:8080 failed: port is already allocated

または:

ERROR: for nginx  Cannot start service nginx: driver failed programming external connectivity on endpoint xxx: Bind for 0.0.0.0:80 failed: port is already allocated

なぜ起きるのか?

だいたい次の 3 パターンです。

  1. 前回 docker-compose up のあと Ctrl+C だけで終了し、docker-compose down していない——コンテナがバックグラウンドで残っている
  2. docker-compose.yml のポート設定を変えたが、古いコンテナが残っている
  3. ローカルの別プログラム(Nginx、MySQL など)がそのポートを使用中

解決策(シンプルな順に試す)

方案 1:クリーンアップして再起動(90% 有効)

docker-compose down
docker-compose up -d

私にとっては百発百中の手順です。down は全コンテナを停止・削除しますが、volume データは保持されます。

方案 2:ポートを占有しているコンテナを特定

方案 1 でもダメなら、「幽霊コンテナ」の可能性があります——現在のプロジェクト外だがポートを占有しているコンテナです。

# 全コンテナ(停止中も含む)
docker ps -a | grep 8080

# container_id が分かったら停止・削除
docker stop <container_id>
docker rm <container_id>

方案 3:docker-proxy プロセスを確認

コンテナを削除しても docker-proxy プロセスが残ることがあります。

# docker-proxy プロセスを確認
ps aux | grep docker-proxy | grep 8080

# 残っていれば Docker サービスを再起動
sudo systemctl restart docker  # Linux
# Mac の場合:Docker Desktop メニュー → Restart

方案 4:ホスト側のポート占有を確認

ローカルアプリがポートを使っている可能性もあります。

# Linux/Mac
lsof -i :8080
netstat -tlnp | grep 8080

# Windows
netstat -ano | findstr 8080

別プログラムが占有しているなら、そのプログラムを止めるか、docker-compose.yml のポートを変更してください。

方案 5:ポート設定を変更(最後の手段)

docker-compose.yml を編集します。

services:
  web:
    ports:
      - "8081:80"  # 8080 を 8081 に変更

私のおすすめ

習慣をつけましょう:コンテナを止めるときは Ctrl+C ではなく docker-compose down を使う。以前は Ctrl+C ばかりで、定期的にポート競合が起きていました。習慣を変えてから、このエラーはほぼ消えました。

開発環境では非標準ポートを使うのも有効です。80 や 3306 をそのまま使わず、8080 や 3307 にすると、システムサービスとの衝突を避けやすくなります。

ネットワーク問題 — 「network declared as external but could not be found」

典型的なエラーは次のとおりです。

ERROR: Network my_network declared as external, but could not be found. Please create the network manually using `docker network create my_network` and try again.

なぜ起きるのか?

Docker Compose の落とし穴の 1 つです。docker-compose.yml でネットワークを external: true とマークすると、Docker はそのネットワークが既に存在すると仮定し、自動作成しません。見つからなければエラーになります。

よくあるシナリオ:

  1. 他人の設定ファイルをコピーし、external ネットワークを参照しているが、ローカルに存在しない
  2. Docker を再起動し、一部のネットワーク設定が失われた
  3. ネットワーク名の大文字小文字を間違えた(Docker のネットワーク名は大文字小文字を区別します)

解決策

方案 1:既存ネットワークを一覧し、名前を確認

docker network ls

実際の名前が myproject_app_network で、設定では app_network になっている——こういうケースがあります。Docker Compose は自動的にプロジェクト名プレフィックスを付けます。

方案 2:不足しているネットワークを手動作成

docker network create my_network

方案 3:設定ファイルを修正

3 つの修正方法から選びます。

# 方式 A:external を外し、Compose に自動作成させる
networks:
  app_network:
    driver: bridge

# 方式 B:name フィールドでネットワーク名を明示
networks:
  app_network:
    external: true
    name: my_actual_network_name

# 方式 C:先に手動作成してから external で参照

個人的には方式 A を推します。複数の Compose プロジェクト間でネットワークを共有しない限り、Compose に任せた方が楽です。

方案 4:クリーンアップして再構築(Docker 再起動後にネットワークが消えた場合)

docker-compose down
docker network prune  # 不要なネットワークを削除
docker-compose up -d

避けるべき坑

  • どのネットワークを external(プロジェクト間共有)にすべきか、Compose 管理(単一プロジェクト)にすべきかを明確にする
  • name フィールドでネットワーク名を明示し、Compose の自動プレフィックスによる混乱を防ぐ
  • チームの README に事前作成が必要な external ネットワークを記載し、新人の坑を減らす

ビルド失敗 — 「service failed to build」

このエラーが出ても慌てないでください。

ERROR: Service 'app' failed to build: Build failed

重要なコツ:ログを上に遡る

「service failed to build」はまとめのエラーです。本当の原因はその前にあります。50〜100 行上に遡り、ERRORfailedcannotnot foundpermission denied を探してください。

初めて遭遇したとき、最終行だけを見て半日悩みました。上に遡るべきだったのです。本当のエラーは「npm install 失敗」や「ファイルが見つからない」など、出力の中に埋もれています。

よくあるサブエラー

タイプ 1:ファイルが見つからない

COPY failed: stat /var/lib/docker/tmp/.../package.json: no such file or directory

原因:

  • build context のパスが誤り
  • .dockerignore が必要なファイルを除外している

解決:

# docker-compose.yml の context 設定を確認
services:
  app:
    build:
      context: ./my-app  # このパスが正しいか確認
      dockerfile: Dockerfile

# .dockerignore を一時的にリネームしてテスト
mv .dockerignore .dockerignore.bak
docker-compose build app

タイプ 2:依存インストール失敗

npm ERR! 404 Not Found - GET https://registry.npmjs.org/xxx

または:

E: Unable to locate package xxx

原因:パッケージ名の誤り、存在しないバージョン、ネットワーク問題

解決:

# 国内ミラーを使う(Dockerfile 内)
RUN npm config set registry https://registry.npmmirror.com
RUN npm install

# apt のミラー変更
RUN sed -i 's/deb.debian.org/mirrors.aliyun.com/g' /etc/apt/sources.list
RUN apt-get update && apt-get install -y xxx

タイプ 3:メモリ不足

The command '/bin/sh -c npm install' returned a non-zero code: 137
signal: killed

終了コード 137 は多くの場合メモリ不足を示します。

解決:

  • Docker Desktop → Settings → Resources → Memory を 4GB 以上に
  • Dockerfile で並列構築を減らす:RUN npm install --max_old_space_size=4096

タイプ 4:Dockerfile の構文エラー

命令名の typo、COPY のソースパス誤りなど。

解決:単体ビルドでテスト:

cd ビルドディレクトリ
docker build -t test-build .

より明確なエラーメッセージが得られます。

デバッグ方法

キャッシュなしで再ビルド:

docker-compose build --no-cache service_name

キャッシュの中間レイヤーに問題があるとき、キャッシュをクリアすると解決することがあります。

ビルドコンテキストを確認:

docker-compose config

Compose が解釈した完全な設定が表示され、パス問題の発見に役立ちます。

私の経験

  • 正常にビルドできる版を baseline として保存し、変更のたびにテストする
  • Dockerfile は少しずつ変更する。一度に大量変更すると、どこが原因か分からなくなる
  • ビルドが遅いなら、マルチステージビルドや命令順序の最適化を検討。変更頻度の低い命令を前に置いてキャッシュを活かす

コンテナ起動後に終了 — 「exited with code X」

こちらはより厄介です。イメージのビルドは成功し、コンテナは起動した——が、すぐ終了します。

docker-compose ps では次のように見えます。

Name              State
app_web_1         Exit 1
app_db_1          Up

終了コードの意味(覚えておく)

  • Exit 0:正常終了——ただしコンテナとしては問題の可能性(コマンドが終わってしまった)
  • Exit 1:アプリケーションエラー(最も多い)
  • Exit 137:メモリ不足(OOM)または kill
  • Exit 139:セグメンテーション違反(Segmentation fault)
  • Exit 143:SIGTERM 受信(通常は手動停止)

排查ステップ

ステップ 1:ログを確認

docker-compose logs service_name

90% のケースで、ログに終了理由が書いてあります。

ステップ 2:手動でコンテナに入ってデバッグ

ログで分からない場合、docker-compose.yml を一時変更してコンテナを維持します。

services:
  app:
    command: sleep infinity  # まず終了させない

その後:

docker-compose up -d
docker-compose exec app sh  # コンテナに入る
# 元の起動コマンドを手動実行してエラーを確認

種別ごとの解決策

Exit 0 — コマンド実行後に終了

command: echo "Hello" のように、実行が終わるとコンテナも終了します。

解決:デーモンプロセスまたはブロックするコマンドに変更:

# 誤った例
command: echo "Started"

# 正しい例
command: npm start  # 継続実行するプロセス

Exit 1 — アプリケーションエラー

ログで原因を特定。よくあるのは:

  • 設定ファイルのパス誤り
  • 環境変数の不足
  • DB 接続失敗(DB がまだ ready でない)
  • 権限問題

Exit 137 — メモリ不足

コンテナにメモリ制限を設定:

services:
  app:
    mem_limit: 2g
    memswap_limit: 2g

または Docker Desktop の総メモリ割り当てを調整。

依存サービスが未準備

私も踏みました。アプリコンテナは起動したが DB はまだ初期化中で、接続できずクラッシュ。

解決:depends_onhealthcheck を組み合わせる:

services:
  app:
    depends_on:
      db:
        condition: service_healthy

  db:
    image: postgres
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

これで app は db が本当に ready になるまで待ちます。

私が踏んだ坑

あるコンテナが Exit 1 を繰り返し、ログには「Config file not found」だけ。半日探した結果、設定ファイルを相対パスで書いていたのが原因でした。コンテナ内の作業ディレクトリが想定と違っていました。絶対パスに変えて解決。

もう 1 回は DB パスワードの typo。アプリは起動直後にクラッシュ。ログにははっきり書いてあったのに、最初はちゃんと読まず……20 分無駄にしました。

権限問題 — 「permission denied」

volume マウント時に特に多いエラーです。

Error: EACCES: permission denied, open '/app/data/config.json'

またはコンテナログに「Permission denied」とあるが、どのファイルか分からないケース。

なぜ権限問題が起きるのか?

コンテナ内ユーザーの UID/GID とホスト側ファイル所有者が一致しないためです。例:

  • ホスト上のファイル所有者はあなた(UID 1000)
  • コンテナ内アプリは www-data(UID 33)で実行
  • www-data に読み書き権限がなくエラー

解決策

方案 1:user で UID/GID を指定(推奨)

コンテナをあなたのユーザーで実行:

services:
  app:
    user: "${UID}:${GID}"
    volumes:
      - ./data:/app/data

実行時:

UID=$(id -u) GID=$(id -g) docker-compose up

または .env に記載:

# .env
UID=1000
GID=1000

方案 2:ホスト側のファイル権限を変更

手っ取り早い方法:

chmod -R 777 ./data  # 慎重に。セキュリティリスクあり
# または
chmod -R 755 ./data  # より安全
chown -R $(id -u):$(id -g) ./data

方案 3:SELinux システム(CentOS/RHEL)でフラグを追加

CentOS/RHEL では SELinux が原因のことも:

volumes:
  - ./data:/app/data:z  # 複数コンテナで共有
  # または
  - ./config:/app/config:Z  # このコンテナ専用

小文字 z と大文字 Z の違い:小文字は共有、大文字は専用です。

方案 4:bind mount の代わりに named volume

Docker 管理の volume なら権限問題が起きにくい:

services:
  app:
    volumes:
      - app_data:/app/data  # named volume

volumes:
  app_data:  # Docker が権限を自動管理

欠点はホストから直接ファイルを編集できないこと。コンテナ経由でアクセスします。

方案 5:entrypoint スクリプトで権限を調整

複雑なシナリオ向け:

# entrypoint.sh
#!/bin/sh
chown -R appuser:appuser /app/data
exec "$@"
COPY entrypoint.sh /
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD ["node", "app.js"]

私のおすすめ

  • 本番環境:named volume。安全で権限を気にしなくてよい
  • 開発環境:方案 1(user で UID/GID 指定)。ホストから直接編集しやすい
  • 777 は避ける:コンテナ内コードを完全に信頼できる場合以外は使わない

権限問題は最初は複雑に感じますが、UID/GID の一致の仕組みを理解すれば難しくありません。

汎用デバッグテクニックまとめ

具体的なエラーをたくさん見てきました。最後に体系的な排查の考え方を整理します。

標準排查フロー(これに従えば間違いない)

1. docker-compose ps           → 状態確認、問題のサービスを特定
2. docker-compose logs <サービス>  → ログでキーエラーを探す
3. docker-compose config       → 設定ファイルの構文を検証
4. docker inspect <コンテナ>       → 深掘り(必要な場合)
5. 隔離テスト                    → 問題のサービスだけ単独起動

この習慣をつければ、問題が起きても途方に暮れません。

よく使うクリーンアップコマンド(定期メンテ)

# コンテナを停止・削除(volume は保持)
docker-compose down

# volume も削除(注意して使う)
docker-compose down -v

# 未使用リソース(ネットワーク、イメージなど)を削除
docker system prune

# 完全クリーンアップ(全イメージ含む)
docker system prune -a

# キャッシュなしで再ビルド
docker-compose build --no-cache

# Docker のディスク使用量を確認
docker system df

毎週金曜の退勤前に docker system prune を実行しています。あるとき Docker が 50GB を占有していて、クリーンアップ後 10GB になったことも……

予防策(未然に防ぐ)

設定検証:

# 起動前に設定ファイルを検証
docker-compose config

YAML 構文チェックと設定エラーの早期発見に役立ちます。

ヘルスチェック:

services:
  web:
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:80/health"]
      interval: 30s
      timeout: 10s
      retries: 3

healthcheck があれば、起動はしたが実際は unhealthy な状態を早く検知できます。

適切な再起動ポリシー:

services:
  app:
    restart: unless-stopped  # 推奨:手動停止以外は常に再起動
    # restart: always        # 常に再起動
    # restart: on-failure    # 失敗時のみ再起動

環境変数の集中管理:

# .env ファイル
DB_PASSWORD=your_password
API_KEY=your_key

# docker-compose.yml
services:
  app:
    environment:
      - DB_PASSWORD=${DB_PASSWORD}
      - API_KEY=${API_KEY}

設定変更で YAML を触らずに済み、チーム開発でも便利です。

まとめ

冒頭のシーンに戻りましょう。金曜午後 3 時半、deadline が迫り、コンテナが起動しない。今ならこう動けます。

  1. 慌てない、深呼吸
  2. どのカテゴリのエラーか判断(ポート、ネットワーク、ビルド、終了、権限)
  3. 該当セクションの解決策を、シンプルな順に試す
  4. それでもダメならログを見る——答えはそこにある

Docker Compose のエラー自体は怖くありません。怖いのは体系的な排查の考え方がないことです。この 5 大エラーと対処パターンを覚えておけば、次は 5 分で片付けられます。

最後の提案:チームのナレッジベースに踏んだ坑と解決策を記録しましょう。うちの Wiki には「Docker よくある問題」ページがあり、新人が読めば 80% の坑を避けられます。

あなたが遭遇した変わった Docker Compose エラーがあれば、コメントで共有してください。他の人の助けになるかもしれません。

Docker Compose エラー排查の完全フロー

5 大よくあるエラーの即効解決法と体系的排查フローで、5 分以内に原因を特定

⏱️ 目安時間: 5 分

  1. 1

    ステップ1: 3 つのコア排查ツールを押さえる

    ツール 1:docker-compose ps — 状態を素早く確認
    • どのコンテナが起動し、どれが落ちているかが分かる
    • State 列に注目:
    - Up:正常稼働
    - Exit:起動失敗、または実行中にクラッシュ
    - Restarting:再起動を繰り返し、起動コマンドに問題あり

    ツール 2:docker-compose logs — ログで手がかりを探す
    • 特定サービスのログ:docker-compose logs web
    • 直近 50 行:docker-compose logs --tail=50 web
    • リアルタイム追跡:docker-compose logs -f web

    ツール 3:docker-compose config — 設定を検証
    • docker-compose.yml の構文確認:docker-compose config
    • 環境変数の検証:docker-compose config --resolve-env-vars
  2. 2

    ステップ2: エラー 1:ポート競合の排查と解決

    エラー特徴:
    • Error starting userland proxy: Bind for 0.0.0.0:8080 failed: port is already allocated

    原因:
    • ポートが他プロセスに占有されている
    • 前回のコンテナが停止していない、またはシステムの別サービスがポートを使用中

    解決策:
    1. ポート占有を確認
    • lsof -i :8080
    • netstat -tuln | grep 8080

    2. 占有プロセスを停止
    • kill -9 PID
    • docker-compose down

    3. ポートを変更
    • docker-compose.yml の ports 設定を修正
    • 例:"8081:8080"

    4. 動的ポートを使う
    • ホスト側ポートを指定せず、Docker に自動割り当てさせる
  3. 3

    ステップ3: エラー 2〜5:ネットワーク、ビルド、コンテナ終了、権限

    エラー 2:ネットワーク問題
    • エラー特徴:network not found、container name resolution failed
    • 解決策:
    - ネットワーク設定を確認:docker network ls
    - カスタムネットワークを作成:docker network create my-network
    - docker-compose.yml でネットワークを指定:networks: my-network

    エラー 3:ビルド失敗
    • エラー特徴:build failed、Dockerfile not found
    • 解決策:
    - Dockerfile の構文を確認
    - ビルドコンテキストを確認
    - 依存ファイルを確認
    - 詳細ビルドログ:docker-compose build --no-cache

    エラー 4:コンテナ終了
    • エラー特徴:Exited with code 1、Restarting
    • 解決策:
    - docker-compose logs でログ確認
    - 起動コマンドを確認
    - 環境変数を確認
    - 依存サービスを確認

    エラー 5:権限エラー
    • エラー特徴:Permission denied、Cannot connect to Docker daemon
    • 解決策:
    - chmod で権限修正
    - Docker daemon の状態確認:sudo systemctl status docker
    - ユーザー権限確認:sudo usermod -aG docker $USER

FAQ

Docker Compose エラー排查のコアツールは?
3 つのコアツールを押さえましょう:

1) docker-compose ps — 状態を素早く確認:
• どのコンテナが起動し、どれが落ちているかが分かる
• State 列に注目(Up=正常、Exit=起動失敗またはクラッシュ、Restarting=起動コマンドに問題)

2) docker-compose logs — ログで手がかりを探す:
• 特定サービス:docker-compose logs web
• 直近 50 行:docker-compose logs --tail=50 web
• リアルタイム追跡:docker-compose logs -f web

3) docker-compose config — 設定を検証:
• 構文確認:docker-compose config
• 環境変数検証:docker-compose config --resolve-env-vars
ポート競合エラーはどう解決する?
エラー特徴:Error starting userland proxy: Bind for 0.0.0.0:8080 failed: port is already allocated。

原因:ポートが他プロセスに占有されている。前回のコンテナが残っている、またはシステムの別サービスが使用中。

解決策:
1) ポート占有を確認(lsof -i :8080 または netstat -tuln | grep 8080)
2) 占有プロセスを停止(kill -9 PID または docker-compose down)
3) ポートを変更(docker-compose.yml の ports を修正、例 "8081:8080")
4) 動的ポート(ホスト側を指定せず Docker に自動割り当て)
Docker Compose のネットワーク問題はどう排查する?
エラー特徴:network not found、container name resolution failed。

原因:ネットワーク設定の誤り、コンテナ名による名前解決の失敗。

解決策:
1) ネットワーク設定を確認(docker network ls)
2) カスタムネットワークを作成(docker network create my-network)
3) docker-compose.yml でネットワークを指定(networks: my-network)
4) サービスが同一ネットワーク上にあることを確認(同じネットワーク名を使用)
コンテナ終了エラーはどう排查する?
エラー特徴:Exited with code 1、Restarting。

原因:
• 起動コマンドの誤り
• 環境変数の不足
• 依存サービスが未準備

解決策:
1) ログ確認(docker-compose logs)
2) 起動コマンド確認(CMD または ENTRYPOINT が正しいか)
3) 環境変数確認(.env や環境変数設定)
4) 依存サービス確認(依存先が起動・準備完了しているか)
5) ヘルスチェック確認(healthcheck 設定時、パスしているか)
Docker Compose エラーを体系的に排查するには?
体系的排查フロー:
1) docker-compose ps でコンテナ状態を確認
2) docker-compose logs でエラーログを確認
3) docker-compose config で設定ファイルを検証
4) エラー種別ごとに対処:
• ポート競合 → 占有確認 → ポート変更またはプロセス停止
• ネットワーク → 設定確認 → カスタムネットワーク作成
• ビルド失敗 → Dockerfile 確認 → ビルドエラー修正
• コンテナ終了 → ログ確認 → 起動コマンド修正
• 権限エラー → ファイル権限確認 → 権限修正

エラーの 90% は 5 分以内に解決できます。どこから手を付けるかが分かれば十分です。

ベストプラクティス:チームのナレッジベースに踏んだ坑と解決策を記録しましょう。うちの Wiki に「Docker よくある問題」ページがあり、新人が読めば 80% の坑を避けられます。

5分で読めます · 公開日: 2025年12月17日 · 更新日: 2026年6月8日

関連記事

コメント

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