KDOC 696: コンテナの中のlocalhostはそのコンテナ自身を指す
この文書のステータス
- 作成
- 2026-10-18 貴島
- レビュー
- 2026-10-18 貴島
概要
既定のブリッジネットワークでは、コンテナはそれぞれ自分のネットワークを持つので、コンテナの中の localhost (127.0.0.1)はそのコンテナ自身を指す。そのため、次の2つがよく起きる。
| 起きること | 対策 |
|---|---|
| コンテナの中のサーバが127.0.0.1で待ち受けると、ポートを公開してもホストマシンから届かない | 0.0.0.0で待ち受ける |
| 別のコンテナのRedisなどに127.0.0.1でつなごうとすると、自分自身につながって失敗する | Composeではサービス名でつなぐ |
Each container for a service joins the default network and is both reachable by other containers on that network, and discoverable by its service name.
0.0.0.0でよいのは、公開したポートへの通信がコンテナのループバック(127.0.0.1)ではなく、コンテナのネットワークの口( eth0 。172.17.0.xなど)へ転送されてくるからである。127.0.0.1で待ち受けたサーバはループバックに来た通信しか受け取らない。0.0.0.0はすべての口で待ち受ける指定なので、 eth0 に来た通信も受け取れる。
MANWIDTH=80 man 7 ip | tail -1
MANWIDTH=80 man 7 ip | grep -A1 -E 'When +INADDR_ANY +is +specified'
Linux man-pages 6.7 2024-03-17 ip(7)
pair. When INADDR_ANY is specified in the bind call, the socket will be
bound to all local interfaces. When listen(2) is called on an unbound
試す。
for addr in 127.0.0.1 0.0.0.0; do
docker run -d --rm --name lh -p 18080:8080 busybox httpd -f -p "$addr:8080" >/dev/null
sleep 1
ip=$(docker exec lh ip -4 -o addr show eth0 | awk '{print $4}' | cut -d/ -f1)
for url in "localhost:18080" "$ip:8080"; do
if curl -s -o /dev/null --max-time 2 "$url"; then r=応答あり; else r=応答なし; fi
echo "$addr で待ち受け、$url へ: $r"
done
docker rm -f lh >/dev/null
done
127.0.0.1 で待ち受け、localhost:18080 へ: 応答なし
127.0.0.1 で待ち受け、172.17.0.4:8080 へ: 応答なし
0.0.0.0 で待ち受け、localhost:18080 へ: 応答あり
0.0.0.0 で待ち受け、172.17.0.4:8080 へ: 応答あり
関連
なし。