Dockerコンテナが起動しない時の原因特定と解決方法

本記事では、Dockerコンテナが起動しない主な原因7つとその解決策を実践的に解説します。ログの読み方からネットワーク設定まで、すぐに仕事で活用できるトラブルシューティング手順を紹介します。

Dockerコンテナが起動しない主な原因

Dockerコンテナが起動しない場合、原因は大きく分けて3つのカテゴリに分類されます:イメージの問題コンテナの設定エラーリソース不足またはポート競合です。最初に行うべきは、詳細なエラーログの確認です。

ステップ1:ログで原因を特定する

起動失敗時のエラーログを確認

コンテナの起動に失敗した場合、まずは以下のコマンドで詳細ログを確認してください。

docker logs <コンテナID>

すでにコンテナが存在しない場合でも、起動前のエラーメッセージを確認できます:

docker run --name test-container my-image 2>&1 | head -50

詳細な診断情報を表示

より詳細な情報が必要な場合は、以下のコマンドでコンテナの状態を確認します:

docker container inspect <コンテナID>

このコマンドにより、ネットワーク設定、マウント状態、環境変数など、すべての設定情報を JSON 形式で取得できます。

原因1:イメージが存在しない、または破損している

イメージの存在確認

最も一般的な原因として、指定したイメージがローカルに存在しないケースがあります。以下のコマンドでインストール済みイメージを確認してください:

docker images

イメージが一覧に表示されない場合、以下の方法で取得します:

docker pull my-image:latest

イメージの検証と再ビルド

Dockerfile を修正した直後の場合、古いキャッシュが原因で起動に失敗することがあります。キャッシュをクリアして再ビルドしてください:

# キャッシュを無視してイメージを再ビルド
docker build --no-cache -t my-image:latest .

原因2:ポート競合またはバインドエラー

使用中のポートを確認

コンテナが起動時に指定したポートが既に使用されている可能性があります。以下のコマンドでポート使用状況を確認しましょう:

docker ps

ホスト側のポート使用状況を確認するには:

# macOS / Linux
lsof -i :[ポート番号]

# Windows
netstat -ano | findstr :[ポート番号]

別のポートでバインドする

既に使用されているポートがある場合、異なるポート番号を指定します:

docker run -p 8081:8080 my-image

または、docker-compose.yml で複数のコンテナを管理する場合:

version: '3.9'
services:
  app:
    image: my-image
    ports:
      - "8081:8080"  # ホストポート:コンテナポート
    environment:
      - PORT=8080

原因3:メモリ不足またはリソース制限

コンテナのリソース使用状況を確認

Dockerデーモンのリソース不足が原因の場合、以下のコマンドで稼働中のコンテナのリソース使用状況を確認します:

docker stats

メモリ制限を超えたことが原因でコンテナが強制終了される場合があります。確認方法は:

docker logs <コンテナID> | grep -i "OOMKilled"

メモリ制限を増やす

コンテナ起動時にメモリ制限を明示的に設定します:

docker run -m 2g --memory-swap 2g my-image

docker-compose.yml を使用する場合:

version: '3.9'
services:
  app:
    image: my-image
    deploy:
      resources:
        limits:
          memory: 2G
        reservations:
          memory: 1G

原因4:マウントポイントの権限またはパス指定エラー

ボリュームマウントのエラーを特定

ホストとコンテナ間でファイルをマウントする際、パスが存在しない、または権限がないことが原因で起動に失敗することがあります。ログで確認:

docker logs <コンテナID> | grep -i "mount\|permission"

マウントパスの確認と修正

以下のコマンドで、マウントが正常に設定されているか確認します:

docker inspect <コンテナID> | grep -A 5 "Mounts"

ホスト側のパスが存在することを確認してから起動してください:

docker run -v /host/path:/container/path my-image

または、名前付きボリュームを使用することをお勧めします(パスの存在確認が不要):

docker run -v my-volume:/container/path my-image

原因5:環境変数の不足または不正な値

必須環境変数の確認

アプリケーションが起動時に特定の環境変数を必要とする場合、指定漏れが原因で失敗します。Dockerfile または起動スクリプトで確認:

docker run -e DATABASE_URL="postgresql://user:pass@host/db" my-image

複数の環境変数を指定する場合は、ファイルから読み込むと管理しやすくなります:

docker run --env-file .env my-image

.env ファイルの例:

DATABASE_URL=postgresql://user:pass@localhost/db
API_KEY=your-secret-key
DEBUG=false

原因6:ヘルスチェックの失敗

ヘルスチェック設定の問題

docker-compose.yml でヘルスチェック(healthcheck)を設定している場合、起動直後のチェック失敗が原因で起動と判定されないことがあります:

version: '3.9'
services:
  app:
    image: my-image
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
      interval: 10s
      timeout: 5s
      retries: 3
      start_period: 20s  # 起動後このくらい待ってからチェック開始

start_period を十分に長く設定することで、アプリケーションの起動完了を待ってからチェックを開始します。

原因7:ネットワークドライバーの設定エラー

ネットワーク設定の確認

複数のコンテナを相互接続する場合、カスタムネットワークを使用しないとコンテナ名での通信ができません:

docker network ls

カスタムネットワークの作成と使用

以下のコマンドでカスタムネットワークを作成します:

docker network create my-network

コンテナ起動時にネットワークを指定:

docker run --network my-network --name app my-image

docker-compose を使用する場合、デフォルトでカスタムネットワークが作成されるため、サービス名で通信可能です:

version: '3.9'
services:
  web:
    image: nginx
  app:
    image: my-image
    depends_on:
      - web
    environment:
      - WEB_HOST=web  # サービス名でアクセス可能

実践的なトラブルシューティング手順

チェックリスト

コンテナ起動に失敗した際は、以下の順序で確認してください:

# 1. ログを確認
docker logs <コンテナID>

# 2. イメージが存在するか確認
docker images | grep my-image

# 3. ポート競合を確認
docker ps

# 4. ホストのポート使用状況を確認(macOS/Linux)
lsof -i :[ポート番号]

# 5. コンテナの詳細設定を確認
docker inspect <コンテナID>

# 6. Docker デーモンのシステムリソースを確認
docker system df

デバッグモードでの実行

通常の起動で失敗する場合、コンテナ内でインタラクティブシェルを起動してデバッグします:

docker run -it --name debug my-image /bin/bash

このコマンドでコンテナ内に入り、スクリプトやアプリケーションを手動で実行して何が起こっているか確認できます。

よくある質問

A: 起動直後に終了してしまう可能性があります。docker ps -a でコンテナの状態を確認し、ExitCode が 0 以外の場合は異常終了しています。ENTRYPOINT や CMD に /bin/bash を指定して、手動でデバッグするのが効果的です。

A: docker-compose config で YAML ファイルの構文エラーを確認してください。その後、docker-compose logs -f service-name で各サービスのログをリアルタイム確認すると原因が明確になります。

A: docker-compose.yml で deploy.resources.limits を設定し、メモリ制限を明示的に指定することをお勧めします。また、docker stats で定期的に監視し、使用状況に応じてリソースを調整してください。

まとめ

  • ログ確認が最優先:docker logs で 90% の原因は特定できます
  • ポート競合は docker pslsof の併用で素早く確認できます
  • マウントとネットワークの設定ミスは複合要因になりやすいため、docker inspect で全体を確認しましょう
  • 本番環境ではメモリ制限とヘルスチェックの設定が必須です
  • docker-compose 使用時は docker-compose config で構文を常に検証してください
  • 原因特定が難しい場合は、デバッグモード(-it /bin
K
AWS・Python・生成AIを専門とするソフトウェアエンジニア。AI・クラウド・開発ワークフローの実践ガイドを執筆しています。詳しく見る →