Dockerコンテナ側からホストOS側のプログラムと通信をしたいなあと思うことがあったので、ちょっと調べて見ました。もちろん、Docker側のネットワークIPを指定すれば、アクセスできますけどもう少し簡単したいなあと思ってのことです。
Dockerで設定された名前を使ってアクセスを行う
Docker Desktop for Windows
やDocker Desktop for Mac
でしか使えないらしいですが、Dockerコンテナ側のOSからhost.docker.internal
を名前指定してアクセスするとDocker Desktop側のホストOSと通信を行うことができるようです。
これが求めていた機能だった感じですね。さすがにIPアドレスを覚えるというのは現実的ではないですし。
実験
まずはホスト側でHTTPサーバを起動したいのでpython3のワンライナーを使って起動しておきます。ローカル側からcurlコマンドでアクセスするのも確認しておきます。
ホスト側でHTTPサーバを起動
PS> python3 -m http.server 8080
続いてはDockerのコンテナを起動します。今回はほとんど機能が必要ないのでalpineのイメージを使用して起動しています。
コンテナ側のOSを起動
PS> docker run -it --rm alpine
OSが起動したらcurl
をインストールしてから、host.docker.internal
にアクセスを行います。
PS> docker run -it --rm alpine # apk add curl # curl http://host.docker.internal:8080/
もちろん、pingコマンド
からでもちゃんとアクセスできています。
コンテナ側の/etc/hosts
ファイルを起動オプションを使って変更し、アクセスを行う
2つ目の方法としては
dockerコマンド
の起動オプションに以下のオプションスイッチを追加することで、/etc/hostsファイル
にlocalhost
の名前でホスト側のDockerネットワークのIPアドレス追加することできます。
※ 追加するオプション
--add-host=localhost:【ホスト側のDockerネットワークのIPアドレス】
Dockerホスト側のネットワークのIPアドレスが172.28.224.1
だった場合の実行例
PS> docker run -it --rm --add-host=localhost:172.28.224.1 alpine
あまりlocalhost
に固執する理由が自分にはわからないのですが、開発上の理由はあるのかなと思うのでこうしますが、もちろん別のホスト名をつけることも可能です。
Dockerホスト側の名前をtest.dev
として、ネットワークのIPアドレスが172.28.224.1
だった場合の実行例
PS> docker run -it --rm --add-host=test.dev:172.28.224.1 alpine
実験
先程と同様にアクセスのテストを行ってみます。まずはpython3でワンライナーのサーバーを起動しておきます。
あとはコンテナを先程のオプションをつけて起動します。
PS> docker run -it --rm --add-host=test.dev:172.28.224.1 alpine # apk add curl # curl http://test.dev:8080/
アクセス後のホスト側のHTTPサーバーのログを確認するとちゃんとアクセスができています。
おわりに
Dockerコンテナ側からホスト側のアプリへのアクセスは問題なくできるようになりました。やっぱり簡単なのは、ホストOS側の環境の制限はありますが、host.docker.internal
を使ってのアクセスでしょうか。IPアドレスを覚えなくて良い点が利点です。
あとはコードへの埋め込みなどを考えるのであれば/etc/hosts
を変更してのホスト名を変える手もいいのかなと思います。