# Docker 镜像拉取排障与离线启动

西楚极客 ·「Ubuntu + Docker 自建」第 2 篇

环境：Ubuntu 26.04 amd64，Docker Engine 29.9.3，Compose v5.7.0。以下练习使用单服务 Nginx，端口仅绑定在本机回环地址。

## 1. 分开拉镜像与启动服务

在你自己的 Compose 项目目录运行，替换 `web` 为实际服务名。

```bash
docker compose config --images
docker compose --progress plain pull web
```

如果报错指向某个镜像引用且提示 `not found`，先核对仓库名和标签。比如本期故意将 `nginx:stable-alpine` 写成了 `nginx:stable-alpnie`。修正 Compose 的 `image:` 行后重复以上两条命令，看到 `Pulled` 再启动服务。私有镜像还要核对仓库授权和登录状态。

## 2. 在实际拉取的机器上检查连接

这里用 Docker Hub 的报错域名举例。自建或其他仓库使用对应域名及接口。

```bash
getent ahosts registry-1.docker.io
curl -sS --connect-timeout 5 --max-time 12 -o /dev/null \
  -w 'HTTP %{http_code}\n' https://registry-1.docker.io/v2/
```

- 没有 DNS 结果或提示无法解析时，先检查这台目标机的 DNS。修复后先重复解析，再重试拉取。
- 连接反复超时时，检查这台目标机到报错域名的网络出口。浏览器访问其他站点成功，只能说明那次浏览器请求成功。
- 此 Docker Hub 入口的无凭据探测返回 `HTTP 401`，说明该次请求收到响应。继续实际执行 `docker compose --progress plain pull web`，验证认证与镜像层也能完成。
- Docker Hub 返回 `429` 时，按完整响应区分拉取额度和请求过多。具体处理见 [Docker Hub 官方排障](https://docs.docker.com/docker-hub/troubleshoot/)。

## 3. 来源机导出

先在 Ubuntu 目标机用 `dpkg --print-architecture` 查看架构。以下练习使用 `linux/amd64`，来源机必须能取得目标平台的镜像。真实项目使用 `docker compose config --images` 得到的镜像名与标签。

```bash
docker image pull --platform linux/amd64 nginx:stable-alpine
docker image inspect nginx:stable-alpine --format '{{.Os}}/{{.Architecture}} {{.Id}}'
docker image save -o nginx-stable-alpine.tar nginx:stable-alpine
sha256sum nginx-stable-alpine.tar > SHA256.txt
```

记录平台和镜像 ID。把归档和清单一起带到目标机。校验清单用于检测文件变化，文件和清单都应来自可信渠道。多服务项目准备每个服务实际引用的镜像。

## 4. 目标机导入并验证

先在放有归档和清单的目录运行。校验返回 `OK` 后才会导入。

```bash
sha256sum -c SHA256.txt && docker image load -i nginx-stable-alpine.tar
docker image inspect nginx:stable-alpine --format '{{.Os}}/{{.Architecture}} {{.Id}}'
```

确认标签、平台和 ID，回到 Compose 项目目录。练习使用配套 `compose.yaml`，或者保存以下配置。

```yaml
services:
  web:
    image: nginx:stable-alpine
    ports:
      - "127.0.0.1:18221:80"
```

```bash
docker compose up -d --pull never --no-build
docker compose ps
curl --retry 5 --retry-connrefused --max-time 10 -fsSI http://127.0.0.1:18221
```

容器显示 `Up`，且本示例返回 `HTTP/1.1 200 OK`，才算服务跑通。自己的项目以实际映射端口和业务验收条件为准。只清理自己新建的演示项目时，可在其目录运行 `docker compose down`。

镜像归档包含镜像内容。Compose 文件、应用配置、卷、挂载文件和数据库数据需按项目单独准备。本期验证了禁止拉取和构建时使用本地镜像完成启动，运行期依赖外网的其他项目仍应另行验证。

## 官方参考

- [Compose 单独拉取](https://docs.docker.com/reference/cli/docker/compose/pull/)
- [Registry 认证](https://docs.docker.com/reference/api/registry/auth/)
- [保存镜像](https://docs.docker.com/reference/cli/docker/image/save/)
- [导入镜像](https://docs.docker.com/reference/cli/docker/image/load/)
- [Compose 启动与拉取策略](https://docs.docker.com/reference/cli/docker/compose/up/)
- [Docker Official Image nginx](https://hub.docker.com/_/nginx)
