CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
Docker 容器入门/课时/镜像仓库
RawBlame
课时目录12 节

Docker 容器入门

  1. 01容器是什么
  2. 02安装与环境
  3. 03Docker CLI 基础
  4. 04镜像与分层
  5. 05编写 Dockerfile
  6. 06构建与优化
  7. 07镜像仓库
  8. 08数据卷与挂载
  9. 09网络
  10. 10Docker Compose
  11. 11容器安全基础
  12. 12综合练习与 K8s 方向

镜像仓库

Docker Hub、tag 规范、GHCR/ACR 概览。

25 分钟

镜像仓库

这一课你将能做到

  1. 把自己构建的 Spring Boot 镜像打 tag 并推送到 Docker Hub / 阿里云 ACR,另一台机器一拉即用
  2. 用 registry:2 在本地或内网搭一个私有镜像仓库并完成 push/pull
  3. 建立正确的镜像版本管理习惯:命名空间、tag 规范、为什么禁止只用 latest

为什么要学

镜像构建在你自己的电脑上,但部署发生在服务器上——中间必须有一座桥。这座桥就是镜像仓库(Registry):CI 构建完推上去,任何环境拉下来就能跑,交付从「传 jar 包 + 部署文档」变成「pull 一个 tag」。

团队协作同样离不开它:你写的镜像同事要用、测试环境要拉、生产环境要回滚到上个版本——全部依赖仓库里的版本管理。国内企业普遍用阿里云 ACR 或自建 Harbor(Harbor 底层同样是 registry 的增强版),个人学习用 Docker Hub 足够。

先建立图像

镜像全名的完整结构,很多人第一次见:

[registry地址/][命名空间/]仓库名:标签
────────────────────────────────────
docker.io/library/mysql:8.0      ← docker pull mysql:8.0 的完整名字
registry.cn-hangzhou.aliyuncs.com/myteam/demo-app:1.0
localhost:5000/demo-app:1.0      ← 本地私有仓库
ghcr.io/myteam/demo-app:1.0      ← GitHub Container Registry

推拉的完整流程:

你的电脑                                     服务器
docker build ─→ docker tag ─→ docker push   docker pull ─→ docker run
                      │                        ▲
                      ▼                        │
                 Registry(存镜像、管版本)──────┘

没有 push,镜像只存在于你的机器上;没有 tag 规范,仓库很快变成垃圾场。

跟着做

步骤 1:注册并登录 Docker Hub

  1. 到 https://hub.docker.com 注册账号(记下用户名,下面用 <你的用户名> 表示)。
  2. 本地登录:
docker login
# 输入用户名密码(或用 Access Token 更安全),看到 "Login Succeeded"

步骤 2:给镜像打规范的 tag

tag 必须带上你的命名空间,否则默认属于 library(官方保留):

docker tag demo-app:1.0 <你的用户名>/demo-app:1.0
docker images | findstr demo-app    # 两个名字,同一个 IMAGE ID

步骤 3:推送到 Docker Hub

docker push <你的用户名>/demo-app:1.0

输出会逐层显示 Pushed / Layer already exists(复用过的层不重传,第 4 课分层的直接收益)。

步骤 4:在另一台机器验证拉取

删掉本地镜像再拉回来,模拟服务器行为:

docker rmi <你的用户名>/demo-app:1.0
docker pull <你的用户名>/demo-app:1.0
docker run -d --name demo-remote -p 8082:8080 <你的用户名>/demo-app:1.0
curl http://localhost:8082/actuator/health

到这里,「任何机器一拉即用」已经成立。

步骤 5:搭一个本地私有仓库

docker run -d --name local-registry -p 5000:5000 --restart always registry:2

向它推送(仓库地址是 localhost:5000):

docker tag demo-app:1.0 localhost:5000/demo-app:1.0
docker push localhost:5000/demo-app:1.0

如果报 http: server gave HTTP response to HTTPS client:registry:2 默认要求 HTTPS,本地需在 daemon.json 加 insecure 配置并重启引擎:

{
  "insecure-registries": ["localhost:5000"]
}

验证私有仓库里的镜像可用:

curl http://localhost:5000/v2/_catalog          # 列出仓库
curl http://localhost:5000/v2/demo-app/tags/list # 列出 tag

步骤 6:国内企业方案——阿里云 ACR 概览

  1. 阿里云控制台 → 容器镜像服务 → 个人实例(免费)→ 创建命名空间(如 myteam)。
  2. 创建镜像仓库(如 demo-app),得到地址 registry.cn-hangzhou.aliyuncs.com/myteam/demo-app。
  3. 推送三件套:
docker login --username=你的阿里云账号 registry.cn-hangzhou.aliyuncs.com
docker tag demo-app:1.0 registry.cn-hangzhou.aliyuncs.com/myteam/demo-app:1.0
docker push registry.cn-hangzhou.aliyuncs.com/myteam/demo-app:1.0

内网机器(同 VPC 的 ECS)拉取走内网地址,速度接近本地磁盘。GHCR 用法同理:ghcr.io/<github用户名>/demo-app:1.0,用 GitHub PAT 登录。

讲清楚要点

  1. 镜像全名的寻址结构:registry地址/命名空间/仓库名:tag。省略 registry 默认 docker.io,省略命名空间默认 library。理解这个结构,任何仓库(Hub/ACR/GHCR/Harbor)的用法都通了。
  2. tag 规范建议:主版本.次版本.修订号(1.0.0)对应里程碑,配合 git commit 短哈希(1.0.0-a1b2c3d)保证可追溯;每个镜像多推一个 1.0 这样的滚动 tag 方便引用,但永远不要只用 latest。
  3. latest 的真实含义:它只是「最后一次被 docker push 时带上的名字」,既不保证最新,也不保证稳定。生产回滚场景里,latest 无法回答「线上跑的到底是哪个版本」。
  4. 登录凭据管理:docker login 的凭据存在本地凭据存储里;CI 上用 Access Token(Hub)或 RAM 账号(ACR)而非主账号密码,最小权限原则。
  5. 公库与私库的选择:开源项目用 Docker Hub 公库扩大影响力;商业代码一律私库(ACR/Harbor/GHCR 私有),公库泄漏业务 jar 等于泄漏代码——jar 可被反编译。

你可能会懵的地方

  • docker pull mysql 为什么不需要完整地址? 省略时自动补全为 docker.io/library/mysql:latest。官方镜像(如 mysql、redis、nginx)都在 library 命名空间下,个人镜像必须带自己的用户名。

  • push 报 denied: requested access to the resource is denied? 三种可能:没 docker login;tag 的命名空间和登录账号不一致;对目标仓库无写权限。按顺序排查:先 docker info 看登录状态,再核对 tag 全名。

  • 私有仓库和 Docker Hub 私有仓库有什么区别? 功能上都提供「仅授权可见」,差别在数据位置与网络:Hub 在境外有拉取限流与速度问题;自建 registry/Harbor 数据在自己机房,内网传输快、可控合规。企业里两者都可能有——开源依赖走 Hub 缓存,业务镜像走私库。

  • 为什么推荐 tag 加上 git commit 哈希? 版本号(1.0.0)回答「这是哪一版」,commit 哈希回答「这一版对应哪行代码」。线上排障时拿镜像 tag 直接定位代码提交,是可追溯性的关键一环。

  • 镜像能删吗?怎么删? Hub/ACR 网页端或 API 可删除 tag;自建 registry 删除需要先开启 REGISTRY_STORAGE_DELETE_ENABLED=true,再 DELETE /v2/<name>/manifests/<digest>。习惯上更推荐「只推新不删旧 + 定期清理策略」,因为别的环境可能还在引用旧版本。

错法对照

错法问题正解
docker push demo-app:1.0(无命名空间)被当作官方 library 仓库,无权限push <你的用户名>/demo-app:1.0
生产环境只引用 latest版本漂移,回滚无从谈起固定语义化版本 + commit 哈希 tag
把公司业务镜像推成公开仓库jar 可被任意下载反编译私有仓库 + 访问控制
用主账号密码配 CI 登录凭据泄漏影响面巨大最小权限 Access Token / RAM 账号
自建 registry 忘配 insecure-registriespush 报 HTTPS 错误daemon.json 加配置或正确配 TLS
镜像推完就不管 tag 清理仓库膨胀,存储费用上升保留最近 N 版 + 定期清理策略

卡点急救

  1. pull 限流 toomanyrequests:Docker Hub 匿名限流。docker login 后重试;国内环境换阿里云 ACR 或配加速器(第 2 课)。
  2. push 极慢或中途断开:大镜像走境外网络不稳定。换 ACR(国内快)或压缩镜像体积(第 6 课多阶段构建)。
  3. localhost:5000 push 报 HTTPS 错误:daemon.json 的 insecure-registries 漏配或没重启引擎(systemctl restart docker / Desktop Apply & Restart)。
  4. 忘记登录账号对应哪个 token:cat ~/.docker/config.json(Windows 在 %USERPROFILE%\.docker\config.json)查看已登录的 registry 与凭据存储方式。
  5. 同事说拉不到你的镜像:让他核对完整镜像名(含命名空间)与仓库可见性(public/private),私有仓库需先登录且有权限。

面试常问

  • 说一下你们项目的镜像版本管理策略? 构建时打两个 tag:语义化版本(或构建号)+ git commit 短哈希,推送到私有仓库;部署清单记录 digest;latest 仅本地开发使用。回滚 = 部署上一个版本 tag。

  • Docker Hub、Harbor、ACR 的区别? Docker Hub 是全球公共仓库(有限流);Harbor 是开源企业级私有仓库(含权限、漏洞扫描、镜像签名、复制同步,底层基于 registry);ACR 是阿里云托管服务(国内网络快,与阿里云 CI/CD 生态集成)。

  • CI/CD 中镜像如何流转? 流水线:拉代码 → 构建(多阶段 Dockerfile)→ 打 tag(版本+commit)→ push 私库 → 部署环境 pull 对应 tag → run。构建一次、多处部署同一镜像,是「交付物标准化」的落地。

  • 为什么生产环境建议用 digest 部署? tag 可被重新推送覆盖,digest(sha256)由镜像内容唯一确定。以 digest 记录部署版本,能保证任何时间任何机器拉到的字节完全一致,审计可追溯。

自测三问

  1. 写出镜像全名的完整结构,并给出 docker pull redis:7 实际请求的完整地址。
  2. 把 demo-app:1.0 推送到阿里云 ACR 需要哪三步命令?
  3. 为什么「只用 latest」在生产环境是事故隐患?举一个具体回滚场景说明。

小结一句话

仓库把镜像从「你电脑上的文件」变成「团队与环境的公共交付物」——理解全名寻址结构、守住 tag 规范,镜像才能真正流动起来。

延伸

  • Docker Registry 官方文档
  • 阿里云容器镜像服务 ACR
  • 下一课预告:数据卷与挂载——解决容器化最经典的坑:容器删了,MySQL 数据没了。
加载本节练习…
← 上一课构建与优化下一课 →数据卷与挂载