nginxコンテナでhost.docker.internal
を利用しようとした際に一生名前解決ができなくて困った件を書きます。
TL;DR
nginxは/etc/hosts
を参照しないので/etc/hosts
に記載されても名前解決できない
172.17.0.1 host.docker.internal
そのためhostネットワークに接続して利用するか、172.17.0.1のようなすでに解決されたIPをハードコードするなどが必要
やりたかったこと
nginxのコンテナをリバースプロキシとして利用していました。
example.com
へアクセスがあればcompose.yml
で定義したfrontへ
example.com/api/
へアクセスがあれば、ホストで別途立ち上げているサービスへ
という風に流してあげる必要があったので、host.docker.internal
を使って「dockerを動かしているホストのネットワークの8000に」という意味でproxy_pass http://host.docker.internal:8000;
と記載しました。
server { listen 80; server_name example.com; location / { proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://front; } location /api/ { proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://host.docker.internal:8000; } }
すると何故か名前解決ができなかったので困っていました。
そもそもLinuxでhost.docker.internal
を使うには設定する必要があったりとヒントを得て、試してみましたがこれもだめ。
extra_hosts: - "host.docker.internal:host-gateway"
いろいろ試してもだめだったんですが、githubのissueを見ていると「nginxは/etc/hostsを見てない」というコメントが多数ありました。
ということで調べて見ると本当に見ていないようで、/etc/hostsを見るようにするにはdnsmasq
というものを別途立ち上げる必要があるみたいです。
解決
名前解決ができないだけでhost.docker.internal
が使えないわけではないので、起動後に/etc/hostsを見て割り当てられるIPを確認して以下のようにハードコードしました。
割り当てるIPはDockerの設定で固定にすることもできるのでこのような実装でも問題ないっぽい。
proxy_pass http://host.docker.internal:8000; # x proxy_pass http://172.17.0.1:8000; # o
おしまい