Docker 代理配置方法合集

由于众所周知的原因,使用 Docker 时可能会遇到诸多网络问题。然而,网络上关于此的文章充斥着杂乱无章的错误内容,而官方文档的描述也没有特别清楚。本文依据文档和亲身实践,整理 Docker 中各种代理配置方法,留供参考。

Docker daemon 代理

当执行 docker pull 拉取镜像,一般是从 DockerHub 等仓库拉取,此时容易遇到网络问题。

这一拉取过程实际上是 Docker daemon 在执行,而它是由 systemd 启动管理的,并不直接使用我们 shell 中配置的代理环境变量。为了让其走代理,需要编写其 systemd 配置。

文件位置:/etc/systemd/system/docker.service.d/http-proxy.conf

内容示例:

[Service]
Environment="HTTP_PROXY=http://127.0.0.1:1080"
Environment="HTTPS_PROXY=http://127.0.0.1:1080"

保存配置后,需要重启 Docker daemon。注意:这会重启所有容器。

sudo systemctl daemon-reload
sudo systemctl restart docker

相关文档:Configure the daemon to use a proxy。

容器内代理

容器内的应用或许需要访问网络,我们也希望其流量通过代理。这需要在容器内配置环境变量。

可以在 Dockerfile 或者 docker run 的时候设定环境变量,但这要求对每个容器都写重复的配置。有一种更方便的方式:进行如下配置后,启动的容器都会自动设置 http_proxy 等环境变量。

文件位置:~/.docker/config.json

内容示例:

{
 "proxies": {
   "default": {
     "httpProxy": "http://example:1080",
     "httpsProxy": "http://example:1080",
     "noProxy": "*.test.example.com,.example.org,127.0.0.0/8,192.168.0.0/16"
   }
 }
}

指定 httpProxy 属性值,相当于在容器内同时设定 http_proxyHTTP_PROXY 两个环境变量。

保存配置后,无需重启任何服务。在保存配置之后启动的 docker 容器,都会自动配置对应环境变量(之前的容器不会改变)。然而,应用是否读取该环境变量并使用代理设置,取决于应用的实现。这并不是一个标准。

⚠️ 注意:此处环境变量会在容器内被读取,所以地址 127.0.0.1 指的是容器自身,而非宿主机。

⚠️ 注意:如果容器是以 root 模式启动的(使用 sudo),上面所述的 ~/.docker/config.json 其实指的是 /root/.docker/config.json

⚠️ 注意:curl 等工具并不支持 socks 代理,只支持 http。所以建议统一配置 htp 代理。

相关文档:Use a proxy server with the Docker CLI。

Build 时代理

在运行 docker build 时,许多操作容易遇到网络问题。这个 build 过程其实也在一个 Docker 容器中进行,所以读取不到我们 shell 环境的代理环境变量,也访问不到我们的主机网络。

解决方案是,首先指定 build 时使用的网络环境为 host:

docker build --network=host

或者在 docker-compose.yml 中:

build:
  context: .
  network: host
  dockerfile: Dockerfile

接下来,在 Dockerfile 中,设置环境变量:

ENV http_proxy "http://127.0.0.1:1080"
ENV HTTP_PROXY "http://127.0.0.1:1080"
ENV https_proxy "http://127.0.0.1:1080"
ENV HTTPS_PROXY "http://127.0.0.1:1080"

我的终极代理解决方案

我们希望容器内外的网络都使用同样的代理。为了方便容器内的访问,更好的选择是将代理程序作为一个容器运行。

我的解决方案是:单独启动一个名为 proxy 的容器,专门负责进行网络代理;映射 1080 端口,为宿主机提供代理。

容器外:只要配置代理地址 http://127.0.0.1:1080。 容器内:只要加入 proxy 同一网络,并配置代理地址 http://proxy:1080

⚠️ 注意:不要将此端口暴露在公网中,否则被 ISP 扫描到可能要写保证书。

Happy Self-hosting!

文章来源:

Author:me@skywt.cn
link:https://skywt.cn/blog/docker-proxy-configuration/