外观
逐层排查镜像拉取失败
拉取失败常见于拼错标签、仓库限流、网络不通或架构不匹配。先保留完整错误和失败镜像名,再改一个变量重试。反复换“加速镜像”会丢失原始证据,也可能换成无关的第三方构建。
配置影响范围
本文诊断命令在 NAS 的 SSH 终端执行。修改 Docker 守护进程代理或重启服务可能影响全部容器,先保存配置和安排停机窗口。不要关闭 TLS 校验,不要把账号令牌粘到论坛,不要执行陌生来源的修复脚本。
第一步:确认名称、标签与架构
打开应用官方安装文档,对照 registry、命名空间、镜像名和 tag。manifest unknown 或 not found 通常先查标签是否存在,不是先改 DNS。no matching manifest 则检查 NAS 的 CPU 架构是否受镜像支持;linux/amd64 与 linux/arm64 不是随意互换的选项,强制指定平台还可能需要模拟执行。
在目标应用目录执行 docker compose config --images 查看最终镜像名称,这只列镜像而不会展开整份含密码的配置。对照发布页选定的版本,确认 .env 中的标签没有多余空格或空值。
第二步:确认在哪台机器失败
网页浏览器能打开 Docker Hub,只证明你的电脑能访问。真正拉取镜像的是 NAS 上的 Docker 守护进程。SSH 进入 NAS,先确认系统时间正确,再进行只读检查:
sh
getent hosts registry-1.docker.io
curl --connect-timeout 10 --head https://registry-1.docker.io/v2/getent 使用当前系统名称解析;curl 的连接超时设为 10 秒,--head 只请求响应头。Docker Hub /v2/ 返回 401 Unauthorized 往往说明 DNS、连接和 TLS 已经走通,随后 Docker 需要完成令牌认证;不要把所有非 200 响应都认定为断网。其他 registry 的认证和域名可能不同。
第三步:按错误处理
| 错误线索 | 优先检查 | 不该直接做的事 |
|---|---|---|
no such host | NAS DNS 与上游可达性 | 修改每个应用的端口 |
i/o timeout、连接超时 | 出口、代理、防火墙、镜像层下载域名 | 关闭证书验证 |
x509 | NAS 时间、证书链、代理拦截 | 添加所有仓库为不安全 registry |
unauthorized、denied | 私有仓库权限、登录账号、镜像拼写 | 反复输入管理员系统密码 |
toomanyrequests | 仓库限流策略和认证 | 无限制并发重试 |
no space left | Docker 数据所在空间与 inode | 未确认前删除卷 |
合规代理与镜像加速
优先使用应用官方提供的其他 registry,例如官方同时发布到 GHCR。确认两边属于同一维护者,记录所用镜像摘要。代理应使用自己有权使用且可信的服务;登录令牌和镜像请求会经过网络路径,未知的“免费加速”服务不适合承载私有仓库。
SSH shell 的 HTTP_PROXY 不等于 Docker 守护进程代理。按照当前 fnOS Docker 组件支持的配置方式设置代理;没有官方支持的入口时,不盲改受系统管理的配置文件。Docker 官方的 daemon proxy 文档解释了作用范围,但具体持久化方式需与 fnOS 配套。
验收与保留记录
在原应用目录重新 docker compose pull,确认全部镜像下载完成,再 docker compose up -d 并查看日志。记录最初错误、修改项和最终镜像来源;遇到以后相同问题可直接判断是认证还是网络。拉取成功后服务打不开,转向端口与挂载检查,不要继续折腾镜像源。