FROM

前文

关于发布Docker镜像到仓库, 思路有不少, 比如:

  1. 本地生成Docker镜像后, 使用 docker login 登录, 然后再 docker push 发布到仓库(Docker Hub等)
  2. Docker仓库平台(Docker Hub等) 关联 Github项目 , git push 后, 仓库平台会获取 Github项目 下的 Dockerfile 等相关文件, 自动构建Docker镜像

本文要讲的是第3种思路, 利用 Github Actions 自动化构建和发布, 与 Github 更高度的结合

仓库平台区别

Docker Hub 再熟悉不过, 它是Docker的官方平台, 不作多介绍
对于 Github 下却有两个发布Docker镜像的平台, ghcr.io 和 docker.pkg.github.com

区别1

前者发布的镜像在 用户 之下, 地址格式 : https://ghcr.io/[用户名]/[镜像名]
后者发布的镜像在 项目 之下, 地址格式 : https://docker.pkg.github.com/[用户名]/[项目名]/[镜像名]

区别2

前者下的镜像可选择公开, 任何人都可 docker pull
后者却只能用户授权才能 docker pull
本文重点讲如何发布到** **ghcr.io

发布到ghcr.io

步骤一

想要在 GitHub 使用 ghcr.io , 首先要 启用改进的容器支持

步骤二

需要生成 GitHub账号 的 Token ; 用于 GitHub-Actions 有权限操作 GitHub账号 下的项目 ;
登录 GitHub , 右上角点击用户头像, 找到 settings > Developer settings > Personal access tokens , 点击 Generate new token , 传送门直达 , 如图 :image.png接着, 设置 Token 的权限, 选择 write:packages (这样,连同 repo 都一起勾选了), 如图 :image.png最后生成了一个 Token , 一定要记录下来, 下一步要用到

步骤三

把生成的 Token 添加到您的GitHub项目 secrets 下 ; 找到项目下 Setting > secrets , 右上角点击 New repository secret , 如图image.png
如图
Name 值填写 PACKAGES_TOKEN (可自定义, 但下一步用到的 secrets.PACKAGES_TOKEN 同步要改)
Value 值填写 上一步获得的 Token , 最后点击 Add secret ;
GitHub-Actions 就可通过secrets.PACKAGES_TOKEN 获取 Token , 用于发布镜像到 ghcr.io 了image.png

步骤三

如何使用 GitHub-Actions 在此不过多简释, 直接贴出代码 :

  1. name: ci
  2. on:
  3. workflow_dispatch: #github页面手动触发
  4. push:
  5. tags:
  6. - "v*.*"
  7. env:
  8. IMAGE_NAME: test #这是您的镜像名
  9. jobs:
  10. get-tags:
  11. runs-on: ubuntu-20.04
  12. env:
  13. TZ: Asia/Shanghai
  14. outputs:
  15. tags: ${{ steps.set-output-id.outputs.tags }}
  16. steps:
  17. - uses: actions/checkout@v2
  18. - name: set-output
  19. id: set-output-id
  20. run: |
  21. VERSION=edge
  22. if [[ $GITHUB_REF == refs/tags/* ]]; then
  23. VERSION=${GITHUB_REF#refs/tags/v}
  24. fi
  25. echo ::set-output name=tags::${VERSION}
  26. push-ghcr:
  27. runs-on: ubuntu-20.04
  28. env:
  29. TZ: Asia/Shanghai
  30. REGISTRY: ghcr.io
  31. steps:
  32. - uses: actions/checkout@v2
  33. - name: Login
  34. uses: docker/login-action@v1
  35. with:
  36. registry: ${{ env.REGISTRY }}
  37. username: ${{ github.repository_owner }}
  38. password: ${{ secrets.PACKAGES_TOKEN }}
  39. - name: Build && Push
  40. uses: docker/build-push-action@v2
  41. with:
  42. context: .
  43. file: ./Dockerfile
  44. push: true
  45. tags: |
  46. ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:${{ needs.get-tags.outputs.tags }}
  47. ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:latest

借鉴代码

如图, GitHub-Actions 运行成功后, 在用户首页下的 Packages 模块下, 新增了一个 Packagesimage.png但是, 可看到 Private 标签, 也就是说, 这个Docker镜像默认不公开的 ; 如需要公开, 请往下看

步骤四

公开 Packages 下的Docker镜像 ; 进入需要公开的镜像后, 点击右上角 Package Settings , 进入配置页面image.png拉到低, 点击 Change visibility , 就可设置为公开 ;
在任何地方, 都可以下载镜像: docker pull ghcr.io/[用户名]/[镜像名]:[标签]image.png

步骤五

虽然这个镜像是通过您的GitHub项目发布的, 但默认是不会关联到对应GitHub项目的 ;
在上文 仓库平台区别 已经知道, ghcr.io 下的镜像是对应账号, 而不是 项目 的 ;
如果需要将该镜像关联到对应项目, 也很简单 :
如图 , 进入该镜像的页面, 在页面下就可以看到 Connect Repository 按钮, 点击关联对应的项目 ; 项目下的 README.md 也会加载进来image.png
来到对应的GitHub项目下, 也可以看到关联的Docker镜像, 如图 :image.png

发布到其他仓库

给出全部代码, 同时发布到 Docker Hub / ghcr.io / docker.pkg.github.com

  1. name: ci
  2. on:
  3. workflow_dispatch: #github页面手动触发
  4. push:
  5. tags:
  6. - "v*.*"
  7. env:
  8. IMAGE_NAME: test #这是您的镜像名
  9. jobs:
  10. get-tags:
  11. runs-on: ubuntu-20.04
  12. env:
  13. TZ: Asia/Shanghai
  14. outputs:
  15. tags: ${{ steps.set-output-id.outputs.tags }}
  16. steps:
  17. - uses: actions/checkout@v2
  18. - name: set-output
  19. id: set-output-id
  20. run: |
  21. VERSION=edge
  22. if [[ $GITHUB_REF == refs/tags/* ]]; then
  23. VERSION=${GITHUB_REF#refs/tags/v}
  24. fi
  25. echo ::set-output name=tags::${VERSION}
  26. push-ghcr:
  27. needs: get-tags
  28. runs-on: ubuntu-20.04
  29. env:
  30. TZ: Asia/Shanghai
  31. REGISTRY: ghcr.io
  32. steps:
  33. - uses: actions/checkout@v2
  34. - name: Login
  35. uses: docker/login-action@v1
  36. with:
  37. registry: ${{ env.REGISTRY }}
  38. username: ${{ github.repository_owner }}
  39. password: ${{ secrets.PACKAGES_TOKEN }}
  40. - name: Build && Push
  41. uses: docker/build-push-action@v2
  42. with:
  43. context: .
  44. file: ./Dockerfile
  45. push: true
  46. tags: |
  47. ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:${{ needs.get-tags.outputs.tags }}
  48. ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:latest
  49. push-docker-hub:
  50. needs: get-tags
  51. runs-on: ubuntu-20.04
  52. env:
  53. TZ: Asia/Shanghai
  54. steps:
  55. - uses: actions/checkout@v2
  56. - name: Login
  57. uses: docker/login-action@v1
  58. with:
  59. username: ${{ secrets.DOCKERHUB_USERNAME }}
  60. password: ${{ secrets.DOCKERHUB_TOKEN }}
  61. - name: Build && Push
  62. uses: docker/build-push-action@v2
  63. with:
  64. context: .
  65. file: ./Dockerfile
  66. push: true
  67. tags: |
  68. ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:${{ needs.get-tags.outputs.tags }}
  69. ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:latest
  70. push-docker-pkg-github:
  71. needs: get-tags
  72. runs-on: ubuntu-20.04
  73. env:
  74. REGISTRY: docker.pkg.github.com
  75. TZ: Asia/Shanghai
  76. steps:
  77. - uses: actions/checkout@v2
  78. - name: Login
  79. uses: docker/login-action@v1
  80. with:
  81. registry: ${{ env.REGISTRY }}
  82. username: ${{ github.actor }}
  83. password: ${{ secrets.PACKAGES_TOKEN }}
  84. - name: Build && Push
  85. uses: docker/build-push-action@v2
  86. with:
  87. context: .
  88. file: ./Dockerfile
  89. push: true
  90. tags: |
  91. ${{ env.REGISTRY }}/${{ github.repository }}/${{ env.IMAGE_NAME }}:${{ needs.get-tags.outputs.tags }}
  92. ${{ env.REGISTRY }}/${{ github.repository }}/${{ env.IMAGE_NAME }}:latest
  93. - name: Delete Package
  94. uses: actions/delete-package-versions@v1
  95. with:
  96. package-name: ${{ env.IMAGE_NAME }}
  97. num-old-versions-to-delete: 1 #删除最旧的一个包

GitHub-Actions 真香 !