Docker コンテナ間通信の実践:Web と DB を名前でつなぐ正しい方法
金曜の午後 3 時、ローカル開発環境のコンテナ化を仕上げようとしていました。MySQL コンテナは起動、Node.js アプリコンテナも動いている——あとはつなぐだけ、と思っていました。ブラウザを更新すると 500 エラー。ログには「Connection refused」が並んでいます。
両方のコンテナが動いているのに、なぜ? MySQL コンテナ名で ping すると「unknown host」。IP で試すと通る。アプリも DB に接続できました。ほっとしてコミットし、帰宅。
月曜に戻ると悲劇です。アプリがまた落ちている。MySQL コンテナ再起動で IP が 172.17.0.2 から 172.17.0.3 に変わっていた。毎回再起動のたびに設定を直すのか——本当にきつかった。
同じ経験があるなら、この記事はあなた向けです。Docker のネットワークを一午後かけて調べ、コンテナ間通信の正しいやり方がわかりました。次を共有します。
- コンテナ名で ping できない根本原因
- デフォルトネットワークの制限
- カスタムネットワークでの解決
- 名前で相互アクセスする実践手順
- 応用のコツとベストプラクティス
なぜコンテナ名で ping できないのか
Docker デフォルトネットワークの制限
原因は Docker のデフォルトネットワーク設定にあります。ネットワークを指定せず起動すると、コンテナは自動的にデフォルトの bridge ネットワーク(docker0 ブリッジ)に接続されます。
このデフォルトネットワークには大きな制限があります。IP アドレス通信のみで、コンテナ名解決に非対応です。
つまりデフォルトネットワークでは:
- ✅ IP で他コンテナにアクセスできる(例:
ping 172.17.0.2) - ❌ コンテナ名ではアクセスできない(例:
ping mysql-containerは失敗)
なぜか。デフォルトネットワークには組み込み DNS がないからです。連絡先帳のない携帯のように、番号(IP)は覚えられるが名前(コンテナ名)では相手を特定できません。
さらに厄介なのは、コンテナ再起動のたびに Docker が IP を再割り当てすることです。今日 172.17.0.2 で MySQL に繋がっても、明日再起動後は 172.17.0.3 かもしれず、アプリ設定の IP は無効になります。
コマンドで確認しました:
# MySQL コンテナ起動(デフォルトネットワーク)
docker run -d --name mysql-demo \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:8.0
# ネットワーク確認用 busybox コンテナ
docker run -it --name test-box busybox sh
# test-box 内で MySQL コンテナ名を ping
/ # ping mysql-demo
ping: bad address 'mysql-demo' # ← 名前解決失敗
# MySQL の IP を確認
docker inspect mysql-demo | grep IPAddress
# "IPAddress": "172.17.0.2"
# IP なら ping 成功
/ # ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: seq=0 ttl=64 time=0.123 ms
コンテナ名では ping できず、IP だけ、という状態です。
--link パラメータは非推奨
古いチュートリアルでは --link が出てきます。Docker 初期の解決策です。
docker run --link mysql-demo:mysql -d my-app
これで my-app から「mysql」という名前で mysql-demo にアクセスできます。ただし Docker 公式は --link を推奨しておらず、将来バージョンで削除予定です。
非推奨の理由:
- 一方向接続:my-app → mysql のみ。逆方向は不可
- 保守が大変:コンテナが増えると
--link設定が複雑化 - 機能が限定的:柔軟なマルチコンテナネットワーク管理に不向き
まだ --link を使っているなら、新しい方法への移行をおすすめします。
カスタムネットワーク:コンテナ間通信の正しい方法
カスタムネットワークのメリット
Docker 1.12 以降の docker network が公式推奨のコンテナ間通信方式です。
カスタム bridge ネットワークの利点:
-
自動 DNS 解決:組み込み DNS がコンテナ名を IP に解決。「連絡先帳」付きネットワークのイメージです。
-
ネットワーク分離:異なるカスタムネットワーク間のコンテナはデフォルトで隔離。フロント・バックエンド・DB を別ネットワークに分け、セキュリティを高められます。
-
保守性:再起動で IP が変わってもコンテナ名を使えば DNS が更新されるため、アプリ設定を変える必要がありません。
-
マルチネットワーク:1 コンテナが複数ネットワークに参加でき、複雑なトポロジも可能です。
最初は Docker ネットワークが難しく感じますが、この 4 点がわかると一気に整理できます。
カスタムネットワークの作成
作成コマンドはシンプルです:
# 最もシンプル:名前だけ指定
docker network create my-app-net
# フルオプション版
docker network create \
--driver bridge \ # ドライバ(デフォルトは bridge)
--subnet 172.20.0.0/16 \ # カスタム IP レンジ(任意)
--gateway 172.20.0.1 \ # カスタムゲートウェイ(任意)
my-app-net # ネットワーク名
多くの場合、最初のシンプルな方法で十分です。Docker が競合しない IP レンジを自動割り当てします。
作成後、詳細確認:
docker network inspect my-app-net
IP レンジ、ゲートウェイ、接続済みコンテナなどが確認できます。
コンテナをカスタムネットワークに参加させる
参加方法は 2 つあります。
方法 1:起動時に指定(推奨)
docker run -d \
--name mysql-demo \
--network my-app-net \ # ← 重要
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:8.0
方法 2:実行中コンテナを後から接続
# 既に動いているコンテナがある場合
docker network connect my-app-net existing-container
起動時指定がおすすめです。方法 2 は既存コンテナを新ネットワークへ移行するとき向けです。
実践:Web アプリから MySQL に接続する
理論はここまで。Node.js アプリコンテナが MySQL DB コンテナに接続する手順を見ていきます。
シナリオ
目標:
- MySQL コンテナ名
mysql-server、カスタムネットワーク上で稼働 - Node.js アプリコンテナ名
node-app、同一ネットワーク - アプリは IP ではなくコンテナ名
mysql-serverで DB に接続
実装手順
ステップ 1:カスタムネットワーク作成
docker network create my-app-net
ネットワーク ID が出力されれば成功です。
ステップ 2:MySQL コンテナを起動してネットワークに参加
docker run -d \
--name mysql-server \
--network my-app-net \
-e MYSQL_ROOT_PASSWORD=my-secret-pw \
-e MYSQL_DATABASE=myapp_db \
mysql:8.0
パラメータ:
--name mysql-server:後で DB の host として使う名前--network my-app-net:作成したネットワークへ接続-e MYSQL_ROOT_PASSWORD:root パスワード-e MYSQL_DATABASE:初期データベース作成
ステップ 3:アプリコンテナを起動
docker run -d \
--name node-app \
--network my-app-net \
-p 3000:3000 \
-e DB_HOST=mysql-server \
-e DB_USER=root \
-e DB_PASSWORD=my-secret-pw \
-e DB_NAME=myapp_db \
my-node-app:latest
DB_HOST=mysql-server に注目——IP ではなくコンテナ名です。
ステップ 4:アプリコードでコンテナ名を host に使う
Node.js の例:
const mysql = require('mysql2');
const connection = mysql.createConnection({
host: process.env.DB_HOST, // 'mysql-server'(コンテナ名)
user: process.env.DB_USER, // 'root'
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME
});
connection.connect((err) => {
if (err) {
console.error('データベース接続失敗:', err);
return;
}
console.log('MySQL に接続成功!');
});
host にコンテナ名 mysql-server を指定すれば、Docker DNS が現在の IP に解決します。
ステップ 5:疎通確認
docker exec -it node-app sh
/ # ping mysql-server
PING mysql-server (172.20.0.2): 56 data bytes
64 bytes from 172.20.0.2: seq=0 ttl=64 time=0.089 ms
64 bytes from 172.20.0.2: seq=1 ttl=64 time=0.096 ms
コンテナ名の解決と ping が成功します。
DNS 解決の確認:
/ # nslookup mysql-server
Server: 127.0.0.11 # ← Docker 組み込み DNS
Address: 127.0.0.11:53
Name: mysql-server
Address: 172.20.0.2 # ← MySQL の現在 IP
カスタムネットワークでは DNS サーバー(127.0.0.11)がコンテナ名を解決します。
MySQL を再起動して IP が変わっても、アプリは影響を受けません。DNS が解決を更新します。
トラブルシューティング
よく使う確認コマンド:
1. ネットワーク詳細
docker network inspect my-app-net
JSON で IP レンジ、ゲートウェイ、接続コンテナと各 IP が確認できます。
2. コンテナのネットワーク設定
docker inspect mysql-server | grep -A 20 Networks
接続ネットワークと各ネットワーク上の IP がわかります。
3. コンテナログ
docker logs node-app
docker logs mysql-server
接続エラーの詳細はログに出ることが多いです。
よくある問題と対処:
| 問題 | 想定原因 | 対処 |
|---|---|---|
| コンテナ名で ping 失敗 | 同一ネットワークにいない | docker network inspect で確認、docker network connect で接続 |
| ping は通るがアプリ接続失敗 | ポート設定ミス | アプリのポートと MySQL のリスン(デフォルト 3306)を確認 |
| DB が接続拒否 | 認証情報・権限 | 環境変数を確認、MySQL コンテナ内でユーザー権限を確認 |
| DNS 解決エラー | デフォルトネットワーク使用 | カスタムネットワークを作り、コンテナを再起動 |
応用のコツとベストプラクティス
マルチネットワーク:フロントとバックの分離
実プロジェクトでは、フロント・バックエンド・DB を別レイヤのネットワークに分けることもあります。
docker network create frontend-net
docker network create backend-net
docker run -d --name nginx \
--network frontend-net \
-p 80:80 \
nginx:latest
docker run -d --name api-server \
--network frontend-net \
my-api:latest
docker network connect backend-net api-server
docker run -d --name postgres \
--network backend-net \
-e POSTGRES_PASSWORD=secret \
postgres:14
効果:
- nginx は api-server にアクセスできるが DB にはアクセスできない
- api-server は DB にアクセスできる
- DB はバックエンドからのみ到達可能でより安全
当社プロジェクトでもこの構成を使っています。
Docker Compose で管理を簡素化
コンテナが多いと手動管理は大変です。Docker Compose が有効です。
docker-compose.yml の例:
version: '3.8'
services:
mysql:
image: mysql:8.0
container_name: mysql-server
environment:
MYSQL_ROOT_PASSWORD: my-secret-pw
MYSQL_DATABASE: myapp_db
networks:
- app-network
volumes:
- mysql-data:/var/lib/mysql
app:
image: my-node-app:latest
container_name: node-app
ports:
- "3000:3000"
environment:
DB_HOST: mysql # ← service 名(container_name ではない)
DB_USER: root
DB_PASSWORD: my-secret-pw
DB_NAME: myapp_db
networks:
- app-network
depends_on:
- mysql
networks:
app-network:
driver: bridge
volumes:
mysql-data:
一発起動:
docker-compose up -d
Compose が自動で:
- app-network を作成
- 全コンテナをネットワークに接続
- コンテナ間 DNS を設定
- depends_on の順で起動(mysql → app)
停止・クリーンアップ:
docker-compose down
docker-compose down -v # ボリュームも削除
個人的にはほぼ Compose 一択です。効率が段違いです。
その他のネットワークモード
bridge 以外にも用途別モードがあります。
| ネットワークモード | 用途 | 特徴 |
|---|---|---|
| bridge | 単一ホスト上のマルチコンテナ | デフォルト。ブリッジ経由で隔離通信 |
| host | 高性能ネットワークが必要 | ホストネットワークを直接使用。隔離なし、最速 |
| overlay | マルチホスト通信 | Swarm / Kubernetes 向け。複数マシン間の接続 |
| none | 完全隔離 | ネットワーク IF なし。高セキュリティ用途 |
多くの場合は カスタム bridge で十分です。host は高頻度取引など極端な性能要求向け。overlay はオーケストレーション基盤の話で、通常は手動設定不要です。
よくある質問(FAQ)
Q1: IP では通るのにコンテナ名では通らないのはなぜ?
A: デフォルト bridge ネットワーク(docker0)にいるためです。DNS がなくコンテナ名解決に非対応。カスタムネットワークを作り、コンテナを参加させてください。
Q2: --link はまだ使える?
A: 今は動きますが非推奨で、将来削除の可能性があります。カスタムネットワークへ移行を。機能も強く、将来性があります。
Q3: カスタムネットワークは性能に影響する?
A: ほぼありません。デフォルトもカスタムも bridge で実装は同じ。DNS 分の差は無視できるレベルです。
Q4: コンテナはインターネットにアクセスできる?
A: 通常、bridge のコンテナは NAT で外部ネットワークに出られます。出られない場合は iptables やホスト側ネットワーク設定を確認してください。
Q5: 既存コンテナをカスタムネットワークへ移すには?
A:
docker network connect my-app-net old-container
docker network disconnect bridge old-container # 任意
ただし --network で新規作成する方がおすすめです。
Q6: コンテナ名に大文字は使える?
A: 使えますが非推奨です。DNS 慣習では小文字・数字・ハイフンが無難です。
Q7: 1 コンテナが複数ネットワークにいられる?
A: はい。docker network connect で複数参加でき、複雑なトポロジが組めます。
まとめ
要点のおさらいです。
ステップ 1:問題の理解
- デフォルトネットワークはコンテナ名解決不可、IP のみ
- 再起動で IP が変わり接続が壊れる
--linkは非推奨、使わない
ステップ 2:カスタムネットワーク作成
docker network create my-app-net
ステップ 3:ネットワーク参加とコンテナ名通信
docker run -d --name mysql-server --network my-app-net mysql:8.0
# アプリ側
host: 'mysql-server' // IP ではなくコンテナ名
シンプルで Docker 公式推奨。コンテナ化アプリが安定し、保守も楽になります。
マイクロサービスやマルチコンテナプロジェクトなら:
- 今すぐ試す:既存プロジェクトをカスタムネットワーク化し、IP ハードコードをやめる
- Compose を試す:コンテナが 3 つ以上なら Compose 管理が楽
- 深掘りする:overlay と Kubernetes ネットワーク——クラウドネイティブの基礎
コンテナネットワークには学習曲線がありますが、一度掴むと Docker が格段に使いやすくなります。ターミナルを開き、最初のカスタムネットワークを作ってみてください。
コメント欄で質問があれば、できる範囲で返信します。
Docker コンテナ間通信の完全設定フロー
カスタムネットワークでコンテナ名解決の失敗と IP 変動を解決し、Web と DB を安定接続する
⏱️ 目安時間: 15 分
- 1
ステップ1: 問題の根源を理解する:デフォルトネットワークの制限
問題の根源:
• Docker のデフォルトネットワーク(bridge)は IP アドレス通信のみで、コンテナ名解決に非対応
• コンテナ再起動のたびに IP が再割り当てされ、アプリ設定の IP が無効になる
デフォルトネットワークの制限:
• 組み込み DNS がなく、IP でしかアクセスできない
• コンテナ名の ping が失敗する(unknown host)
• IP は変わるため本番向きではない
実際のシーン:
• MySQL コンテナは起動、Node.js アプリコンテナも動いている
• しかしアプリはコンテナ名で DB に接続できず、IP のみ
• 再起動で IP が変わり、設定が壊れる - 2
ステップ2: カスタムネットワークを作成する
カスタムネットワークの作成:
• docker network create でカスタムネットワークを作成
• コマンド:docker network create my-app-net
• コンテナ名解決に対応し、名前で相互アクセスできる
• IP が変わってもアプリ設定はそのまま
作成確認:
• docker network ls で一覧確認
• カスタムネットワークが作成されたことを確認 - 3
ステップ3: 起動時にネットワークを指定する
起動時のネットワーク指定:
• --network パラメータでネットワークを指定
• コマンド:docker run -d --name mysql-server --network my-app-net mysql:8.0
• アプリでは host: 'mysql-server'(IP ではなくコンテナ名)
接続確認:
• docker exec -it web-container ping mysql-server で ping
• またはアプリから DB 接続をテスト - 4
ステップ4: docker-compose でネットワークを自動作成する
応用:docker-compose でネットワークを自動作成
docker-compose.yml でネットワーク定義:
• networks:
my-app-net:
driver: bridge
• サービスは同一ネットワークに参加し、コンテナ名が自動解決。設定がシンプルで信頼性が高い
docker-compose の例:
• services でサービス定義
• networks でネットワーク定義
• 指定ネットワークに自動参加、コンテナ名解決
シンプルかつ Docker 公式推奨。コンテナ化アプリが安定し、保守も楽になる。
FAQ
なぜコンテナ名で ping できない?デフォルトネットワークの制限は?
デフォルトネットワークの制限:
• 組み込み DNS がない
• IP でしかアクセスできない
• コンテナ名の ping が失敗(unknown host)
• IP は変わるため本番向きではない
実際のシーン:MySQL は起動、Node.js も動いているが、コンテナ名では DB に接続できず IP のみ。再起動で IP が変わり設定が壊れる。
コンテナ間通信の問題はどう解決する?カスタムネットワークの設定は?
実践の流れ:
1. カスタムネットワーク作成:docker network create my-app-net
2. 起動時にネットワーク指定:docker run --network my-app-net
3. アプリでコンテナ名を host に:host: 'mysql-server'
4. 接続確認:コンテナ名で ping またはアプリ接続テスト
docker-compose でコンテナネットワークをどう設定する?
設定手順:
• docker-compose.yml で networks を定義(networks: my-app-net: driver: bridge)
• サービスは同一ネットワークに自動参加
• コンテナ名が自動解決
• 設定がシンプルで信頼性が高い
docker-compose の例:
• services でサービス定義
• networks でネットワーク定義
• 指定ネットワークに自動参加
• コンテナ名解決
シンプルかつ Docker 公式推奨。コンテナ化アプリが安定し、保守も楽になる。
4分で読めます · 公開日: 2025年12月17日 · 更新日: 2026年6月8日
Docker 実践ガイド
検索からこのページに来た場合は、前後の記事もあわせて読むと同じテーマの理解がかなり早く深まります。
前の記事
Dockerネットワークモード完全解説:bridge/host/none/containerの4モード性能比較と使い分け
Dockerの4つのネットワークモード(bridge/host/none/container)の仕組み、性能比較、適用シナリオを深掘り解説。正しいネットワーク設定の選び方を実践例と意思決定ガイド付きで紹介します。
第 17 / 37 記事
次の記事
Docker ポートマッピング:「port already allocated」で金曜の夜を台無しにしない
ポート占有の排查からパフォーマンス最適化まで、Docker ポートマッピングのあらゆる悩みを体系的に解決。port already allocated エラーとおさらばしましょう。
第 19 / 37 記事
関連記事
Dockerfile入門:ゼロから最初の Docker イメージを作る(実例付き)
Dockerfile入門:ゼロから最初の Docker イメージを作る(実例付き)
Docker vs 仮想マシン:5分で理解する性能差とシーン別選び方ガイド
Docker vs 仮想マシン:5分で理解する性能差とシーン別選び方ガイド
Docker インストールの落とし穴ガイド 2025:permission denied から正常起動までの完全解決策
コメント
GitHubアカウントでログインしてコメントできます