docker compose upで失敗する6つの原因と即座の解決策

本記事では、docker compose up実行時に発生する頻出エラーの原因特定方法と、実際の修正コマンドを紹介します。開発環境の立ち上げで時間を失わないための実践的なトラブルシューティングを学べます。

docker compose upで失敗する前に確認すべきこと

本記事での検証環境:macOS 13 / Docker Desktop 4.26 / Docker Compose v2.24で動作確認済みです。

docker compose upコマンドは、docker-compose.ymlファイルで定義されたサービスを一括起動するツールです。エラーが発生する場合、多くは以下の原因に該当します:

  • YAMLファイルの構文エラー
  • ポート競合
  • イメージの取得失敗
  • ネットワーク設定の問題
  • ボリューム(ストレージ)のパーミッション問題
  • 環境変数の未設定

エラー原因別の診断と解決方法

1. YAML構文エラー:「invalid compose file」

最も一般的な失敗パターンです。インデント位置の誤りやコロンの忘れがあると発生します。

エラーメッセージ例:

ERROR: invalid compose file './docker-compose.yml': services.web.ports must be a list

よくあるミス例:

services:
  web:
    image: nginx:latest
    ports: 8080:80  # ❌ 間違い:リスト形式ではない
    volumes:
    - ./app:/app  # ❌ インデント位置が間違い

正しい記述方法:

version: '3.8'
services:
  web:
    image: nginx:latest
    ports:
      - "8080:80"  # ✅ リスト形式で記述
    volumes:
      - ./app:/app  # ✅ インデント統一

すぐに試せる検証コマンドは以下です:

# YAMLファイルの構文を検証
docker compose config

# 詳細なエラー箇所を表示
docker compose validate

2. ポート競合エラー:「Bind for 0.0.0.0:xxxx failed」

指定したポートが既に別のプロセスで使用されている場合に発生します。

エラーメッセージ例:

Error response from daemon: Bind for 0.0.0.0:5432 failed: port is already in use

解決手順:

# ポート5432を使用しているプロセスを特定
lsof -i :5432

# 該当プロセスを終了する(PIDを指定)
kill -9 12345

# または別のポート番号に変更
# docker-compose.ymlを編集
services:
  db:
    image: postgres:15
    ports:
      - "5433:5432"  # ホストの5433をコンテナの5432にマッピング

別の方法として、既に起動しているコンテナをクリーンアップすることも有効です:

# 停止中のコンテナも確認
docker ps -a

# 特定のコンテナを停止
docker stop コンテナID

# 未使用のリソースを一括削除
docker system prune -a

3. イメージ取得失敗:「image ... not found」

指定したイメージがDocker Hubで見つからない、またはネットワーク接続がない場合に発生します。

エラーメッセージ例:

failed to pull image "my-app:latest": failed to resolve reference ... not found

確認と解決方法:

# イメージが正しくpullできるか確認
docker pull nginx:latest

# ローカルに存在するイメージを確認
docker images

# docker-compose.ymlでイメージ名を再確認
services:
  web:
    image: nginx:latest  # タグまで正確に指定
    # または自作イメージの場合
    build:
      context: .
      dockerfile: Dockerfile

プライベートレジストリを使用している場合は、認証情報が必要です:

# Docker Hubにログイン
docker login

# プライベートレジストリの場合
docker login myregistry.azurecr.io -u username -p password

# その後、docker compose upを実行
docker compose up

4. ネットワーク接続エラー:「Can't reach database」

複数のコンテナ間の通信が失敗する場合です。Composeは自動でネットワークを作成しますが、設定の誤りがあると発生します。

よくあるシナリオ:

# アプリケーション側でのDB接続設定
# ❌ 間違い:localhostを指定
DATABASE_HOST=localhost

# ✅ 正しい:サービス名を指定
DATABASE_HOST=db  # docker-compose.ymlで定義したサービス名

正しいdocker-compose.ymlの例:

version: '3.8'
services:
  web:
    image: myapp:latest
    environment:
      DATABASE_HOST: db  # サービス名を使用
      DATABASE_PORT: 5432
    depends_on:
      - db  # 起動順序を保証
  
  db:
    image: postgres:15
    environment:
      POSTGRES_PASSWORD: password

ネットワーク設定を明示的に指定する方法もあります:

version: '3.8'
services:
  web:
    image: myapp:latest
    networks:
      - app-network
  
  db:
    image: postgres:15
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

5. ボリューム(ストレージ)パーミッション問題

ホストマシンのディレクトリをコンテナにマウントする際に、ファイルアクセス権が原因でエラーになることがあります。

エラーメッセージ例:

Permission denied while trying to connect to Docker daemon

解決方法:

# ホストディレクトリのパーミッション確認
ls -la ./app

# docker-compose.ymlでボリュームを正確に指定
services:
  web:
    image: myapp:latest
    volumes:
      - ./app:/app  # ホストパス:コンテナ内パス
      - ./data:/data:ro  # ro=読み取り専用

# Macの場合、Docker Desktopの設定確認
# 「Preferences」→「Resources」→「File Sharing」でパスを追加

デバッグ時は詳細ログを有効にします:

# ログレベルを上げて実行
docker compose --verbose up

6. 環境変数の未設定

.envファイルが見つからない、または環境変数が正しく読み込まれない場合です。

正しい設定方法:

# プロジェクトルートに.envファイルを作成
# .env
DB_PASSWORD=mypassword
API_KEY=secret123

# docker-compose.ymlで参照
services:
  db:
    image: postgres:15
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}  # ${}形式で参照
  
  api:
    image: myapi:latest
    environment:
      API_KEY: ${API_KEY}

複数の環境を管理する場合:

# 本番環境用の設定ファイルを指定
docker compose --env-file .env.production up

# 複数のenvファイルを使用
docker compose --env-file .env --env-file .env.local up

トラブルシューティングの実践的フロー

エラーが発生したとき、以下の順序で対応することをお勧めします:

# ステップ1: 構文検証
docker compose validate

# ステップ2: 現在のコンテナ状況を把握
docker ps -a

# ステップ3: 前の実行をリセット
docker compose down -v  # -vでボリュームも削除

# ステップ4: ログを詳細に確認しながら再起動
docker compose up --build  # イメージを再構築

# 特定サービスのログだけ確認
docker compose logs db  # dbサービスのログ

# リアルタイムでログを監視
docker compose logs -f web  # -fでfollow

本番環境でのベストプラクティス

開発環境と本番環境では異なる設定が必要です:

# docker-compose.yml(共通設定)
version: '3.8'
services:
  web:
    image: myapp:latest
    ports:
      - "8080:8080"

# docker-compose.prod.yml(本番環境設定を上書き)
version: '3.8'
services:
  web:
    ports:
      - "80:8080"  # ホストの80番ポートを使用
    restart: always  # 本番ではコンテナ再起動を有効化
    deploy:
      replicas: 3  # Swarm Mode使用時

# 実行コマンド
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d

代替手段との比較

Docker Composeは複数コンテナの管理に優れていますが、Kubernetes(k8s)やPodmanなどの選択肢もあります。Docker Composeは学習曲線が低く、ローカル開発や小~中規模環境に適しています。一方、Kubernetesは大規模本番環境での自動スケーリングなど高度な機能が必要な場合に向いています。

よくある質問

Docker Compose v2以降は統合されたDockerコマンドの一部になったため、docker composeが推奨されます。docker-composeは旧形式のスタンドアロンツールです。互換性のため両方使用できますが、新規プロジェクトはdocker composeを使用してください。

Docker Desktopのメモリ割り当てが不足しています。「Preferences」→「Resources」で割り当てメモリを増やしてください。または、docker-compose.ymlでサービスごとのメモリ制限を調整します:deploy: resources: limits: memory: 512M

PowerShellの制限です。GitBashまたはWSL2(Windows Subsystem for Linux 2)を使用するか、docker compose run --no-TTYを指定してください。

まとめ

  • docker compose validateでYAML構文を最初に確認する習慣をつける
  • ポート競合はlsof -i :ポート番号で特定し、別ポートへの変更か既存プロセスの停止で解決
  • コンテナ間通信にはサービス名を使用し、localhost接続は避ける
  • .envファイルで環境変数を一元管理し、本番環境用の別設定ファイルを用意する
  • docker compose logs -fでリアルタイムログ監視すればデバッグが効率化できる
  • 問題解決時はdocker compose down -vでリセットし、クリーンな状態から再実行する

Docker Compose公式ドキュメント

K
AWS・Python・生成AIを専門とするソフトウェアエンジニア。AI・クラウド・開発ワークフローの実践ガイドを執筆しています。詳しく見る →