WSL2環境でのDocker host.docker.internal解決エラーの対処法
なにこれ
WSL2 + Docker 環境で開発してると、
host.docker.internal にアクセスしようとして「繋がらない…」ってなったこと、ありませんか?
例えばこんなエラー:
Error creating agent_session: HTTPConnectionPool(host='host.docker.internal', port=37443):
Max retries exceeded with url: /alive
(Caused by ConnectTimeoutError(..., 'Connection to host.docker.internal timed out. (connect timeout=5)'))
この記事では、このエラーが出る原因と、サクッと解決する方法を紹介します。
🤔 そもそも何が起きているのか?
WSL2は独自の仮想ネットワークの中で動いています。
そのせいで、WSL2内から host.docker.internal を名前解決しようとしても、うまくいかないことがあります。
つまり、WindowsホストのIPが見えない or 解決できないという状態。
Docker Desktopならホスト名が使えることもありますが、WSL2ではちょっと工夫が必要です。
✅ 解決方法(結論)
/etc/hosts にホストのIPを追加する。
echo "$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}') host.docker.internal" | sudo tee -a /etc/hosts
これだけで host.docker.internal が正しく解決できるようになります。
💡 なんでこれで解決するの?
WSL2の resolv.conf に書かれている nameserver は、WindowsホストのIPなんです。
これをそのまま /etc/hosts に host.docker.internal として登録することで、
WSL2からもDockerコンテナからも正しくホストに接続できるようになるということでした。
🔍 動作確認してみる
ping host.docker.internal ✔
PING host.docker.internal (1.1.1.1) 56(84) bytes of data.
64 bytes from host.docker.internal (1.1.1.1): icmp_seq=1 ttl=57 time=3.88 ms
64 bytes from host.docker.internal (1.1.1.1): icmp_seq=2 ttl=57 time=3.33 m
Dockerコンテナ内でも確認するには以下のようにする。
docker run --rm alpine ping host.docker.internal
どちらも ping が通ればOK!
🛠 docker-compose.yml に書く方法もある
services:
your-service:
extra_hosts:
- "host.docker.internal:host-gateway"
これでもうまくいかない場合は、/etc/hosts への追記はわりと確実な方法かと思います。(私はそうしました。)
⚠️ Tips
WSL2を再起動すると、ホストのIPが変わることがある
つまり、/etc/hosts に書いたIPが古くなる
なので、起動時に毎回自動更新するスクリプトを入れておくのがオススメ
たとえば、~/.bashrc や ~/.zshrc に以下を追加しておくと便利:
# 自動で /etc/hosts 更新
ip=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}')
grep -q "host.docker.internal" /etc/hosts || echo "$ip host.docker.internal" | sudo tee -a /etc/hosts
Discussion