docker
docker-compose

Dockerのコンテナの中からホストOS上のプロセスと通信する方法

問題点

Docker で起動したコンテナ内からホストOS(ローカルPC)内のプロセスと通信する際に、
localhost と指定しがちだけど localhost だとコンテナ内を指してしまい、
意図した通りに通信することができない。

例えば、ホストOS上で 80ポートで Listen している Nginx が起動していて、
コンテナ内のプログラムから http://localhost:80 でアクセスしても接続できない。

これは通常のプロセスだけじゃなく、docker で複数のコンテナを起動して、
コンテナ同士で通信する場合も同じように接続できない。

解決方法

その1:ホストOSのIPアドレスを指定する

ホストOSのIPアドレスが 192.168.11.1 だとして、http://192.168.11.1:80 でアクセスするようにする。

その2:dockerコマンドの引数で指定する

Dockerで/etc/hostsファイルが操作出来ない対策 で紹介されているように
docker run コマンドの引数(--add-host=[])でホスト名とIPアドレスの紐付けをコンテナに認識させ、
アクセスするときにそのホスト名を使用する。

docker run --add-host=local_dev:192.168.11.1 ・・・

で起動したときに、http://local_dev:80 でアクセスする

その3:docker-compose.yml で指定する

docker run--add-host=[] と同じことが docker-compose.ymlextra_hosts でもできる

docker-compose.yml
  extra_hosts:
   - "local_dev:192.168.11.1"

その4:docker-compose.yml で指定 + 環境変数を使う

DHCPなどでIPアドレスが変わる可能性がある場合、変わるたびに docker-compose.yml を変更する必要があるので
自IPアドレスを環境変数に入れるとその手間が省ける。

以下のコマンドを .bashrc.bash_profile に記述し、

export LOCAL_HOST_IP=`ifconfig en0 | grep inet | grep -v inet6 | sed -E "s/inet ([0-9]{1,3}.[0-9]{1,3}.[0-9].{1,3}.[0-9]{1,3}) .*$/\1/" | tr -d "\t"`

docker-compose.yml を以下のように変更する。

docker-compose.yml
  extra_hosts:
   - "local_dev:$LOCAL_HOST_IP"

ただし、このコマンドはMacでしか確認してしてなくて、他のOSではどのようにやれば良いかは確認していない。

まとめ

個人的には「その4」がよいかなと思うけど、
使う環境によって、できること・できないことあるので、
その時々でベストなものを選択してもらえたらよいかなと思う。