Docker 指南 · 1 分钟阅读

在代理后面的Docker:守护进程、构建和组合

Docker在三个不同的地方需要代理——拉取镜像的守护进程、运行命令的构建和你运行的容器。设置错误的代理会导致拉取失败。以下是每个正确的范围。

三层,三种配置

我设置了 http_proxy,但 docker pull 仍然失败的原因如此普遍,是因为 Docker 有 三个独立的网络上下文,而你的 shell 环境变量只触及其中一个。首先,守护进程 (dockerd) 实际上是从注册表中拉取镜像的——它作为系统服务运行,并从自己的配置中读取代理,而不是你的 shell。其次,构建在一个临时容器中运行每个 RUN 步骤,该容器需要自己的代理才能访问网络。第三,如果容器内的应用程序进行外部调用,运行中的容器 也需要代理。

这三者都使用 s4m HTTP 端点,端口为 3128,采用 USER:PASS 认证。配置守护进程和构建的现代方式是 Docker 客户端配置文件 ~/.docker/config.json,它会自动将代理设置注入到构建和 docker run 中;守护进程本身通过 systemd drop-in 或 Docker Desktop 设置进行配置。请参阅 代理页面;这与 npm/yarn 和 pip/conda 指南自然配对,指导你在镜像中运行的内容。

配置所有三个层

通过systemd drop-in运行守护进程,通过docker config.json构建和运行,并提供compose回退。替换USER:PASS。

bash
# --- 1) DAEMON (image pulls): systemd drop-in on Linux ---
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo tee /etc/systemd/system/docker.service.d/http-proxy.conf >/dev/null <<'CONF'
[Service]
Environment="HTTP_PROXY=http://USER:PASS@proxy.s4m.online:3128"
Environment="HTTPS_PROXY=http://USER:PASS@proxy.s4m.online:3128"
Environment="NO_PROXY=localhost,127.0.0.1,.internal"
CONF
sudo systemctl daemon-reload && sudo systemctl restart docker

# --- 2) BUILDS + RUNS: ~/.docker/config.json (injected automatically) ---
cat > ~/.docker/config.json <<'JSON'
{
  "proxies": {
    "default": {
      "httpProxy":  "http://USER:PASS@proxy.s4m.online:3128",
      "httpsProxy": "http://USER:PASS@proxy.s4m.online:3128",
      "noProxy":    "localhost,127.0.0.1,.internal"
    }
  }
}
JSON

# --- 3) docker-compose fallback (per-service build args) ---
# services:
#   app:
#     build:
#       context: .
#       args:
#         HTTP_PROXY:  http://USER:PASS@proxy.s4m.online:3128
#         HTTPS_PROXY: http://USER:PASS@proxy.s4m.online:3128

获取 docker pull 和构建工作

修复层次结构,使故障通常出现的顺序。

先修复守护进程

如果 docker pull 失败,守护进程无法访问注册表。添加带有 HTTP_PROXY/HTTPS_PROXY 的 systemd drop-in,然后执行 daemon-reload 并重启 docker。在 Docker Desktop 中,在设置中设置代理。

为构建配置客户端

将代理块添加到 ~/.docker/config.json,以便 docker build 和 docker run 自动将代理注入每个步骤和容器 — 无需编辑 Dockerfile。

在所有地方添加 NO_PROXY

在每一层的 NO_PROXY 中包含 localhost、127.0.0.1 以及任何内部注册表或服务主机,以便内部流量不必无谓地通过代理路由。

验证每一层

使用docker pull hello-world(守护进程)进行测试,运行apt-get或pip的构建(构建),以及一个curl一个IP回显端点的容器(运行时)。

范围、秘密和诚实

有两个注意事项。首先,将代理凭据保留在镜像层之外。在 Dockerfile 中设置代理环境变量使用ENV会将它们嵌入到镜像中;请使用构建参数或客户端的config.json注入,以便凭据保持在构建主机上。其次,确保NO_PROXY的准确性——内部注册表缺少条目意味着 Docker 尝试通过外部代理访问它并且会失败,造成困惑。

s4m 的 HTTP 代理是一个经过身份验证的数据中心端点,按需计费——非常适合需要从受控出口拉取镜像和包的 CI 构建器和 DevOps 主机。它不是住宅代理,而是一个正向代理,不是注册表镜像或缓存;对于拉取缓存,请在旁边运行注册表镜像。当您的构建集群需要一个允许的出口 IP 时,添加一个专用个人 IP。任何地方的407意味着代理凭据错误——请参阅407 指南。使用工具验证端点。

FAQ

问题,已解答

为什么即使我在shell中设置了http_proxy,docker pull仍然失败?

因为图像拉取是由守护进程完成的,而不是您的 shell。通过 systemd drop-in(或 Docker Desktop 设置)使用 HTTP_PROXY/HTTPS_PROXY 配置 dockerd 的代理,然后执行 daemon-reload 并重启 docker。

我如何在不编辑 Dockerfile 的情况下代理 docker build 和 docker run?

在 ~/.docker/config.json 中添加代理块。Docker 客户端会自动将 httpProxy/httpsProxy 注入每个构建步骤和容器,因此无需更改 Dockerfile。

我如何将代理凭据保留在我的镜像之外?

不要在 Dockerfile 中使用 ENV 设置它们——这会将它们烘焙到层中。使用构建参数或客户端 config.json 注入,以便凭据保留在构建主机上,而不是在交付的镜像中。

s4m 提供注册表镜像或缓存吗?

不。s4m是一个用于出站流量的前向数据中心代理,而不是拉取注册表缓存。要缓存图像,请运行注册表镜像,并在需要时通过代理路由。

在代理后拉取和构建

通过 proxy.s4m.online:3128 的经过身份验证的 HTTP 端点路由 Docker 守护进程、构建和容器。按需计费,专用 IP 用于 CI 白名单。

人们通过搜索找到此页面

此页面回答的真实搜索短语 — 链接的短语打开详细覆盖它们的页面。