资讯动态

Docker镜像拉取慢?一文搞定Docker安装、Compose与国内镜像源配置

发布时间:2026/9/18 16:29:13 来源:尧图企业网站定制
玩Docker一年多的朋友大概率都经历过这种崩溃执行docker pull mysql:8.0进度条像睡着了一样卡在 0%等了几分钟直接给你甩一句net/http: TLS handshake timeout。更狠的是docker run hello-world都能卡上十分钟。很多人第一反应是“Docker 坏了”其实问题出在镜像仓库的网络链路上这也是国内玩 Docker 绕不开的一道坎。这篇文章就围绕 Docker 引擎、Docker Compose 安装以及国内镜像源配置三件事展开Linux 服务器和 Windows 开发机两种场景都会覆盖。我自己的主力环境是 Ubuntu 22.04 服务器加 Windows 11 笔记本文章里的命令和坑都是这两套环境下实测过的照着操作基本能一路顺到底。1. 为什么镜像拉不动从Docker Hub到国内镜像源1.1 镜像拉取链路与慢的根因要理解镜像源的价值得先搞明白 Docker 拉取镜像的完整路径。Docker 的镜像默认存放在 Docker Hub 这个公开仓库里。当你执行docker pull时Docker 客户端会向 registry 发起请求registry 返回镜像的 manifest 清单里面列着这个镜像由哪些层组成、每一层的大小和校验值。客户端拿到清单后一层一层下载本地拼接成完整的镜像文件。如果本地已经存在部分层Docker 会提示layer already exists只下载缺失的部分。理解了这张图就能明白镜像拉不下来或者极慢通常不是 Docker 客户端的问题而是客户端到 Docker Hub 这段网络链路的吞吐太低、丢包率高甚至连接被重置。Docker Hub 本身是稳定的但国内访问它的路径不稳定这是客观存在的事实。你可以做个简单测试同一台服务器上分别测一下访问 Docker Hub 和访问国内镜像站的速度多数情况下差距会非常明显。1.2 国内镜像源到底是什么、能解决什么问题国内镜像源本质上是一个只读缓存节点。它在国内部署了服务器持续同步 Docker Hub 上的热门镜像。你在/etc/docker/daemon.json里配置了registry-mirrors之后Docker 拉镜像时不会直接去 Docker Hub而是先去你配置的镜像源。镜像源本地有缓存就直接返回没有缓存就替你去 Docker Hub 同步一份再把结果返回给你。这里有几个边界需要注意。第一镜像源只对 Docker Hub 上的官方镜像和热门社区镜像有效。gcr.io、ghcr.io、quay.io这些第三方 registry 不会经过镜像源如果访问慢那是另一个体系的问题不在本文讨论范围。第二镜像源同步有延迟某个冷门 tag 刚发布时镜像源不一定立刻就有拉取时可能提示manifest unknown。这种情况要么等一会儿再试要么临时去掉镜像源直连一次 Docker Hub。另外像 ollama 这类工具有自己独立的模型拉取流程跟 Docker 镜像源不是一回事别混在一起。配置多个镜像源时Docker 会按顺序依次尝试第一个源失败后自动换下一个。但并不是说配得越多越好这一点后面会展开讲。2. Docker引擎安装Linux和Windows两套方案2.1 Linux快速安装Ubuntu/Debian系Linux 下安装 Docker 最简单的方式是用官方安装脚本curl -fsSL https://get.docker.com | sh。但我不太建议新手直接这么干倒不是说脚本有问题而是你不知道它到底改了什么后面排查问题会很被动。我更推荐手动走一遍官方仓库流程虽然多几步但心里有底。以 Ubuntu 22.04 为例完整流程是sudo apt update sudo apt install -y ca-certificates curl gnupg lsb-release sudo install -m 0755 -d /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg sudo chmod ar /etc/apt/keyrings/docker.gpg echo \ deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable | sudo tee /etc/apt/sources.list.d/docker.list /dev/null sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin注意最后一行我特意加了docker-compose-plugin这样 Docker Compose 插件会一起装好省得后面再补。装完以后启动服务并设置开机自启sudo systemctl enable --now docker这里有个细节现在安装的是docker-ce不是 Ubuntu 仓库里的docker.io。docker.io是发行版维护的老版本更新节奏慢而docker-ce是 Docker 官方维护的社区版功能更贴近上游bug 修复也更快。生产环境建议一律用docker-ce。2.2 Windows下安装Docker Desktop与前置条件Windows 上最省心的是 Docker Desktop但它有一个绕不开的前置条件虚拟化必须开启WSL2 功能要能用。装之前先打开任务管理器 → 性能 → CPU看右下角“虚拟化”是不是“已启用”。如果没启用得进 BIOS 开 VT-x 或 AMD-V不同主板菜单位置不一样一般都在 Advanced、CPU Configuration 或 Security 菜单里。这一步没做好Docker Desktop 装完启动时大概率会报Docker Desktop failed to start because virtualisation support wasn’t detected。虚拟化没问题之后启用 WSL2。在管理员 PowerShell 里执行wsl --install装完重启。如果之前已经装过 WSL 但内核是老的先执行wsl --update升级到最新。Docker Desktop 安装包下载好后一路 Next 即可首次启动会让你选择是否使用 WSL2 后端选 WSL2。整个过程最容易翻车的就两个点虚拟化检测没过、WSL 内核版本太老。这两个问题的排查方式我放到最后一章集中说。2.3 装完先做这两步验证不管 Linux 还是 Windows装完第一件事不是急着拉镜像而是先确认引擎正常。Linux 下执行docker version能看到 Client 和 Server 两段信息。如果 Server 段是空的说明守护进程没起来多半是服务没启动或者配置有误。Windows 下看 Docker Desktop 托盘图标是否变成稳定的鲸鱼状态而不是一直转圈或显示红色报错。接着可以尝试拉一个极小的镜像比如hello-world。但这里我建议先别急着拉因为如果镜像源还没配置这一步很可能卡住反而让自己误以为 Docker 装坏了。正确的顺序应该是先装好引擎再配置镜像源最后才拉镜像测试。下面第三节先把 Compose 装好第四节再动手改镜像源最后统一验证。3. Docker Compose安装新版插件与旧版命令3.1 compose新老版本怎么选Docker Compose 经历了从独立二进制到插件的演变。老一点的环境里命令是docker-compose中间带横线它是一个独立的可执行文件通常是下载二进制后放到/usr/local/bin就能用。新版 Docker 从 2.x 开始把 Compose 作为 Docker CLI 的插件命令变成docker compose中间是空格它和docker命令天然一体安装方式也简单很多。从实际使用的角度新环境一律用新版插件形式命令统一、兼容性好。如果你手头维护的旧脚本里写的是docker-compose那也别急着改独立二进制一样能用无非是多维护一份。这里有个容易混淆的点docker-compose和docker compose是两套不同的命令入口虽然底层功能一致但旧命令不归 Docker CLI 管它的配置解析、启动行为都由自己处理。所以在看教程时先确认对方用的是哪种写法否则照抄很容易出现command not found。3.2 Linux安装compose插件的具体步骤在 Ubuntu 22.04 上如果安装docker-ce时带了docker-compose-plugin包docker compose就已经可用了直接验证docker compose version输出形如Docker Compose version v2.24.1就说明 OK。如果当初没装可以用一条命令补齐sudo apt install -y docker-compose-pluginCentOS / RHEL 系也是同理包名就叫docker-compose-plugin。如果用的是 Docker 官方安装脚本搭的环境脚本默认也会把 Compose 插件一并装上所以并不需要单独折腾。那什么情况下需要单独装旧版独立二进制就一种情况你维护的脚本和 CI 流程里大量使用docker-compose暂时没有迁移计划。这时候去 GitHub release 页下载对应平台的二进制即可命令大概是sudo curl -L https://github.com/docker/compose/releases/download/v2.24.1/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose sudo chmod x /usr/local/bin/docker-compose需要注意GitHub 下载在国内也是时好时坏如果这个文件本身拉不动可以换一个版本号或者用镜像站下载但这就跟 Docker 镜像源没关系了是另一回事。3.3 Windows/macOS上的Compose其实不需要装Docker Desktop 默认内置了docker compose插件。装完 Docker Desktop直接在 PowerShell 或 CMD 里跑docker compose version就能看到版本号。如果你发现旧的docker-compose命令不存在不用慌新版统一用docker compose即可。macOS 同理。所以 Windows 和 macOS 用户在这块基本不用费心真正要手动折腾 Compose 的主要是 Linux 服务器场景。4. 配置国内镜像源文件修改、桌面端配置与验证4.1 可用镜像源清单与选型先说结论没有哪个源是永远最快、永远稳定的所以建议在daemon.json里同时配置两到三个源Docker 会按顺序尝试。目前比较常用、我在不同网络环境下实测过的有这些阿里云专属加速地址每个账号都有一个专属地址格式是https://xxxx.mirror.aliyuncs.com需要登录阿里云控制台在容器镜像服务 → 镜像加速器页面查看。这个源我在国内多地测试速度稳定推荐首选。中科大镜像https://docker.mirrors.ustc.edu.cn无需注册公开可用。网易镜像https://hub-mirror.c.163.com老牌公共源稳定性中上。百度源https://mirror.baidubce.com也算比较稳定的公共源。腾讯云https://mirror.ccs.tencentyun.com这个比较特殊它在腾讯云内网访问有优势普通家宽环境下表现一般。这些都是公开可信的镜像加速服务。务必记住这些公共源是运营方免费提供的可能随时调整或下线所以配置完之后一定要验证。不建议在公网找来路不明的“最新可用源大全”然后一股脑全填进去源太多反而会让问题变复杂尽量只保留两三个。4.2 Linux用daemon.json配置多个源Docker 守护进程的集中配置在/etc/docker/daemon.json。没有这个文件就新建一个注意文件名必须是daemon.json目录是/etc/docker。内容示例{ registry-mirrors: [ https://docker.mirrors.ustc.edu.cn, https://hub-mirror.c.163.com, https://mirror.baidubce.com ] }配置完先检查一下 JSON 格式然后重启守护进程sudo systemctl daemon-reload sudo systemctl restart docker这里有个常见的坑很多人改了配置但不重启docker info里显示的还是空的。还有人在文件里把registry-mirrors写成了registry-mirror少个字母 sDocker 不会报错但它根本不认。这种错误最恼火因为看起来一切正常实际上配置完全没生效。额外说明一下daemon.json里还可以同时设置>{ registry-mirrors: [ https://docker.mirrors.ustc.edu.cn, https://mirror.baidubce.com ], data-root: /data/docker, log-driver: json-file, log-opts: { max-size: 10m, max-file: 3 } }注意修改>docker info在输出里找Registry Mirrors这一段如果列出了你配置的地址说明镜像源已经生效。如果显示的是空那就回到 4.2检查配置文件路径、JSON 格式确认守护进程重启过没有。验证完镜像源就可以实测拉取镜像。推荐先拉一个小的比如docker pull hello-world速度正常说明链路通畅。再挑一个常用的中间件镜像比如docker pull mysql:8.0看看整体速度是否可接受。我实测下来配置前后差别非常大同一个镜像配置前可能 5 分钟拉不完配置后十几秒就完成具体数值因网络而异但方向是明确的。5. 实战Compose一键拉起MySQL 8和Redis 75.1 compose文件怎么设计光会装环境没意思得真能跑起来。这里用最常见的两个中间件 MySQL 8 和 Redis 7 做个例子这两个是大多数后端项目的标配用 Compose 管理最合适。我会在项目目录下建一个docker-compose.yml内容大致如下services: mysql: image: mysql:8.0 container_name: mysql8 restart: unless-stopped environment: MYSQL_ROOT_PASSWORD: root123 MYSQL_DATABASE: demo TZ: Asia/Shanghai command: - --character-set-serverutf8mb4 - --collation-serverutf8mb4_unicode_ci ports: - 3306:3306 volumes: - ./mysql-data:/var/lib/mysql healthcheck: test: [CMD, mysqladmin, ping, -h, localhost, -proot123] interval: 10s timeout: 5s retries: 5 redis: image: redis:7-alpine container_name: redis7 restart: unless-stopped ports: - 6379:6379 command: redis-server --requirepass redis123 --appendonly yes volumes: - ./redis-data:/data healthcheck: test: [CMD, redis-cli, -a, redis123, ping] interval: 10s timeout: 5s retries: 5简单解读一下字段含义services定义容器image是镜像名会从配置好的国内镜像源拉取container_name给容器起固定名字restart: unless-stopped表示容器异常退出后自动重启除非你手动停止environment里设置 MySQL 的 root 密码和默认数据库command追加启动参数设置 MySQL 的字符集为 utf8mb4ports做端口映射volumes挂载数据目录保证容器删了数据还在healthcheck做容器健康检查方便编排系统判断服务是否就绪。5.2 启动、连接与数据持久化启动前先确认当前目录下没有同名文件冲突然后执行docker compose up -d-d表示后台运行。第一次启动会因为拉取镜像多一些时间正好验证镜像源配置是否有效。启动完docker compose ps看状态如果两个服务都是running和healthy说明服务正常。连接测试也很简单。MySQL 进容器docker exec -it mysql8 mysql -uroot -p输入密码进入。Redis 验证docker exec -it redis7 redis-cli -a redis123 ping返回PONG就正常。再讲数据持久化上面的 compose 文件把 MySQL 数据目录映射到./mysql-dataRedis 的 AOF 持久化文件映射到./redis-data。这意味着你执行docker compose down之后再docker compose up -d数据都还在。但要注意如果挂载的是数据卷执行docker compose down -v时数据卷会被一并清空数据就没了。所以生产环境操作前要确认清楚我自己的习惯是默认不碰-v参数把它列入危险命令清单。5.3 生产环境还要注意什么上面这个 compose 文件适合本地开发如果直接扔到生产有几点要调整。密码不要硬编码在 yml 里用环境变量文件compose 支持通过env_file引入端口不要直接暴露到公网或者改掉默认端口MySQL 的 root 密码强度要提高Redis 的requirepass至少换成 16 位以上随机字符串服务要加资源限制比如mem_limit、cpus这类参数防止容器之间互相影响日志要限制大小避免长时间运行磁盘爆掉。最后如果业务发展到多台机器编排Compose 只是过渡方案那就要考虑 K8s 或 Swarm 了。这些不是要求一下子全会但心里要有数。6. 高频故障排查与经验记录6.1 常见报错与处理速查表把这段时间实际碰到过、以及周围朋友问过的高频问题整理成一张表方便直接对照现象可能原因处理方法docker: permission denied while trying to connect to the Docker daemon socket当前用户不在 docker 组sudo usermod -aG docker $USER注销重新登录生效Cannot connect to the Docker daemon at unix:///var/run/docker.sockDocker 服务没启动systemctl start docker再执行systemctl enable docker设置开机自启Docker Desktop failed to start because virtualisation support wasnt detectedBIOS 里虚拟化未开启或 WSL2 未启用进 BIOS 开启 VT-x/AMD-V管理员 PowerShell 执行wsl --install后重启docker compose: command not foundCompose 插件未安装安装docker-compose-plugin或单独安装独立二进制docker info里Registry Mirrors为空daemon.json未生效、路径错误或没重启检查/etc/docker/daemon.json重启 Docker确认 JSON 键名正确拉取镜像卡住后报EOF或timeout网络到 Docker Hub 不稳定或镜像源不可用配置两三个国内镜像源重启 Docker 后再 pull换一个源镜像源配了多个但拉取仍然很慢某个源失效或当前网络到该源不佳用docker info确认所有源依次测试把不可用的移除Ubuntu 安装时提示Unable to locate package docker-ce没添加 Docker 官方 apt 仓库或没更新索引按官方文档添加 GPG key 和仓库apt update后重装6.2 两个值得留意的Docker细节第一个细节是 docker 组。把用户加入 docker 组之后docker命令不用再敲 sudo看起来方便但这也意味着用户直接拥有了 root 级别的能力因为 Docker 本身可以挂载主机目录。所以如果这台机器还有其他人用不要随手把所有用户都加入 docker 组。单机开发环境无所谓多人共享的开发机要谨慎一些。第二个细节是日志。默认情况下Docker 的json-file日志驱动不会限制大小一个容器跑久了日志文件可以轻松占满磁盘。我处理过一台生产服务器就是被一个打印大量日志的容器撑爆的排查了半天才定位到是日志的问题。预防很简单不需要单独给每个容器加配置直接在daemon.json里加全局日志限制前面已经给过示例log-driver: json-file, log-opts: { max-size: 10m, max-file: 3 }这样每个容器最多保留 3 个 10MB 的日志文件满了自动轮转。注意这个配置对已有容器不生效需要重建容器才会应用所以新环境一开始就配好老环境分批重建容器。6.3 我踩过坑后沉淀的几条心得第一安装顺序一定要对先装 Docker 引擎再装 Compose然后配镜像源最后拉镜像测试。我见过不少人一上来先配置镜像源再安装 Docker结果daemon.json写好了Docker 一启动反而报错原因是配置文件里有些键和当前版本不兼容。顺序对了能少踩一半坑。第二镜像源不是越多越好。我试过一次配五个源某一个源超时时Docker 要等它超时再试下一个反而拖慢了整体速度。现在我只保留两个国内公共源加一个阿里云专属源够用且稳定。如果发现某个源长期出问题果断停用不要恋战。第三docker compose down -v要当危险命令对待。我有一次因为手滑把整个开发数据库的数据卷清空了虽然本地开发影响不大但也是深深的教训。养成习惯执行任何带-v的参数之前先看一遍当前 compose 文件里挂载了什么东西确认没有不可丢的数据。第四拉镜像遇到拉不动的时候不要反复重试同一个源先验证当前网络环境是否正常再确认镜像源是否可用。可以用一个 curl 命令快速验证镜像源的连通性比如curl -I https://docker.mirrors.ustc.edu.cn/v2/返回正常 HTTP 状态码就说明源本身没问题。如果源没问题那可能是镜像太大或者磁盘空间不足用docker system df看下磁盘占用情况。第五也是我最想强调的入门阶段不要追求一次性把 K8s、Swarm 全部拿下把 Docker、Compose、国内镜像源这三件事做扎实后面很多内容会自然顺畅。Docker 是底层引擎Compose 是日常管理工具镜像源是保证使用体验的基础设施这三者构成了国内环境下最顺手的一套组合方案。先把这套基本功练好后面接触更复杂的编排工具时会轻松很多。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价