示例repo:docker-jekyll - sieveLau
多个docker image可以单纯是tag不一样,也可以是连名字都不一样。至于platform不一样的话,docker/build-push-action本身就支持这个功能。
原理是使用github actions的matrix功能把Dockerfile跟其他属性连接起来,从而生成多个image。比如示范repo做的就是build两个tag出来。
./
|-- .github/
│ `-- workflows/
│ `-- docker.yaml
├── Dockerfile.cli
├── Dockerfile.server
└── entry.sh
显然Dockerfile.cli
是给cli
tag用的。我们有两个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里面用逗号分隔写上就好。
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
参考:
- actions里不同architecture要怎么写:Multi-arch docker images the easy way, with Github Actions - Pablo Romeo
- matrix语法:Using a matrix for your jobs - Github
- 将jekyll塞进容器里的指导:jekyll-serve