github actions 单repo build多个docker image

示例repo:docker-jekyll - sieveLau

多个docker image可以单纯是tag不一样,也可以是连名字都不一样。至于platform不一样的话,docker/build-push-action本身就支持这个功能。

原理是使用github actions的matrix功能把Dockerfile跟其他属性连接起来,从而生成多个image。比如示范repo做的就是build两个tag出来。

1
2
3
4
5
6
7
./
|-- .github/
│ `-- workflows/
│ `-- docker.yaml
├── Dockerfile.cli
├── Dockerfile.server
└── entry.sh

显然Dockerfile.cli是给clitag用的。我们有两个tag,所以就是两个Dockerfile,用一个1x2的matrix来跑。首先我们需要把对应关系定义好,用matrix的include来进行定义:

1
2
3
4
5
6
7
8
9
10
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
include:
- dockerfile: ./Dockerfile.cli
tag: sievelau/jekyll:cli
- dockerfile: ./Dockerfile.server
tag: sievelau/jekyll:server

有了这个matrix定义,github actions在运行时就会自动创建两个jobs,各带一组变量:

1
2
3
4
5
6
7
8
9
10
11
12
{
"matrix": {
"dockerfile":"./Dockerfile.cli",
"tag":"sievelau/jekyll:cli"
}
}
{
"matrix": {
"dockerfile":"./Dockerfile.server",
"tag":"sievelau/jekyll:server"
}
}

那么自然我们就可以在docker/build-push-action里面用${{ matrix.变量名 }}语法来访问对应的文件和tag了。至于build不同架构的image,比如同时build m1用的arm64和普通的amd64,就直接在platforms里面用逗号分隔写上就好。

note

platform的格式是os/arch,一般来说os直接写linux,然后arch常见的就是amd64、arm64等。不确定的话可以在自己的机上build之后,用docker inspect <image-name>看。

1
2
3
4
5
6
7
8
9
-
name: Build and push
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
file: ${{ matrix.dockerfile }}
push: true
tags: ${{ matrix.tag }}
完整的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
name: Push to DockerHub

on:
workflow_dispatch:
push:
branches:
- "master"
paths:
- "Dockerfile.*"
- "entry.sh"
- ".github/**/*"

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
include:
- dockerfile: ./Dockerfile.cli
tag: sievelau/jekyll:cli
- dockerfile: ./Dockerfile.server
tag: sievelau/jekyll:server
steps:
- name: Checkout repo
uses: actions/checkout@v4
-
name: Set up QEMU
uses: docker/setup-qemu-action@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
-
name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKER_TOEKN }}
-
name: Build and push
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm64
file: ${{ matrix.dockerfile }}
push: true
tags: ${{ matrix.tag }}

参考:

  1. actions里不同architecture要怎么写:Multi-arch docker images the easy way, with Github Actions - Pablo Romeo
  2. matrix语法:Using a matrix for your jobs - Github
  3. 将jekyll塞进容器里的指导:jekyll-serve