4 min read

Docker代理设置完全指南:守护进程与容器内部配置

Docker代理设置完全指南:守护进程与容器内部配置

好的,为 Docker 设置代理通常分为两种情况,这两种情况完全不同,请根据你的需求选择:

  1. 为 Docker 守护进程(Daemon)设置代理:用于让 Docker 本身在拉取镜像(docker pull)或与外部仓库通信时使用代理。
  2. 为容器(Container)内部设置代理:用于让容器内部运行的应用(如 apt, curl, npm 等)使用代理。

情况一:为 Docker 守护进程设置代理(用于拉取镜像等)

当你的 Docker 主机处于防火墙之后,需要通过代理服务器才能访问互联网时,就需要配置这个。这个配置是针对 Docker 引擎本身的,而不是针对某个容器。

方法:通过 systemd 修改 Docker 服务启动配置(适用于 Linux)

绝大多数 Linux 发行版都使用 systemd 来管理 Docker 服务。

  1. 在文件中填入代理配置:根据你的代理类型(HTTP 或 HTTPS)进行设置。请将 http://proxy-server-ip:porthttps://proxy-server-ip:port 替换为你实际的代理地址和端口。
  2. 保存文件并退出编辑器

重新加载 systemd 配置并重启 Docker

# 重新加载 systemd 的配置,使其识别新的服务文件
sudo systemctl daemon-reload

# 重启 Docker 服务以使配置生效
sudo systemctl restart docker

# 验证配置是否已加载
sudo systemctl show --property=Environment docker

这个命令应该会输出你刚才设置的 HTTP_PROXYHTTPS_PROXY 环境变量。

如果代理需要用户名和密码认证

[Service]
Environment="HTTP_PROXY=http://username:password@proxy-server-ip:port/"
Environment="HTTPS_PROXY=http://username:password@proxy-server-ip:port/"
Environment="NO_PROXY=localhost,127.0.0.1,.example.com,.docker.internal"

注意:如果密码中有特殊字符(如 @, $, % 等),需要进行 URL 编码(例如 %40 代表 @)。

如果代理不需要认证

[Service]
Environment="HTTP_PROXY=http://proxy-server-ip:port/"
Environment="HTTPS_PROXY=http://proxy-server-ip:port/" # 注意,很多HTTPS代理也用http://
Environment="NO_PROXY=localhost,127.0.0.1,.example.com,.docker.internal" # 绕过代理的地址

创建代理配置文件:使用 vimnano 等编辑器创建一个新文件:

sudo vim /etc/systemd/system/docker.service.d/http-proxy.conf

为 Docker 服务创建配置目录(如果不存在):

sudo mkdir -p /etc/systemd/system/docker.service.d

对于 Docker Desktop (Windows/macOS)

Docker Desktop 的守护进程代理设置更简单,直接在图形界面中完成。

  1. 打开 Docker Desktop。
  2. 进入设置(Settings)。
  3. 找到 Resources -> Proxies
  4. 在界面上填写你的 HTTP 和 HTTPS 代理地址,以及绕过代理的地址(NO_PROXY)。
  5. 点击 Apply & Restart

情况二:为容器内部设置代理(用于容器内应用的网络请求)

这种方法影响的是容器内部的环境,让容器内的程序(如 apt-get, pip, wget 等)通过代理上网。

有几种方法可以实现,推荐使用 方法A

方法A:通过 -e 参数在 docker run 时传递环境变量(最常用)

在启动容器时,直接设置环境变量。

docker run -it \
  -e HTTP_PROXY="http://proxy-server-ip:port" \
  -e HTTPS_PROXY="http://proxy-server-ip:port" \
  -e NO_PROXY="localhost,127.0.0.1" \
  --rm \
  your_image:tag

例子

docker run -it \
  -e HTTP_PROXY="http://192.168.1.100:8080" \
  -e HTTPS_PROXY="http://192.168.1.100:8080" \
  ubuntu:22.04 \
  bash

进入容器后,你可以运行 env | grep -i proxy 查看变量是否生效,或者尝试 apt update 来测试。

方法B:在 Dockerfile 中定义(不灵活,不推荐用于代理)

你可以在构建镜像时硬编码代理设置,但这会使镜像失去灵活性,无法在不同网络环境中使用。

FROM ubuntu:22.04
# 设置代理环境变量
ENV HTTP_PROXY="http://proxy-server-ip:port"
ENV HTTPS_PROXY="http://proxy-server-ip:port"
ENV NO_PROXY="localhost,127.0.0.1"
... # 其他指令

方法C:使用 --env-file 参数(适合复杂环境)

将所有的环境变量(包括代理变量)写在一个文件里,启动容器时引用这个文件。

启动容器时使用该文件:

docker run -it --env-file proxy.env --rm your_image:tag

创建一个名为 proxy.env 的文件:

# proxy.env
HTTP_PROXY=http://192.168.1.100:8080
HTTPS_PROXY=http://192.168.1.100:8080
NO_PROXY=localhost,127.0.0.1

总结与选择

场景 配置对象 推荐方法
Docker 拉取镜像失败 Docker 守护进程(引擎) 修改 systemd 配置或 Docker Desktop 图形界面
容器内程序需要联网(如 apt 容器内部 docker run -e HTTP_PROXY=...--env-file

重要提示

  • NO_PROXY 用于指定不通过代理直接连接的域名或IP地址,对于内部仓库、本地网络服务非常重要。
  • 确保你的代理服务器本身允许来自 Docker 容器或主机的连接。
  • 区分大小写:有些程序识别 HTTP_PROXY,有些识别 http_proxy。为了最大兼容性,可以同时设置大小写两种形式(如 HTTP_PROXYhttp_proxy)。