Dockerのコンテナからホスト側アプリへの通信を行う

Dockerコンテナ側からホストOS側のプログラムと通信をしたいなあと思うことがあったので、ちょっと調べて見ました。もちろん、Docker側のネットワークIPを指定すれば、アクセスできますけどもう少し簡単したいなあと思ってのことです。

Dockerで設定された名前を使ってアクセスを行う

Docker Desktop for WindowsDocker Desktop for Macでしか使えないらしいですが、Dockerコンテナ側のOSからhost.docker.internalを名前指定してアクセスするとDocker Desktop側のホストOSと通信を行うことができるようです。

f:id:ueponx:20210602002416p:plain

参考 docs.docker.com

これが求めていた機能だった感じですね。さすがにIPアドレスを覚えるというのは現実的ではないですし。

実験

まずはホスト側でHTTPサーバを起動したいのでpython3のワンライナーを使って起動しておきます。ローカル側からcurlコマンドでアクセスするのも確認しておきます。

ホスト側でHTTPサーバを起動

PS> python3 -m http.server 8080

f:id:ueponx:20210601232959p:plain

続いてはDockerのコンテナを起動します。今回はほとんど機能が必要ないのでalpineのイメージを使用して起動しています。

コンテナ側のOSを起動

PS> docker run -it --rm  alpine

f:id:ueponx:20210601232956p:plain

OSが起動したらcurlをインストールしてから、host.docker.internalにアクセスを行います。

PS> docker run -it --rm alpine

# apk add curl
# curl http://host.docker.internal:8080/

f:id:ueponx:20210602001752p:plain

もちろん、pingコマンドからでもちゃんとアクセスできています。

f:id:ueponx:20210601233016p:plain

コンテナ側の/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でワンライナーのサーバーを起動しておきます。

f:id:ueponx:20210601233007p:plain

あとはコンテナを先程のオプションをつけて起動します。

PS> docker run -it --rm --add-host=test.dev:172.28.224.1  alpine

# apk add curl
# curl http://test.dev:8080/

f:id:ueponx:20210601233019p:plain

アクセス後のホスト側のHTTPサーバーのログを確認するとちゃんとアクセスができています。

f:id:ueponx:20210601233003p:plain

おわりに

Dockerコンテナ側からホスト側のアプリへのアクセスは問題なくできるようになりました。やっぱり簡単なのは、ホストOS側の環境の制限はありますが、host.docker.internalを使ってのアクセスでしょうか。IPアドレスを覚えなくて良い点が利点です。 あとはコードへの埋め込みなどを考えるのであれば/etc/hostsを変更してのホスト名を変える手もいいのかなと思います。

/* -----codeの行番号----- */