第05回: ネットワークとサービス間通信 — コンテナはなぜ「localhost」で繋がらないのか?

章: 第1章: Docker基礎と環境理解

PHPからMySQLに接続しようとしたら繋がらない、なぜ?

DockerでPHPとMySQLを別々のコンテナで動かし、PHPから localhost でMySQLに接続しようとすると失敗します。「同じマシンで動いているのになぜ?」——これはDockerネットワークの仕組みを知ると一瞬で解決します。

この記事では、コンテナ間通信の仕組みとサービス名による名前解決を整理します。

Dockerネットワークを理解すると設定がシンプルになる

各コンテナは独立したネットワーク空間を持っています。localhost はそのコンテナ自身を指すため、別コンテナには届きません。

Docker Composeを使うと、同じ compose.yml 内のサービスは自動的に同じネットワークに配置され、サービス名でお互いにアクセスできるようになります。DNSのように名前解決が行われます。

localhost vs サービス名 の比較

設定方法 動作 推奨
DB_HOST: localhost コンテナ自身を参照 → 接続失敗
DB_HOST: 127.0.0.1 同上 → 接続失敗
DB_HOST: db db サービスへ名前解決 → 接続成功
DB_HOST: db.mynetwork カスタムネットワーク名付き 必要に応じて

チェックポイント: DB_HOST には必ずサービス名(db など)を指定しましょう。コンテナ間通信では localhost は絶対に使えません。

実際の設定サンプル


services:
  app:
    environment:
      DB_HOST: db
  db:
    image: mysql:8.4

# app から db:3306 へ接続できる

app コンテナから db:3306 へアクセスできます。ポートは内部ポート(3306)を使い、ホストへの公開ポートとは別物です。

まとめ & 次のステップ

  • コンテナ間では localhost は使えない、サービス名で接続する
  • Docker Compose は同一 compose.yml 内のサービスを自動的に同じネットワークに配置する
  • 接続先ポートは「内部ポート」を使う(ports: で公開したポートとは別)
  • docker compose exec app ping db でコンテナ間疎通を確認できる

次回は「Docker Composeの基本」を学びます。複数サービスを1つのファイルで管理し、1コマンドで起動・停止する方法を体系的に理解します。

Related Articles