单元五 Docker 发布与部署 · 第 20 课

发布到镜像仓库

把镜像推送到镜像仓库,相当于把封好的集装箱存进码头:有了版本记录,换一台机器也能随时取用,新版本出问题还能取回旧的。

本课目标

  • 注册 Docker Hub,创建访问令牌。
  • 在服务器上登录 Docker Hub。
  • 给镜像打上版本标签,推送到仓库。

先懂概念:为什么要推送到仓库

镜像已经在服务器上了,为什么还要推送到仓库?

  • 备份:服务器坏了、重装了,镜像还在仓库里。
  • 版本记录:v1、v2、v3 一字排开,随时可以换回任意一个版本。
  • 随处部署:任何一台装了 Docker 的机器,一条命令就能拉取运行。下一课的正式部署就从仓库的镜像名来启动。

镜像的全名由三部分组成:

你的用户名/weekly-report:v1
└───┬───┘ └─────┬─────┘ └┬┘
  命名空间      仓库名    标签

标签通常用来标版本号。不写标签时,Docker 会默认使用 latest,但它只是一个普通的标签,并不会自动指向最新版本:推送 v2 时,latest 不会跟着变。所以每个版本都打上明确的版本号。

跟着做

1. 注册 Docker Hub

访问 hub.docker.com 注册账号,验证邮箱。记住你的用户名,后面的命令用 你的用户名 指代它。

2. 创建访问令牌

不要在服务器上用你的账号密码登录,改用访问令牌(Personal Access Token):它可以限定权限,泄露了也能单独作废,不影响账号本身。

  1. 登录 Docker Hub,点右上角头像,进入 Account settings。
  2. 找到 Personal access tokens,点 Generate new token。
  3. 描述填 ai-server,权限选 Read & Write,生成。
  4. 复制令牌。它只显示这一次,关掉页面就看不到了。

3. 在服务器上登录

ssh ai-server

看到服务器的提示符后,再运行:

docker login -u 你的用户名

提示输入密码时,粘贴刚才的令牌(屏幕上不显示),回车。看到 Login Succeeded 即可。

登录信息会保存在服务器的 ~/.docker/config.json 里,并且没有加密。这台服务器只有你在用,问题不大;如果以后不再需要推送,可以运行 docker logout 清除。

4. 打标签并推送

docker tag weekly-report:v1 你的用户名/weekly-report:v1
docker push 你的用户名/weekly-report:v1

docker tag 不会复制出一个新镜像,只是给同一个镜像加了一个带用户名的新名字。docker push 把它上传到 Docker Hub。

5. 在网页上确认

回到 Docker Hub,在 Repositories 里能看到 weekly-report,点进去,Tags 里有 v1。

公开还是私有

Docker Hub 新建的仓库默认是公开的,任何人都能下载这个镜像。

我们的镜像里只有代码,没有 Key,上一课已经确认过,所以公开也没有关系。但要记住一条底线:任何时候都不要把 Key、密码打包进镜像。 如果想设为私有,可以在仓库的 Settings 里修改;免费账号的私有仓库数量有限。

你应该看到

  • docker push 最后显示 v1: digest: sha256:...。
  • Docker Hub 网页上有 你的用户名/weekly-report,标签 v1。

常见问题

denied: requested access to the resource is denied? 镜像名里的用户名和登录的用户名不一致,或者没有登录。用 docker login 重新登录,检查 docker tag 时用户名有没有拼错。

unauthorized: incorrect username or password? 密码处要粘贴访问令牌,不是账号密码;或者令牌已经被删除了。

服务器在中国内地,推送或拉取很慢甚至失败? Docker Hub 在内地访问不稳定。内地服务器可以改用阿里云容器镜像服务(ACR)或腾讯云容器镜像服务(TCR)的个人版,用法相同,只是镜像名前面多了仓库地址。

自检

  • 我能说出镜像全名里命名空间、仓库名、标签分别是什么。
  • 我用访问令牌而不是账号密码登录了 Docker Hub。
  • Docker Hub 上能看到 weekly-report:v1。
  • 我知道为什么镜像里不能有 Key。