如何把 Docker 镜像推送到私有镜像仓库?
推送私有仓库三步:docker login 仓库地址 认证 → docker tag 本地镜像 仓库地址/镜像名:标签 打标 → docker push 推送。本文含 Harbor/云仓库示例与常见报错处理。
三步走:①docker login <仓库地址> 登录认证;②docker tag 本地镜像 <仓库地址>/<项目>/<镜像>:<标签> 添加带仓库前缀的镜像引用;③docker push <仓库地址>/<项目>/<镜像>:<标签> 上传。镜像名里的仓库前缀决定了 push 的目的地。
完整示例
# 1. 登录(Harbor 示例)
docker login registry.example.com
# 输入用户名密码;云厂商仓库通常用临时令牌
# 2. 打标签
docker tag myapp:1.2 registry.example.com/team/myapp:1.2
# 3. 推送
docker push registry.example.com/team/myapp:1.2
推送完到仓库 Web 控制台或 docker pull 测试验证。
为什么必须重新 tag
镜像路径中 / 之前的第一段含 .、: 或等于 localhost 时会被当作仓库地址:myapp:1.2 默认去 Docker Hub,而 registry.example.com/team/myapp:1.2 去你的私有仓库。tag 只是加别名,不复制数据,放心打。
常见报错处理
| 报错 | 原因 | 处理 |
|---|---|---|
unauthorized: authentication required |
没登录或令牌过期 | 重新 docker login |
denied: requested access ... denied |
无项目推送权限 | 检查账号在项目中的角色 |
http: server gave HTTP response to HTTPS client |
仓库是 HTTP 协议 | 核对地址与端口,为仓库配置 TLS;私有 CA 需加入 Docker 的信任配置 |
name unknown: repository not found |
Harbor 项目不存在 | 先在 Harbor 建项目,或开启自动创建 |
给仓库配 HTTPS 或内网例外
使用私有 CA 的仓库,应将可信 CA 证书配置到 Docker 的证书目录,例如 Linux Docker Engine 的 /etc/docker/certs.d/registry.example.com:5000/ca.crt。目录名必须与实际仓库地址和端口匹配。
insecure-registries 会降低传输或证书校验保障,可信内网也不等于免风险;仅在明确评估的测试例外中使用,常规部署应修好 TLS。
CI 中的推送
流水线里用密钥变量做非交互登录:
printf '%s' "$REGISTRY_TOKEN" | docker login registry.example.com -u ci-bot --password-stdin
docker tag myapp:1.2 "registry.example.com/team/myapp:${CI_COMMIT_SHORT_SHA}"
docker push "registry.example.com/team/myapp:${CI_COMMIT_SHORT_SHA}"
用提交哈希做标签便于追踪,但标签仍可被覆盖;需结合仓库不可变标签策略或 digest 固定版本。CI 应使用受控凭据存储;Docker 配置中的 base64 编码并不是加密。
常见问题(FAQ)
Q:推送速度慢怎么优化?
A:镜像分层推送,共用层只传一次;减小镜像体积(多阶段构建、清缓存)是根本;内网仓库优先。
Q:能推到多个仓库吗?
A:打多个 tag 分别 push 即可,分层数据本地共享。
Q:Harbor 里推送后立刻能 pull 吗?
A:能;若开了镜像扫描策略,可能被标记为"阻止拉取"直至扫描通过。