結論
Linuxのdocker-compose.ymlバージョン3でhost.docker.internalを使ってDockerホスト上にあるProxyを通ってインターネット接続させながらイメージビルドしたいときはbuildのところでもextra_hosts
で"host.docker.internal:host-gateway"
を書く必要あり。
https://github.com/docker/compose/issues/7323
version: "3"
services:
myservice:
build:
extra_hosts:
- "host.docker.internal:host-gateway"
extra_hosts:
- "host.docker.internal:host-gateway"
環境
$ docker --version
Docker version 20.10.5, build 55c4c88
$ docker-compose --version
docker-compose version 1.28.5, build c4eb3a1f
背景
LinuxでDockerを使う際、コンテナ内からDockerホストにアクセスしたい場合に、Docker Desktopで使えるhost.docker.internal
を使うことはできません。1
ではCntlmを使ってhttp://localhost:3128
のようなポートにローカルProxyサーバーを作ってそこを経由しないとインターネット接続できないような場合にはどう設定するか?
http://host.docker.internal:3128
の代わりにDockerホストのIPアドレスを書いてhttp://XXX.XXX.XXX.XXX:3128
と設定するとうまくいきます。
{
"proxies": {
"default": {
"httpProxy": "http://XXX.XXX.XXX.XXX:3128",
"httpsProxy": "http://XXX.XXX.XXX.XXX:3128",
"noProxy": "localhost"
}
}
}
ただしこの設定の仕方は、他のコンピュータからこのコンピュータのDockerデーモンに接続する(他のコンピュータの環境変数DOCKER_HOST
でこのコンピュータを設定する)ときに問題を引き起こします。
コンテナ内に作られるプロキシ環境変数は、接続元のコンピュータの~/.docker/config.json
から作られるからです。
そのため接続元のコンピュータからすると、接続先に合わせて毎回~/.docker/config.json
を書き直さないとコンテナはインターネットに接続できません。
{
"proxies": {
"default": {
"httpProxy": "http://host.docker.internal:3128",
"httpsProxy": "http://host.docker.internal:3128",
"noProxy": "localhost"
}
}
}
もしもすべてのコンピュータでDockerコンテナのプロキシ設定を↑のように統一できていれば、接続先に合わせて毎回~/.docker/config.json
を書き直す必要はなく、もちろんプロジェクトのソースコードの中にもプロキシ設定を書く必要はなくなるわけです。
--add-host=host.docker.internal:host-gateway
https://github.com/docker/for-linux/issues/264
上記issue内で散々書かれているように、現在Linux上のDockerコンテナ内でhost.docker.internal
を使うには docker build
やdocker run
の際に--add-host=host.docker.internal:host-gateway
を付けてやればよく、docker-compose up
でコンテナを作る場合にはdocker-compose.ymlのextra_hosts
のところに書けば良いのですが、docker-compose.ymlバージョン2ではbuild
のところにextra_hosts
を指定しなくてもビルド中にも追加のホスト名を解決できたのにバージョン3では今のところbuild
にも指定しないとビルド中はホスト名を解決できないです。
参考記事
- Configure Docker to use a corporate proxy
- linuxでhost.docker.internalを使う
- Cntlmの代わりにpx-proxyでNTLM認証プロキシを手軽に突破する【Windows】
-
「
host.docker.internal
はあくまでDocker Desktopの開発時に使うためのものでLinuxの本番環境でいきなり使えるようになるのはまずい」という言い分も分からないでもないのですが、Linuxで開発している人の立場は……。 ↩