docker push失败主因是Docker默认强制HTTPS而私有registry仅支持HTTP,需配置insecure-registries(测试环境)或启用HTTPS(生产环境),并确保正确tag、挂载存储路径及验证推送结果。

docker pull registry 能直接拉下来,但不配好 insecure-registries 或 HTTPS,docker push 一定会失败——这是最常卡住的第一步。
为什么 push 总报 “http: server gave HTTP response to HTTPS client”
Docker 默认只信任 HTTPS 协议的 registry,而 registry:2 容器默认走 HTTP(端口 5000),客户端一发起 push 就强制走 HTTPS,服务端却没 TLS,直接拒收。
解决方式只有两个:要么让客户端信任这个 HTTP 地址,要么给 registry 加 HTTPS。开发/测试环境推荐前者,速度快、无证书负担;生产环境必须后者。
- 编辑
/etc/docker/daemon.json,加入:{"insecure-registries":["192.168.1.100:5000"]}(把 IP 换成你 registry 服务器的真实内网地址) -
systemctl restart docker生效,否则配置不加载 - 注意:
insecure-registries只接受 IP:PORT 形式,不能写域名,也不能写localhost(除非客户端和服务端在同一台机器) - 如果用的是 macOS Docker Desktop 或 Windows WSL2,配置位置不同:
~/.docker/daemon.json,且需在 GUI 设置里点击 “Apply & Restart”
启动 registry 容器时必须挂载 /var/lib/registry
不挂载就等于把镜像全存在容器临时文件系统里——容器删了,所有镜像立刻清零。这不是 bug,是设计如此。
正确做法是用 -v 明确绑定宿主机目录:
docker run -d -p 5000:5000 --restart=always --name registry -v /data/registry:/var/lib/registry registry:2-
/data/registry目录需提前mkdir -p并确保 Docker 进程有读写权限(常见坑:SELinux 启用时需加:z标签,如-v /data/registry:/var/lib/registry:z) - 别用
/tmp/registry:那是 v1 版本路径,v2 已废弃,挂错位置会导致 registry 启动后看似正常,但 push 实际不落盘 - v2 镜像存储结构是分层哈希目录,不要手动进
/var/lib/registry删除文件,要用registry garbage-collect命令清理
docker tag 和 docker push 的命名规则不能错
push 前必须重打 tag,格式固定为:IP:PORT/namespace/image:tag。漏掉 IP:PORT 或写错顺序,push 会直接报 unauthorized: authentication required(即使没开认证)。
- 例如 registry 地址是
192.168.1.100:5000,想传busybox,得先:docker tag busybox 192.168.1.100:5000/busybox
- 然后 push:
docker push 192.168.1.100:5000/busybox
-
namespace不是必须项,但建议加上(如myapp/busybox),否则所有镜像都挤在根下,后期难管理 - 如果 push 时提示
denied: requested access to the resource is denied,大概率是 tag 没包含完整地址,或者 daemon.json 没生效
验证仓库内容别只靠浏览器访问 /v2/_catalog
浏览器打开 http://IP:5000/v2/_catalog 看到空 JSON 是正常的——它只列“仓库名”,不列 tag。刚 push 完一个镜像,这里可能还是空的,不代表失败。
真正可靠的验证方式是用 curl 查具体镜像的 tag 列表:
curl -X GET http://192.168.1.100:5000/v2/busybox/tags/list
(返回{"name":"busybox","tags":["latest"]}才算成功)- 如果返回 404,说明 push 没成功或 tag 名不一致(比如 push 的是
192.168.1.100:5000/myapp/busybox,但查的是/busybox) - 别依赖
docker images输出判断是否上传成功——它只显示本地镜像列表,和远程无关


















