Github Actions 编译推送 docker

  • Github Actions 编译 docker 推送到 dockerhub

  • 资料来源:

    https://github.com/marketplace/actions/build-and-push-docker-images
    https://docs.github.com/en/actions/guides/publishing-docker-images
    https://www.bboy.app/2020/09/24/%E4%BD%BF%E7%94%A8github%20action%E8%87%AA%E5%8A%A8%E6%8E%A8%E9%80%81%E4%BD%A0%E7%9A%84%E9%95%9C%E5%83%8F%E5%88%B0dockerhub/
    https://stackoverflow.com/questions/58177786/get-the-current-pushed-tag-in-github-actions

  • 更新

    1
    2021.01.21 初始

导语

最近终于有时间重新整理手头写的代码,之前把所有的 dockerfile 都放在一个仓库太惨了..

原有的 dockerhub 和 github 协同需要 dockerhub 持有 github 的密钥,从权责分离角度,这样太不安全了.

如今有了 github action 可以将这个流程换成定制 github action 编译并推送到 dockerhub.并且未来还有更多想象空间,例如 overture master 分支推送了,就自动编译推送到 dockerhub…

workflow

基础 workflow

dockerhub 官方教程 Build and push Docker images.

因为之后还有多平台支持,因此选择 path-context 的基础模板.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
name: ci

on:
push:
branches: master

jobs:
path-context:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v2
-
name: Set up QEMU
uses: docker/setup-qemu-action@v1
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
-
name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
platforms: linux/amd64,linux/arm64,linux/386
push: true
tags: user/app:latest

写入 dockerhub 用户名/密钥

注意,这里的密钥不是 dockerhub 密码.

获取 dockerhub 密钥,注意密钥只显示 1 次,注意复制.

之后写入 github action 的 secrets,详细过程见 Encrypted secrets.

新建&写入 DOCKERHUB_USERNAMEDOCKERHUB_TOKEN.

定制

首先需要改变一下触发条件,不需要每次 master 分支推送就编译.每次推送 tag 且 tag 是 v* 时才出发流程.

1
2
3
4
on:
push:
tags: # 仅带 tag:v* 时构建
- v*

工作流 Checkout 下有时会 checkout 失败,加上 persist-credentials: false,并且指定拉取 master 分支.

1
2
3
4
5
- name: Checkout
uses: actions/checkout@v2
with:
ref: master
persist-credentials: false # 持久凭证设置为false,actions/checkout@v2 需要

虽然计划支持多平台,但是现在还不支持…platforms 下暂时只需要 linux/amd64.

1
2
3
4
5
6
7
8
- name: Build and push
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
platforms: linux/amd64
push: true
tags: jasperhale/overture:latest

由 tag 获取版本号

还有一个需求是,推送到 dockerhub 时加上版本号..

参考 GitHub 操作的上下文和表达式语法,当使用 tag 作为触发时,github.ref 会是 refs/tags/<tag_name>.

因此参考 Get the current pushed tag in Github Actions,从 github.ref 获取版本号.

在 jobs 中增加一个流程,获取 version,写入 vars,之后可以通过 ${{ steps.vars.outputs.tag }} 访问.

1
2
3
- name: Get version # 获取 Tag Version
id: vars
run: echo ::set-output name=tag::${GITHUB_REF#refs/*/}

最终 workflow

因此暂时的最终 workflow 如下.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
name: Publish Docker image

on:
push:
# branches: # 仅 master 分支
# - master
tags: # 仅带 tag:v* 时构建
- v*

env:
# 设置 docker 镜像名
IMAGE_NAME: test
IMAGE_ID: jasperhale/$IMAGE_NAME

jobs:
path-context:
name: Push Docker image to Docker Hub
runs-on: ubuntu-latest # 在最新版的Ubuntu系统下运行
steps:
- name: Checkout
uses: actions/checkout@v2
with:
ref: master
persist-credentials: false # 持久凭证设置为false,actions/checkout@v2 需要

- name: Set up QEMU # 多平台构建需要
uses: docker/setup-qemu-action@v1

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1

- name: Login to DockerHub # 登录 DockerHub
uses: docker/login-action@v1
with: # 获取用户名/密码
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Get version # 获取 Tag Version
id: vars
run: echo ::set-output name=tag::${GITHUB_REF#refs/*/}

- name: Build and push
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
platforms: linux/amd64
push: true
tags: |
jasperhale/overture:latest
jasperhale/overture:${{ steps.vars.outputs.tag }}