【Docker】Dockerネットワークの基本:コンテナ同士をつなぐ

Docker

こんにちは、かつコーチです。

Webアプリケーションのコンテナと、データベースのコンテナを別々に起動して、いざ通信させようとしたら「繋がらない」と焦った経験はありませんか。

コンテナは互いに隔離された環境で動いているため、何もしなければ他のコンテナとやり取りできません。

この記事では、コンテナ同士を通信させるためのDockerネットワークの基本を、実際のコマンド例と一緒に解説します。

Dockerネットワークとは?

部屋同士をつなぐ内線電話に例えると

Dockerネットワーク(コンテナ同士が通信するための仮想的な通信網です)は、オフィスの内線電話に例えるとイメージしやすいです。

それぞれのコンテナは、防音壁で仕切られた個室のようなものです。

何も設定しなければ、隣の部屋にいるコンテナに話しかけることすらできません。

Dockerネットワークを作って複数のコンテナを同じネットワークに参加させることは、部屋同士に内線電話を引くようなものです。

内線電話があれば、部屋番号(コンテナ名)を指定するだけで、外部の電話回線を経由せずに直接やり取りできるようになります。

なぜコンテナ間通信の設定が必要か

Webアプリケーションとデータベースのように、複数のコンテナが連携して1つのシステムを構成するケースは非常に多いです。

Dockerはデフォルトでbridgeネットワーク(コンテナをホストとは別の仮想ネットワークに接続する仕組みです)を用意していますが、デフォルトのbridgeネットワークでは、コンテナ名による自動的な名前解決が行われません。

そのため、コンテナ同士を安定して連携させるには、自分でネットワークを作成し、参加させるコンテナを明示的に指定する必要があります。

基本の使い方

docker network createでネットワークを作る

まず、コンテナ間通信用のネットワークを作成します。

docker network create my-app-network

作成したネットワークの一覧は、以下のコマンドで確認できます。

docker network ls

–networkオプションでコンテナを接続する

作成したネットワークに、コンテナを参加させて起動します。

docker run -d \
  --name my-db \
  --network my-app-network \
  -e MYSQL_ROOT_PASSWORD=example \
  mysql:8.0

docker run -d \
  --name my-web \
  --network my-app-network \
  -p 8080:80 \
  my-web-app:1.0

--network my-app-network を両方のコンテナに付けることで、同じネットワーク内に配置されます。

コンテナ名で名前解決する

同じユーザー定義ネットワークに参加しているコンテナ同士は、コンテナ名をホスト名として名前解決できます。

例えば my-web コンテナのアプリケーションコードから、データベースの接続先を以下のように指定できます。

DB_HOST=my-db
DB_PORT=3306

IPアドレスを直接指定する必要がなく、コンテナ名(my-db)を指定するだけで通信相手を見つけられるのが、ユーザー定義ネットワークの大きなメリットです。

よくあるつまずきポイント・エラー対処

localhostで繋がらない

実際に私が最初にハマったのが、接続先のホスト名として localhost を指定してしまうミスです。

❌ Before:localhostを接続先に指定してしまう

DB_HOST=localhost
DB_PORT=3306

このように設定してアプリケーションコンテナを起動したところ、以下のようなエラーでデータベースに接続できませんでした。

Error: connect ECONNREFUSED 127.0.0.1:3306

コンテナ内から見た localhost は、あくまで「そのコンテナ自身」を指します。

Webアプリケーションのコンテナから見た localhost にMySQLは存在しないので、当然接続できません。

私はホストマシンでの開発に慣れていたせいで、つい localhost と書いてしまい、このエラーメッセージを見てようやく「コンテナごとにlocalhostの意味が違う」と理解しました。

✅ After:コンテナ名をホスト名として指定する

DB_HOST=my-db
DB_PORT=3306

同じユーザー定義ネットワークに参加していれば、コンテナ名がそのまま名前解決可能なホスト名になります。

接続確認は、片方のコンテナから docker exec で相手にpingを打つとわかりやすいです。

docker exec -it my-web ping my-db

応用・一歩先の使い方

bridge/host/noneネットワークドライバの違い

Dockerネットワークには、用途に応じて複数のドライバ(ネットワークの実装方式です)が用意されています。

ドライバ特徴主な用途
bridgeコンテナ専用の仮想ネットワークを作る(デフォルト)単一ホスト内でのコンテナ間通信
hostコンテナがホストのネットワークを直接共有するポート変換のオーバーヘッドを避けたい場合
noneネットワークインターフェースを持たない完全に隔離したい場合

普段の開発では、ユーザー定義の bridge ネットワークを作成する今回の方法が基本になります。

hostnone は特殊な要件がある場合に検討する選択肢として、まずは名前だけ覚えておけば十分です。

まとめ

この記事のポイント

  • Dockerネットワークは、コンテナ同士をつなぐ内線電話のような仕組み
  • docker network create でネットワークを作り、--network オプションで参加させる
  • 同じユーザー定義ネットワーク内では、コンテナ名がそのままホスト名として名前解決できる
  • コンテナ間通信では localhost ではなくコンテナ名を接続先に指定する

次に読むべき記事

  • ボリュームでデータを永続化する
  • docker-composeとは?複数コンテナをまとめて管理する

タグ: Docker, 中級者向け, ネットワーク

タイトルとURLをコピーしました