🔍搜索⌘K

Docker 镜像拉取失败?一招搞定 Docker 代理配置(Linux 系统通用)

概述

在日常使用 Docker 时,经常会遇到 “镜像拉取慢”“拉取超时”“无法连接镜像仓库” 等问题,核心原因通常有两个:

  1. 国内网络访问 Docker Hub、Google Container Registry 等海外仓库时,网络延迟高或存在访问限制;
  2. 企业 / 校园等内网环境中,需通过指定代理服务器才能访问外部网络。

Docker 本身不会自动使用系统全局代理,需单独配置代理规则 —— 无论是 HTTP/HTTPS 代理,还是 Socks5 代理,都可通过修改 Docker 服务的系统配置实现全局生效,彻底解决镜像拉取难题。本文以 Linux 系统(Ubuntu/CentOS/Debian 通用) 为例,详解两种主流代理场景的配置步骤。

二、核心方案:配置 Docker 服务级代理(推荐,全局生效)

该方案通过修改 Docker 服务的系统配置文件,让 Docker 守护进程(dockerd)启动时加载代理环境变量,适用于 所有 Docker 操作(包括 docker pull 拉取镜像、docker run 启动容器时拉取镜像、docker build 构建时拉取基础镜像),是最彻底的代理配置方式。

第一步:创建代理配置文件

Docker 服务的自定义配置需放在 /etc/systemd/system/docker.service.d/ 目录下(系统级配置,优先级高于默认配置),我们需要在此目录创建代理配置文件 http-proxy.conf。

操作命令:

# 1. 确保配置目录存在(若不存在则创建,避免报错)
sudo mkdir -p /etc/systemd/system/docker.service.d

# 2. 创建并编辑代理配置文件(用 vi 或 nano 均可,此处用 vi)
sudo vi /etc/systemd/system/docker.service.d/http-proxy.conf

第二步:写入代理配置(区分 HTTP/HTTPS 与 Socks5 代理)

根据你使用的代理类型,复制对应的配置内容到 http-proxy.conf 中,关键是替换 http://127.0.0.1:7890 为你的实际代理地址。

场景 1:使用 HTTP/HTTPS 代理(如 Clash、V2Ray 本地代理)

大多数本地代理工具(如 Clash for Linux、V2Ray)会在本地监听 HTTP 代理端口(常见端口:7890、8888),配置如下:

[Service]
# HTTP 代理:替换为你的 HTTP 代理地址(格式:http://代理IP:端口)
Environment="HTTP_PROXY=http://127.0.0.1:7890"
# HTTPS 代理:通常与 HTTP 代理地址一致(部分代理工具需单独配置,按实际填写)
Environment="HTTPS_PROXY=http://127.0.0.1:7890"
# 无需代理的地址:本地地址、局域网地址、Docker 内部网段(避免代理穿透问题)
Environment="NO_PROXY=localhost,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"

场景 2:使用 Socks5 代理(如 Shadowsocks、Clash Socks5 模式)

若代理工具仅提供 Socks5 协议(常见端口:7891),需通过 socks5:// 协议指定地址,配置如下:

[Service]
# Socks5 代理用于 HTTP 请求(格式:socks5://代理IP:端口)
Environment="HTTP_PROXY=socks5://127.0.0.1:7891"
# Socks5 代理用于 HTTPS 请求
Environment="HTTPS_PROXY=socks5://127.0.0.1:7891"
# 无需代理的地址(与 HTTP 代理场景一致)
Environment="NO_PROXY=localhost,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16"

配置说明:

  • NO_PROXY 字段:必须包含 Docker 内部网段(172.16.0.0/12 是 Docker 默认桥接网络网段)和局域网地址,否则会导致容器间通信、本地服务访问异常;
  • 代理地址格式:若代理在远程服务器(如公司代理),需将 127.0.0.1 替换为代理服务器的公网 / 内网 IP(如 http://192.168.1.100:8080);
  • 端口确认:通过 netstat -tulpn | grep 端口号(如 grep 7890)确认代理工具已正常监听目标端口,避免端口冲突或代理未启动。

第三步:重载配置并重启 Docker 服务

修改系统服务配置后,需重载 systemd 配置并重启 Docker 服务,让代理生效。

操作命令:

# 1. 重载 systemd 配置(让系统识别新的 Docker 服务配置)
sudo systemctl daemon-reload

# 2. 重启 Docker 服务(应用代理配置)
sudo systemctl restart docker.service

# 3. 验证 Docker 服务状态(确保重启成功,无报错)
sudo systemctl status docker.service

若输出中显示 active (running),且无 error 日志,则表示 Docker 已加载代理配置并正常启动。

第四步:验证代理是否生效

通过 docker info 查看 Docker 守护进程的环境变量,确认代理配置已被正确加载:

# 查看 Docker 环境变量,过滤代理相关字段
docker info | grep -i proxy

预期输出(以 HTTP 代理为例):

 HTTP Proxy: http://127.0.0.1:7890
 HTTPS Proxy: http://127.0.0.1:7890
 No Proxy: localhost,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16

若能看到上述输出,说明代理已生效,此时执行 docker pull ubuntu 等拉取命令,会通过代理加速。

三、补充方案:配置 Docker 客户端代理(临时生效,适合开发场景)

若仅需临时让 docker pull 等客户端命令使用代理(不影响 Docker 服务全局),可通过 环境变量 临时配置,关闭终端后失效,适合临时测试或开发场景。

操作命令(终端临时生效):

# HTTP/HTTPS 代理(替换为你的代理地址)
export HTTP_PROXY=http://127.0.0.1:7890
export HTTPS_PROXY=http://127.0.0.1:7890
export NO_PROXY=localhost,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16

# 此时执行 docker pull 会使用代理
docker pull nginx:alpine

永久生效(客户端级):

若想让客户端代理永久生效(仅当前用户),可将环境变量写入 ~/.bashrc 或 ~/.zshrc(根据你使用的 Shell 选择):

# 1. 写入 .bashrc(bash 用户)
echo 'export HTTP_PROXY=http://127.0.0.1:7890' >> ~/.bashrc
echo 'export HTTPS_PROXY=http://127.0.0.1:7890' >> ~/.bashrc
echo 'export NO_PROXY=localhost,127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16' >> ~/.bashrc

# 2. 生效配置(无需重启终端)
source ~/.bashrc

四、常见问题与解决方案(避坑指南)

问题现象可能原因解决方案
配置后 docker pull 仍超时 / 失败1. 代理地址错误或端口未监听;
2. 代理工具未启动;
3. 防火墙阻止 Docker 访问代理
1. 用 curl http://代理地址 测试代理是否可用(如 curl http://127.0.0.1:7890);
2. 重启代理工具(如 sudo systemctl restart clash);
3. 临时关闭防火墙测试(sudo ufw disable,CentOS 用 sudo systemctl stop firewalld)。
容器内无法访问外部网络(如 ping baidu.com 失败)1. NO_PROXY 未包含 Docker 内部网段;
2. 代理未允许容器网段访问
1. 确认 NO_PROXY 包含 172.16.0.0/12(Docker 默认网段);
2. 检查代理工具的 “允许局域网访问” 选项是否开启(如 Clash 需开启 “允许来自局域网的连接”)。
docker info 未显示代理配置1. 配置文件路径错误;
2. 未重载 systemd 配置
1. 确认配置文件路径是 /etc/systemd/system/docker.service.d/http-proxy.conf(路径大小写敏感);
2. 重新执行 sudo systemctl daemon-reload && sudo systemctl restart docker。
代理需要用户名密码验证未在代理地址中包含认证信息格式:http://用户名:密码@代理 IP:端口(如 http://user:123456@192.168.1.100:8080),注意密码中若有特殊字符(如 @ #)需 URL 编码(如 @ 编码为 %40)。

五、总结:两种代理方案的选择建议

配置方案生效范围优点缺点适合场景
服务级代理全局(Docker 守护进程)所有 Docker 操作均生效,一劳永逸需修改系统配置,对权限有要求服务器环境、长期使用 Docker 的场景
客户端级代理仅当前用户 / 终端操作简单,不影响系统全局配置仅客户端命令生效(容器内需额外配置)临时测试、开发环境、多用户共享服务器

对于大多数用户,服务级代理 是更优选择 —— 一次配置即可解决所有 Docker 网络问题,无需重复操作;若你是开发人员,仅需临时拉取海外镜像,客户端级代理更灵活。

最后,若你使用的是 Windows 或 MacOS 系统,Docker Desktop 已内置代理配置界面(Windows:设置 → Resources → Proxies;MacOS:偏好设置 → Resources → Proxies),可直接填写代理地址,无需手动修改配置文件,操作更简单。