動かない時
コンテナから外部に繋がらない
コンテナ内から `apt-get` / `npm install` / 外部 API が届かない問題。bridge / host ネットワーク、DNS 解決、プロキシの順で切り分けます。
症状
docker buildの途中のapt-get update/npm installがタイムアウトする- 起動したコンテナから
curl https://api.example.comが返ってこない - ping はホスト名では通らないが IP 直指定なら通る(DNS 問題)
- 社内ネットワークや会社 PC からだけ再現する(プロキシ問題)
docker composeの別サービス同士は繋がるが、外部は繋がらない
原因
コンテナ → 外部通信が経由する階層を順に疑います。
- コンテナ内 DNS:
/etc/resolv.confが適切か。Docker はデフォルトで8.8.8.8を入れるが、環境によっては社内 DNS しか解決できないゾーンがある - Docker ブリッジと NAT: 標準の
bridgeネットワークはホストの iptables/NAT でインターネットに抜ける。ホストのnet.ipv4.ip_forward=0やfirewalld/ufwがブロックしていると抜けない - ホストのプロキシ設定: 会社 PC では
HTTP_PROXY/HTTPS_PROXYが Docker エンジンに伝わらないとdocker build/docker pullがまず失敗。コンテナ内アプリにも伝える必要がある - コンテナの DNS 不整合: WSL2 + VPN や macOS + VPN でホスト DNS が途中でブロックされ、コンテナは固有の DNS を使って失敗する
- ネットワークモードの選択:
docker run --network=hostにしているとコンテナの独立ネットワークがないのでホスト側の制限が直撃する
確認コマンド
コンテナ内と外を両方見て、どの層で詰まっているかを特定します。
bash
# ホスト側: 素で外に繋がるか(まずここ)
curl -v https://registry-1.docker.io/v2/
nslookup registry-1.docker.io
# ホスト側: プロキシ環境変数
echo $HTTP_PROXY $HTTPS_PROXY $NO_PROXY
# コンテナ内: DNS 設定
docker run --rm busybox cat /etc/resolv.conf
# コンテナ内: ホスト名 / IP それぞれで到達性
docker run --rm busybox nslookup example.com
docker run --rm busybox ping -c 2 example.com
docker run --rm busybox ping -c 2 93.184.216.34 # example.com の代表 IP
# コンテナ内: HTTP まで届くか
docker run --rm curlimages/curl -v https://api.github.com
# ホストの IP 転送とファイアウォール
sysctl net.ipv4.ip_forward # 1 であること
sudo iptables -L -n -v | head -40 # FORWARD チェインが DROP していないか
# Docker の使っているネットワーク一覧と詳細
docker network ls
docker network inspect bridge解決策
- DNS を明示的に指定する: 一時的に
docker run --dns=8.8.8.8 --dns=1.1.1.1 ...、恒久化するなら/etc/docker/daemon.jsonに"dns": ["8.8.8.8", "1.1.1.1"]を書いて Docker デーモンを再起動 - 社内 DNS しか使えない環境: 社内 DNS の IP を
daemon.jsonのdnsに入れ、同時にsearchで社内ドメインサフィックスを指定する - IP フォワーディングが無効:
sudo sysctl -w net.ipv4.ip_forward=1、永続化は/etc/sysctl.d/99-docker.conf - プロキシが必要な環境:
- Docker デーモン向け:
/etc/systemd/system/docker.service.d/http-proxy.confにEnvironment="HTTP_PROXY=..."などを書いてsystemctl daemon-reload && systemctl restart docker docker build向け:~/.docker/config.jsonのproxiesセクションで設定するとビルド引数として自動で渡る(Docker 20.10+)- コンテナ実行向け:
docker run -e HTTP_PROXY=... -e HTTPS_PROXY=... -e NO_PROXY=localhost,127.0.0.1,.local
- Docker デーモン向け:
- ネットワークモードを見直す:
- 外部通信が主: デフォルトの
bridgeで十分 - 複数コンテナ同士の名前解決が必要:
docker network create mynetしてそこに参加させる(Compose なら自動) - ホストのポート・パフォーマンスが必要で安全性が担保できる:
--network=host(Linux のみ有効)
- 外部通信が主: デフォルトの
- WSL2 + VPN 問題:
.wslconfigのnetworkingMode=mirroredか、VPN 側で WSL2 のサブネットを除外設定にする docker composeで外部だけ切れるとき: Compose が作る<project>_defaultブリッジネットワークが NAT できていないケース。docker network inspect <project>_defaultでGatewayが妥当か確認し、必要ならnetworks: { default: { driver: bridge } }を明示
