Docker 代理设置指南 - 国内环境下的镜像加速与代理配置
由于众所周知的原因,在国内使用 Docker 时,经常会遇到拉取镜像缓慢甚至失败的问题。本文整理了两种主要的解决方案:使用国内镜像加速和配置代理。
方案一:国内镜像加速
最简单的方式是配置国内镜像源。编辑 /etc/docker/daemon.json 文件:
{ "registry-mirrors": ["https://docker.1ms.run"]}但是这个方法总归是权宜之计,速度并不是很好。而一些部署的国内镜像源是需要付费的,怕麻烦的可以购买付费用这些:
- 毫秒镜像:https://1ms.run/
- 轩辕镜像:https://xuanyuan.cloud/
配置完成后重启 Docker 服务:
sudo systemctl daemon-reloadsudo systemctl restart docker方案二:使用代理
快速搭建 Linux 代理环境
如果你还没有在 Linux 上配置代理,推荐使用 clash-for-linux-install 项目快速部署。
NOTE不要在公网部署这个,尤其面板之类的。务必关掉端口,走私网链接。
安装命令:
git clone --branch master --depth 1 https://gh-proxy.org/https://github.com/nelvko/clash-for-linux-install.git && cd clash-for-linux-install && bash install.sh常用命令:
Usage: clashctl COMMAND [OPTIONS]
Commands: on 开启代理 off 关闭代理 status 内核状况 proxy 系统代理 ui Web 面板 secret Web 密钥 sub 订阅管理 upgrade 升级内核 tun Tun 模式 mixin Mixin 配置
Global Options: -h, --help 显示帮助信息理解代理地址的选择
在配置 Docker 代理之前,需要先理解你的代理部署在哪里:
场景一:代理在远程服务器(如通过 Tailscale/WireGuard 访问)
┌─────────────────┐ VPN 网络 ┌─────────────────┐│ 代理服务器 │◄──────────────────►│ 本机 (Docker) ││ 100.98.32.42 │ │ ││ :7890 │ │ │└─────────────────┘ └─────────────────┘这种情况下,无论是宿主机还是容器,都直接使用远程代理地址 100.98.32.42:7890。Docker 容器(即使使用 bridge 网络)的流量会经过宿主机路由,可以正常访问 VPN 网络。
场景二:代理运行在宿主机本地
┌─────────────────────────────────────────┐│ 宿主机 ││ ┌─────────────┐ ┌─────────────────┐ ││ │ 代理服务 │ │ Docker 容器 │ ││ │ 127.0.0.1 │◄───│ (bridge 网络) │ ││ │ :7890 │ │ │ ││ └─────────────┘ └─────────────────┘ │└─────────────────────────────────────────┘这种情况下比较复杂:
- 宿主机上的服务可以直接使用
127.0.0.1:7890 - 但容器内的
127.0.0.1指向容器自己,不是宿主机 - 容器需要使用
172.17.0.1:7890(docker0 网桥地址)来访问宿主机上的代理
Docker Pull/Push 代理配置
Docker 的 pull 和 push 命令由 systemd 管理,需要为 Docker 服务配置代理环境变量。
创建配置目录和文件:
sudo mkdir -p /etc/systemd/system/docker.service.dsudo vim /etc/systemd/system/docker.service.d/http-proxy.conf写入以下内容(将代理地址替换为你自己的):
[Service]Environment="HTTP_PROXY=http://100.98.32.42:7890"Environment="HTTPS_PROXY=http://100.98.32.42:7890"NOTE如果代理运行在宿主机本地,这里可以直接使用
127.0.0.1:7890,因为 Docker daemon 运行在宿主机上。
重新加载配置并重启 Docker:
sudo systemctl daemon-reloadsudo systemctl restart docker验证配置是否生效:
sudo systemctl show --property=Environment docker此时 docker pull 就会通过代理拉取镜像了。
Docker Build 时使用代理
构建镜像时需要通过 --build-arg 参数传递代理设置:
docker build \ --build-arg http_proxy=http://100.98.32.42:7890 \ --build-arg https_proxy=http://100.98.32.42:7890 \ -t image_name .NOTE如果你的代理在远程服务器(通过 VPN 访问),直接使用远程地址即可。容器的网络流量会经过宿主机路由,可以正常访问 VPN 网络中的代理。
如果代理在宿主机本地,需要使用 docker0 网桥地址:
docker build \ --build-arg http_proxy=http://172.17.0.1:7890 \ --build-arg https_proxy=http://172.17.0.1:7890 \ -t image_name .或者使用 --network=host 让构建过程直接使用宿主机网络:
docker build --network=host \ --build-arg http_proxy=http://127.0.0.1:7890 \ --build-arg https_proxy=http://127.0.0.1:7890 \ -t image_name .Docker 全局代理配置
通过配置 ~/.docker/config.json 可以为所有新创建的容器设置代理:
vim ~/.docker/config.json{ "proxies": { "default": { "httpProxy": "http://100.98.32.42:7890", "httpsProxy": "http://100.98.32.42:7890", "noProxy": "localhost,127.0.0.1,.local" } }}IMPORTANT这个配置只对
build和run创建的新容器生效,不影响docker pull。pull 仍需按上文配置 systemd 代理。
CAUTION容器一旦创建,代理环境变量就会被固化。即使之后修改或删除
config.json,已有容器仍会使用创建时的代理设置。如需关闭代理,需要在容器内手动清除环境变量:Terminal window export http_proxy=export https_proxy=最终验证
容器内使用代理
有时需要在运行中的容器内访问外网,以下是几种常用方法。
方法一:直接设置环境变量(推荐)
在容器内执行:
export ALL_PROXY='socks5://100.98.32.42:7890'# 或者export http_proxy='http://100.98.32.42:7890'export https_proxy='http://100.98.32.42:7890'如果代理在宿主机本地,使用 docker0 地址:
export ALL_PROXY='socks5://172.17.0.1:7890'方法二:使用 host 网络模式
创建容器时使用 --network=host 参数:
docker run --network=host your_image此时容器与宿主机共享网络栈。如果代理在宿主机本地,可以直接使用 127.0.0.1:
export ALL_PROXY='socks5://127.0.0.1:7890'NOTE使用
--network=host后,-p端口映射参数将失效,容器的所有端口都会直接暴露在宿主机上。
方法三:使用 Docker 全局代理配置
如上文所述,配置 ~/.docker/config.json 后,新创建的容器会自动继承代理设置。
网络问题排查
验证容器能否访问代理
在容器内测试代理连通性:
# 测试 HTTP 代理curl -x http://100.98.32.42:7890 https://www.google.com
# 测试 SOCKS5 代理curl -x socks5://100.98.32.42:7890 https://www.google.com查看 docker0 网桥地址
ip addr show docker0通常是 172.17.0.1,但可能因配置而异。
确认 VPN 网络可达
如果代理通过 VPN 访问,先在宿主机上确认能正常连接:
curl -x http://100.98.32.42:7890 https://www.google.com代理地址速查表
| 场景 | 代理在远程服务器 | 代理在宿主机本地 |
|---|---|---|
| systemd 配置 | 远程地址(如 100.98.32.42:7890) | 127.0.0.1:7890 |
| docker build (bridge) | 远程地址 | 172.17.0.1:7890 |
| docker build (host) | 远程地址 | 127.0.0.1:7890 |
| 容器内 (bridge) | 远程地址 | 172.17.0.1:7890 |
| 容器内 (host) | 远程地址 | 127.0.0.1:7890 |
| config.json | 远程地址 | 172.17.0.1:7890 |
常见问题
SOCKS5 代理支持
Docker 的 config.json 配置目前只支持 HTTP/HTTPS/FTP 协议,不直接支持 SOCKS5。如果你使用的是 Clash 等支持混合端口的代理,同一端口通常同时支持 HTTP 和 SOCKS5,直接使用 HTTP 方式配置即可。
临时禁用代理
如果配置了全局代理但临时需要禁用:
- 重命名
~/.docker/config.json文件 - 在容器内清除环境变量:
export http_proxy= https_proxy= - 使用
--build-arg http_proxy= --build-arg https_proxy=覆盖
总结
| 需求 | 推荐方案 |
|---|---|
| 加速镜像拉取 | systemd 代理配置 |
| 构建时访问外网 | --build-arg 或全局配置 |
| 容器内临时访问外网 | 直接设置 ALL_PROXY 环境变量 |
| 所有容器默认使用代理 | ~/.docker/config.json 全局配置 |
关键是理解你的代理部署位置:远程代理直接用远程地址,本地代理在容器内需要用 172.17.0.1。
