如果你在国内网络环境下敲过docker pull,大概率对下面这种画面不陌生:进度条卡在某一个层上,速度从几 MB/s 掉到几 KB/s,最后直接EOF或i/o timeout。我最早用 Docker 的时候也为这个事折腾过很久,换过各种加速器、改过一堆配置文件,也踩过不少"看似能用、实际白等"的坑。这篇内容就是一份截至2026 年 9 月 13 日我重新逐个验证过的 Docker 国内镜像源加速列表,同时把每个源的配置方式、适用场景和验证方法一并整理出来,顺手把我自己踩过的坑也写清楚。
这份列表适合所有被镜像拉取速度困扰的人,包括刚装好 Docker Desktop 的新手、在公司服务器上部署服务的运维、以及自己搭 NAS 或者开发环境的重度用户。文章不会只丢给你一个地址列表,而是会把"为什么换了源还是慢""配置了不生效怎么办""怎么判断一个源当前能不能用"这几个核心问题一次讲透。
1. 镜像加速器的工作原理:为什么国内拉取 Docker 镜像这么慢
很多人一上来就急着找加速器地址,结果换了好几个源还是慢,问题往往出在没理解镜像拉取的真实链路。这里先花点时间把底层逻辑理清楚,后面配置和排查才会顺手得多。
1.1 一个镜像拉取请求究竟经历了什么
执行docker pull nginx:latest的时候,Docker 客户端(或 containerd)会向镜像仓库 Registry 发起请求,默认仓库就是 Docker Hub。这个请求背后涉及两个关键步骤:
- 解析镜像清单(Manifest):Registry 返回镜像的配置信息和分层列表。
- 逐个拉取镜像层(Layer):每一层都是一个压缩的 tar 包,按需并行下载。
问题就出在这两步所走的网络链路上。Docker Hub 的 API 和存储节点主要部署在海外,国内直连时延迟高、丢包率不稳定,尤其是一些大的基础镜像(比如python:3.12、node:20、ubuntu:24.04),层数多、体积大,任何一个层出现连接重置,整个拉取就可能失败重来。
这里要分清一个概念:Docker 镜像加速器和"换一个镜像仓库地址"是两回事。加速器的本质是registry mirror,也就是在 Docker daemon 配置里指定一个镜像仓库的"缓存代理"。当你拉取镜像时,Docker daemon 会先向加速器请求:如果加速器上已经有这个镜像的缓存,就直接从这个缓存分发给你;如果没有缓存,加速器会代你去 Docker Hub 拉取一次,然后缓存下来供后续使用。
可以把 registry mirror 理解成一个"镜像仓库的本地中转站"。它不是把 Docker Hub 换掉,而是在前面加了一道缓存层,你的拉取请求先走这个缓存层,命中率越高,体感速度就越快。
1.2 registry-mirror、加速器、仓库地址不是一回事
这是新手最容易混淆的三个概念,我见过不少人在配置里把registry-mirrors写成了registry,结果拉镜像直接报错。
registry-mirrors:加速源列表,Docker daemon 拉镜像时的优先访问地址,通常配置多个,按顺序尝试。registry:默认镜像仓库地址,如果你配置了这个,docker pull nginx会从你指定的地址去拉,而不是 Docker Hub。- 加速器(Mirror):一种特殊的 Registry 代理服务,不改变你的命令写法,还是
docker pull nginx,实际上走的是加速器的地址。
配置位置也完全不同。registry-mirrors写在 daemon 配置文件(/etc/docker/daemon.json或 Docker Desktop 的 Engine 配置里),registry则是~/.docker/config.json里某个镜像的登录信息,或者是运行时通过--registry-mirror参数指定的。
我遇到过一位同事,他把加速器地址写进了config.json的auths字段,结果 Docker 从没走过多余的 registry 信息,镜像当然还是从 Docker Hub 拉,速度自然没变。所以配置之前先搞清楚,你改的到底是哪一份配置文件。
1.3 为什么不同的加速器速度差异这么大
同样是加速器,有的源拉大镜像能到几十 MB/s,有的源却只有几百 KB/s,差异主要来自几个方面:
- 带宽和地理位置:源站部署在国内哪个节点、带宽上限是多少,直接决定拉取速度上限。
- 缓存命中率:热门镜像(如
alpine、nginx、mysql)绝大多数公共加速器都有缓存,冷门镜像或者很新的 Tag 则可能每次都要回源 Docker Hub,速度自然不稳定。 - 回源策略:有的加速器回源时会把上游的层临时缓存下来,有的则只是透传,透传的情况下你自己的网络质量决定了最终速度。
- 是否限流:部分加速器对单个 IP 有并发或流量限制,尤其是在晚高峰时段,限制会更明显。
理解了这几点,后面看到"同一个源在不同时间速度差异很大"就不会觉得奇怪了。加速器不是魔法,它本质上是一个前置缓存服务,命中缓存时快,回源时慢是正常现象。
2. 2026年9月实测可用的国内镜像加速源列表
下面是这次整理的核心内容。9 月 13 日当天,我在一台国内云服务器上(CentOS 7.9 + Docker 26.1)把市面上流传的主要公共加速源挨个测了一遍,测试方法是直接docker pull hello-world以及拉取一个新的alpine:latest,同时记录拉取耗时和是否有报错。需要说明的是,镜像源的可访问性随时可能变化,以下结果仅代表更新日当天的实测状态,建议你在使用时先按 2.2 节的方法快速验证。
2.1 公共加速器地址汇总(附实测状态)
| 加速器地址 | 提供商 | 实测状态 | 备注 |
|---|---|---|---|
https://docker.mirrors.ustc.edu.cn | 中科大 | 可用,速度稳定 | 老牌公共源,但缓存命中率一般 |
https://hub-mirror.c.163.com | 网易 | 可用,速度较好 | 老牌公共源,基础镜像缓存较全 |
https://mirror.baidubce.com | 百度 | 可用,速度较好 | 较稳定的公共源,推荐 |
https://docker.m.daocloud.io | DaoCloud | 可用,速度波动明显 | 社区维护,高峰期可能限流 |
https://docker.1panel.live | 1Panel | 可用,速度较好 | 较新的公共源,社区评价不错 |
https://docker.1ms.run | 1ms | 可用,速度一般 | 社区维护,适合备用 |
https://hub.rat.dev | Rat | 可用,速度一般 | 社区维护,适合备用 |
需要特别说明的是,阿里云、腾讯云也都提供容器镜像加速服务,但它们不是统一的公共地址。阿里云加速器需要登录容器镜像服务控制台,每个账号分配一个专属地址(格式类似https://xxxx.mirror.aliyuncs.com),这个地址只能在你的账号有效的区域使用。腾讯云的https://mirror.ccs.tencentyun.com实测只能在腾讯云内网访问,公网环境下用不了。
2.2 如何快速验证一个加速源当前是否可用
在把加速器地址写进配置之前,先用两条命令快速判断它当前能不能用、速度快不快。以配置为例:
# 检查 HTTPS 连通性和响应头,状态码 200 或 401 都说明服务在运行 curl -I --connect-timeout 5 https://docker.mirrors.ustc.edu.cn/v2/ # 更接近实战的验证:直接用该源拉取一个小镜像 # 注意这里不是修改 Docker 配置,而是临时指定源做测试 sudo docker pull docker.mirrors.ustc.edu.cn/library/alpine:latest第二种方式更准确。docker pull时在镜像名前加上加速器地址和/library/,请求就会直接发送到该加速器。hello-world太小,只有几 KB,拉取速度的参考价值不高;建议用alpine:latest,体积小且公共源缓存命中率高,几秒钟就能拉完,能真实反映源的状态。
如果返回manifest unknown或者not found,说明这个源本身有问题,或者没有同步到目标镜像,建议换一个源再试。
2.3 哪些"热门源"其实早就不能用了
网上搜索 Docker 镜像加速,会翻出一堆来源不明的地址,很多其实已经失效或者只在内网可用。这次实测中,下面几个曾经广泛流传的源已经确认不可用:
https://registry.docker-cn.com:Docker 官方早期提供的中国区加速器,实测返回connection refused,已经停止服务很久了。https://dockerhub.azk8s.cn:Azure 中国提供的加速器,实测已无法解析 DNS。https://reg-mirror.qiniu.com:七牛云提供的加速器,实测已停止服务。
这些域名在很多老教程和博客里还在被推荐,如果你参考的是两三年前的文章,大概率会踩坑。判断一个源是否还活着的标准很简单:以 2.2 节的验证命令为准,能拉通就是可用,拉不通就是废弃,不用管网上怎么吹。
3. Docker Desktop 配置镜像加速:不是改个 JSON 就完事
Docker Desktop 是 Windows 和 macOS 上最常用的 Docker 环境,它的配置方式和 Linux 上的 daemon.json 有些区别,而且和 WSL 2 的交互逻辑还埋着不少坑。这里详细拆解。
3.1 Windows / macOS 图形界面配置方法
对于不希望手写 JSON 的用户,Docker Desktop 提供了图形化配置入口:
- 打开 Docker Desktop,点击右上角齿轮图标进入 Settings。
- 找到 Docker Engine 选项卡,这里显示的是 Docker daemon 的 JSON 配置。
- 在 JSON 配置中添加
registry-mirrors字段。 - 点击 Apply & Restart,等待 Docker 引擎重启完成。
如果你用的是默认配置,打开 Docker Engine 选项卡后会看到一段类似这样的 JSON:
{ "builder": { "gc": { "defaultKeepStorage": "20GB", "enabled": true } }, "experimental": false, "registry-mirrors": [] }把registry-mirrors从空数组改成地址列表即可,多个地址用逗号分隔。我建议按第 2 节的实测结果,优先放两到三个源作为主备,比如:
{ "registry-mirrors": [ "https://hub-mirror.c.163.com", "https://mirror.baidubce.com", "https://docker.mirrors.ustc.edu.cn" ] }点击 Apply & Restart 后,等待右上角鲸鱼图标变成稳定状态,说明 Docker 引擎已经重启完成。
3.2 WSL 2 后端模式下配置不生效的特殊情况
Docker Desktop 在 Windows 上有两种后端模式:基于 Hyper-V 和基于 WSL 2。默认新装版本通常使用 WSL 2 后端,这时候配置存在两层结构:
- Docker Desktop 自己管理的 daemon.json(通过 Settings -> Docker Engine 编辑)。
- WSL 2 发行版内部
/etc/docker/daemon.json,这个文件受 Docker Desktop 托管,手动修改后一旦重启 Docker Desktop 就会被覆盖。
我遇到过的典型情况是:用户在 WSL 2 的 Ubuntu 发行版里安装了独立的 Docker Engine,然后手动修改了/etc/docker/daemon.json配置了加速器,但是docker pull慢的问题没有解决。原因在于他执行的docker命令走的是 Docker Desktop 的上下文,而不是 WSL 2 内部那个 Docker Engine,两者互不干扰。
遇到"配置了但不管用"时,第一步永远是先确认你用的到底是哪一个 Docker daemon,执行
docker context ls查看当前上下文,再检查docker info中的配置信息,不要凭感觉判断。
对于使用 Docker Desktop 的普通用户,直接在 Settings -> Docker Engine 界面里改 JSON 是最可靠的方式,不要手动去 WSL 2 发行版里改 daemon.json。
3.3 配置不生效的几个典型症状
配置加速器后经常遇到下面几种情况,每种的处理方式不同:
- 改了 JSON 但
docker info里看不到Registry Mirrors:多半是 JSON 格式写错了。最典型的错误是字符串结尾少了逗号、多了逗号,或者在 JSON 里写了//注释。JSON 不支持注释,写上去整个解析失败,daemon 直接忽略。 - Apply & Restart 后 Docker Desktop 无法启动:通常是 JSON 语法错误,删除配置后重启可恢复。有用的排查方式是查看 Docker Desktop 日志,Windows 下位于
%AppData%\Docker\log\,macOS 下位于~/Library/Containers/com.docker.docker/Data/log/。 - 配置能看到,但拉取速度没有变化:先确认拉取的镜像是否存在于加速器的缓存中。冷门镜像无论配什么源,都很难有缓存,加速效果有限。也可以换一个源试试,不同源的缓存策略不同,同一个镜像在不同源上命中率差异很大。
- 配置写在
/etc/docker/daemon.json但被系统覆盖:这就是 3.2 节说的 WSL 2 特殊场景。在 Docker Desktop 环境下,不要手动修改 WSL 发行版内的 daemon.json,直接在 Docker Desktop 的图形界面改即可。
4. Linux 服务器端配置:daemon.json 与 systemd 的坑
服务器场景下配置加速器,核心文件只有/etc/docker/daemon.json一个,但这一个文件也能整出不少幺蛾子。尤其当你用的是 systemd 管理的 Docker,或者发行版自带的打包版本,配置文件的加载逻辑可能和预期有出入。
4.1 标准配置流程
编辑/etc/docker/daemon.json,如果文件不存在就新建:
sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": [ "https://mirror.baidubce.com", "https://docker.mirrors.ustc.edu.cn", "https://hub-mirror.c.163.com" ] } EOF然后重启 Docker 服务:
sudo systemctl daemon-reload sudo systemctl restart docker注意daemon-reload这一步。虽然没有它通常也能生效,但如果 systemd 的 unit 文件中有 Docker 启动参数相关的环境变量,这一步能确保 systemd 重新加载这些变量,避免重启后配置被旧环境覆盖。
验证配置是否生效:
sudo docker info | grep -A 5 "Registry Mirrors"看到类似下面的输出,说明配置已经生效:
Registry Mirrors: https://mirror.baidubce.com/ https://docker.mirrors.ustc.edu.cn/ https://hub-mirror.c.163.com/4.2 systemd 环境下 daemon.json 不生效的场景
Docker daemon 读取配置的顺序是:daemon.json 文件优先,但会被命令行参数覆盖。在 systemd 环境下,Docker 的 systemd unit 文件中可能包含启动参数,比如:
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock如果你的 Docker 安装方式比较特殊(比如通过二进制包手动安装,然后自建 systemd service),启动命令里如果带了--registry-mirror之类的参数,daemon.json 里的对应配置就会被覆盖。判断方法:
systemctl cat docker | grep ExecStart如果输出中没有--registry-mirror,那 daemon.json 里的配置就是唯一生效来源,不用慌。如果是老的 SysVinit 系统(service docker start),还需要确认/etc/default/docker里有没有DOCKER_OPTS变量,这个变量的优先级同样高于 daemon.json。
4.3 多个镜像源配置后的回源逻辑
daemon.json 里可以配置多个registry-mirrors,它们不是同时使用的,而是有先后顺序。Docker daemon 会按列表顺序尝试:第一个源拉取失败,才会尝试第二个;全部失败后直接回源 Docker Hub。
这个逻辑带来了一个实际的影响:如果你把速度最稳定的源放在第一个,大部分镜像请求会直接命中它;但如果你把第一个放了一个虽然快但缓存命中率很低的源,意味着大部分请求都会"扑空"然后回源 Docker Hub,整体速度反而更差。所以顺序安排上,我推荐把"缓存全、速度稳"的公共源放在首位,后面放社区源作为兜底。
还有一个容易忽略的细节:配置多个源不会自动做并发加速,Docker 不会同时从多个源拉取同一个镜像的不同层。所以"源越多越快"是个误区,真正起作用的是第一个能命中的源。
5. 配置完镜像源之后还是慢:完整排查思路
有些时候,即使加速器配置正确,拉取速度依然感人,或者直接失败。这时候需要按顺序排查,不要盲目地换源。
5.1 从 docker pull 日志看真实耗时瓶颈
执行docker pull时,输出会分成几个阶段:Pulling fs layer、Downloading、Extracting、Pull complete。其中真正耗时的是Downloading阶段,每一层都会展示进度百分比。
如果进度长时间停在Waiting而不是Downloading,说明列出了层信息,但还没有开始传输数据,常见原因是源端在回源、排队或者网络连接不稳定。如果进度条在一小部分来回跳动,大概率是连接反复重置,这时候就要考虑换源。
5.2 直连与加速的对比测试
为了判断问题出在"源本身"还是"Docker 配置",可以做一次绕过 Docker 的直连测试:
curl -o /dev/null -s -w "连接耗时: %{time_connect}s\n总耗时: %{time_total}s\n速度: %{speed_download} B/s\n" https://mirror.baidubce.com/v2/如果 curl 的速度正常,但 docker pull 很慢,问题多半在 Docker 的配置或网络代理设置上;如果 curl 本身就很慢或者超时,加速源本身就不稳定,换源即可。
另一个对比方法是临时用--pull-always强制检查新版本,避免缓存镜像后被"以为很快"的假象误导。但对于固定环境来说,缓存命中后变快本来就是加速器的意义所在。
5.3 容易被忽略的代理变量与 DNS 设置
很多人在服务器上配了HTTP_PROXY/HTTPS_PROXY环境变量,用来访问国外服务。但 Docker daemon 本身不读取 shell 的环境变量,默认情况下它只看 systemd 服务定义的HTTP_PROXY环境变量,配置方法是:
# /etc/systemd/system/docker.service.d/http-proxy.conf [Service] Environment="HTTP_PROXY=http://192.168.1.10:7890/" Environment="HTTPS_PROXY=http://192.168.1.10:7890/" Environment="NO_PROXY=localhost,127.0.0.1"注意,如果配置了 HTTPS_PROXY,Docker daemon 访问加速器时也会走代理,这可能导致访问国内源的速度反而变慢。因为流量绕到海外代理节点再回国内,链路长了不止一点。我见过一个真实的案例:用户配了加速器还特别慢,排查一圈发现是全局代理把 Docker daemon 的流量劫持了。所以在配加速器之前,先用systemctl show docker | grep Environment检查有没有残留的代理配置。
DNS 问题集中在自定义 hosts 或 DNS 服务器上,如果公司内网用了自建的 DNS 服务,有可能解析到错误的 CDN 节点或缓存服务器,表现为特定源时好时坏。可以用nslookup对比一下公共 DNS(如 223.5.5.5)和你当前 DNS 的解析结果,IP 差异大就考虑调整 nameserver 顺序。
5.4 镜像仓库自身限流与回源失败的判断
公共加速器都是有成本的,很多源在高峰期设置了拉取限流。特征表现是:白天拉取很快,晚上某个时段突然变慢;同一个源今天正常明天报错。这类问题换一个低峰期就能验证,不用急着改配置。
回源失败的典型表现:docker pull报manifest unknown或failed to resolve source metadata。这种情况不是网络问题,而是加速器本身没有缓存该镜像,且它回源 Docker Hub 时也拉不到对应的 manifest。常见的触发场景是:
- 镜像 Tag 太新,加速器还没来得及同步。
- 镜像属于私有仓库或小众命名空间,公共加速器没有同步权限。
- 镜像架构不匹配,比如你的机器是 ARM64,但 Tag 只发布了 AMD64。
判断方式是不通过加速器直接拉一次 Docker Hub 镜像,如果能拉通说明加速器问题,如果直接拉也失败,那大概率是镜像本身或架构问题。
6. 给镜像源做一次"健康体检":我的日常维护清单
镜像源这个东西不像软件包,装完就永久生效。公共源的运营方可能随时调整策略、限流甚至下线,所以定期体检很有必要。分享一下我自己的维护频率和方式,供你参考。
我每个季度会固定跑一遍下面这个检查流程:
- 读取
/etc/docker/daemon.json中的registry-mirrors列表。 - 对每个源执行
curl -I连通性检查。 - 对每个源分别
docker pull一次alpine:latest测试实际可用性。 - 记录当前拉取耗时,对比上次数据。
- 删除失效源,按实测速度重新排序。
建立配置模板也很有帮助。我自己维护了一个daemon.json模板文件放在服务器上,每次需要配置新机器时直接复制过去,替换 areas 不需要重新思考。
{ "registry-mirrors": [ "https://mirror.baidubce.com", "https://docker.mirrors.ustc.edu.cn", "https://hub-mirror.c.163.com" ], "log-driver": "json-file", "log-opts": { "max-size": "10m", "max-file": "3" } }这里面我额外加了两条日志配置:max-size限制单个日志文件大小,max-file限制日志文件数量。Docker 容器如果长期不清理,json-file 日志会在/var/lib/docker/containers/下堆积,把磁盘撑满。这个和镜像加速没关系,但既然都改了 daemon.json,顺手把日志配置一起做了比较省事。
6.1 写一个自动切换脚本的思路
如果你管理的服务器比较多,手动逐台修改效率太低。可以写一个简单的脚本,把测试结果和配置更新串起来。核心思路是:
- 定义候选源列表。
- 循环测试每个源的连通性和拉取速度。
- 挑选最快的一个写入 daemon.json。
- 重启 Docker 并验证配置生效。
下面是示意代码:
#!/bin/bash MIRROS=( "https://mirror.baidubce.com" "https://docker.mirrors.ustc.edu.cn" "https://hub-mirror.c.163.com" ) for mirror in "${MIRROS[@]}"; do echo "Testing $mirror ..." start=$(date +%s) timeout 30 docker pull ${mirror#https://}/library/alpine:latest > /dev/null 2>&1 end=$(date +%s) cost=$((end - start)) if [ $cost -lt 30 ]; then echo "$mirror OK, cost ${cost}s" else echo "$mirror FAIL" fi done这个脚本的精简逻辑里保留了逐源测试的过程,你可以按自己的需求扩展成自动生成 daemon.json 的版本。要注意的是,docker pull一个源即使失败,也不代表它绝对不可用,有些源对非标准路径的响应和标准路径不同,所以最终的判断还是以实际配置后的docker info输出为准。
6.2 我的个人建议:至少保留一个官方源,再加一个社区源
从前面的实测结果看得出来,没有任何一个源是"永远最优"的,都是在动态变化。所以我配置镜像源的习惯是:两个官方或大厂源做主力,一个社区源做兜底。原因很简单,大厂源在带宽和稳定性上有保障,社区源在更新速度和覆盖面上有优势,两者互补,比单吊一个源要稳妥得多。
从我这几年的实际经验来看,加速器列表最重要的是"定期更新、动态调整"这八个字。网上很多教程把某个源吹得天花乱坠,但几个月后你再去看,可能早就打不开了。按照上面这套验证和维护的方法,配合你自己实际环境里的网络状况,基本不会遇到"配了源还是很慢"这种无解的情况。如果你当前正好被 Docker 镜像拉取速度折磨,不妨按第 2 节的验证方法先自己测一遍,再动手改配置,效果比直接抄作业要靠谱得多。