前文

关于发布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.iodocker.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 , 传送门直达 , 如图 : 接着, 设置 Token 的权限, 选择 write:packages (这样,连同 repo 都一起勾选了), 如图 : 最后生成了一个 Token , 一定要记录下来, 下一步要用到

步骤三

把生成的 Token 添加到您的GitHub项目 secrets 下 ; 找到项目下 Setting > secrets , 右上角点击 New repository secret , 如图

如图
Name 值填写 PACKAGES_TOKEN (可自定义, 但下一步用到的 secrets.PACKAGES_TOKEN 同步要改)
Value 值填写 上一步获得的 Token , 最后点击 Add secret ;
GitHub-Actions 就可通过secrets.PACKAGES_TOKEN 获取 Token , 用于发布镜像到 ghcr.io

步骤三

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

name: ci
on:
  workflow_dispatch: #github页面手动触发
  push:
    tags:
      - "v*.*"
env:
  IMAGE_NAME: test #这是您的镜像名
jobs:
  get-tags:
    runs-on: ubuntu-20.04
    env:
      TZ: Asia/Shanghai
    outputs:
      tags: ${{ steps.set-output-id.outputs.tags }}
    steps:
      - uses: actions/checkout@v2
      - name: set-output
        id: set-output-id
        run: |
          VERSION=edge
          if [[ $GITHUB_REF == refs/tags/* ]]; then
            VERSION=${GITHUB_REF#refs/tags/v}
          fi
          echo ::set-output name=tags::${VERSION}          
  push-ghcr:
    runs-on: ubuntu-20.04
    env:
      TZ: Asia/Shanghai
      REGISTRY: ghcr.io
    steps:
      - uses: actions/checkout@v2
      - name: Login
        uses: docker/login-action@v1
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.repository_owner }}
          password: ${{ secrets.PACKAGES_TOKEN }}
      - name: Build && Push
        uses: docker/build-push-action@v2
        with:
          context: .
          file: ./Dockerfile
          push: true
          tags: |
            ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:${{ needs.get-tags.outputs.tags }}
            ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:latest            

借鉴代码

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

步骤四

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

步骤五

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

来到对应的GitHub项目下, 也可以看到关联的Docker镜像, 如图 :

发布到其他仓库

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

name: ci
on:
  workflow_dispatch: #github页面手动触发
  push:
    tags:
      - "v*.*"
env:
  IMAGE_NAME: test #这是您的镜像名
jobs:
  get-tags:
    runs-on: ubuntu-20.04
    env:
      TZ: Asia/Shanghai
    outputs:
      tags: ${{ steps.set-output-id.outputs.tags }}
    steps:
      - uses: actions/checkout@v2
      - name: set-output
        id: set-output-id
        run: |
          VERSION=edge
          if [[ $GITHUB_REF == refs/tags/* ]]; then
            VERSION=${GITHUB_REF#refs/tags/v}
          fi
          echo ::set-output name=tags::${VERSION}          
  push-ghcr:
    needs: get-tags
    runs-on: ubuntu-20.04
    env:
      TZ: Asia/Shanghai
      REGISTRY: ghcr.io
    steps:
      - uses: actions/checkout@v2
      - name: Login
        uses: docker/login-action@v1
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.repository_owner }}
          password: ${{ secrets.PACKAGES_TOKEN }}
      - name: Build && Push
        uses: docker/build-push-action@v2
        with:
          context: .
          file: ./Dockerfile
          push: true
          tags: |
            ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:${{ needs.get-tags.outputs.tags }}
            ${{ env.REGISTRY }}/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}:latest            
  push-docker-hub:
    needs: get-tags
    runs-on: ubuntu-20.04
    env:
      TZ: Asia/Shanghai
    steps:
      - uses: actions/checkout@v2
      - name: Login
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}
      - name: Build && Push
        uses: docker/build-push-action@v2
        with:
          context: .
          file: ./Dockerfile
          push: true
          tags: |
            ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:${{ needs.get-tags.outputs.tags }}
            ${{ secrets.DOCKERHUB_USERNAME }}/${{ env.IMAGE_NAME }}:latest            
  push-docker-pkg-github:
    needs: get-tags
    runs-on: ubuntu-20.04
    env:
      REGISTRY: docker.pkg.github.com
      TZ: Asia/Shanghai
    steps:
      - uses: actions/checkout@v2
      - name: Login
        uses: docker/login-action@v1
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.PACKAGES_TOKEN }}
      - name: Build && Push
        uses: docker/build-push-action@v2
        with:
          context: .
          file: ./Dockerfile
          push: true
          tags: |
            ${{ env.REGISTRY }}/${{ github.repository }}/${{ env.IMAGE_NAME }}:${{ needs.get-tags.outputs.tags }}
            ${{ env.REGISTRY }}/${{ github.repository }}/${{ env.IMAGE_NAME }}:latest            
      - name: Delete Package
        uses: actions/delete-package-versions@v1
        with:
          package-name: ${{ env.IMAGE_NAME }}
          num-old-versions-to-delete: 1 #删除最旧的一个包

GitHub-Actions 真香 !

相关