inductorさんが上のような記事を公開されています。ここで公開されているDockerfileによってbuildされたimageがあると嬉しいので、GitHub Actionsで定期的にbuildしたものをGitHub Container Registry上にホストすることにしました。
https://github.com/users/unasuke/packages/container/package/curl-http3
結論としてはこれだけなのですが、docker imageのtagについてちょっと手間取ったのでそれについて書こうと思います。
このimageをbuidするにあたり、 curl-http3
というimageに対して以下のtagを付けたいと思っていました。
quiche-latest
quiche-2021-05-01
ngtcp2-latest
ngtcp2-2021-05-01
GitHub ActionsでDocker buildを行いたいとなった場合には、以下のDocker公式が提供しているactionを使用するのが定石でしょう。
https://github.com/marketplace/actions/build-and-push-docker-images
そして、 docker/build-push-action@v2
を利用して動的なtagを付けようと、このようなYAMLを書きました。
- run: date +%Y-%m-%d
id: date # 結果を参照できるようにidをつけておく
- run: foobar
- name: Build and push
uses: docker/build-push-action@v2
with:
context: quiche
push: true
tags:
- ghcr.io/unasuke/curl-http3:quiche-${{ steps.date.outputs.result }} # ここで dateの結果を利用したい
- ghcr.io/unasuke/curl-http3:quiche-latest
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new
${{ steps.date.outputs }}
というのは、 idがdateとなっているstepの出力を展開させるための記法です。
https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idoutputs
しかしここで文字列展開はできないらしく、以下のエラーによってActionを実行することができませんでした。
The workflow is not valid. .github/workflows/build.yml (Line: 32, Col: 13): A sequence was not expected .github/workflows/build.yml (Line: 70, Col: 13): A sequence was not expected
(どちらにせよ、上に書いたようなYAMLの内容では dateコマンドの結果を再利用することはできません、 ::set-output
などの記法を適切に使用する必要があります)
どうすればいいでしょうか?
docker/metadata-action
を使うと、ここで行いたいことができるようになります1。
https://github.com/marketplace/actions/docker-metadata-action
もう一度、どのようなタグをつけたいかをおさらいします。
quiche-latest
quiche-2021-05-01
ngtcp2-latest
ngtcp2-2021-05-01
ここで、quiche版のみに注目して考えてみます。まず、quiche-latest
については固定値なので docker/build-push-action@v2
だけでも実現できますが、今問題になっているのは、上でも述べたように quiche-2021-05-01
などのビルドした時点での日付が入っているものです。
これは、docker/metadata-action
では type-schedule
を指定することで実現できます。
https://github.com/marketplace/actions/docker-metadata-action#typeschedule
- uses: docker/metadata-action@v3
id: meta
with:
images: ghcr.io/unasuke/curl-http3
tags: |
type=schedule,pattern={{date 'YYYY-MM-DD'}},prefix=quiche-
type=raw,value=quiche-latest
- name: Build and push
uses: docker/build-push-action@v2
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
具体的には、上のような指定を書くことで quiche-2021-05-01
のようなtagを付けたimageをbuildすることができます。注意すべきは、この type=schedule
で指定したtagが付与されるのはScheduled eventsの場合だけなので、pushしたタイミングで実行されるactionではtagが付きません。
他にもcommit hashを指定することもできます。
最終的に、 quiche-latest
、 quiche-<YYYY-MM-DD>
、 quiche-<commithash>
の3種類のtagを付けるために、以下のようなYAMLを記述しました。
- uses: docker/metadata-action@v3
id: meta
with:
images: ghcr.io/unasuke/curl-http3
tags: |
type=schedule,pattern={{date 'YYYY-MM-DD'}},prefix=quiche-
type=raw,value=quiche-latest
type=sha,prefix=quiche-
- name: Build and push
uses: docker/build-push-action@v2
with:
context: quiche
push: true
tags: ${{ steps.meta.outputs.tags }}
実際に動いているWorkflowの定義は https://github.com/unasuke/curl-http3/blob/master/.github/workflows/build.yml にあります。
HTTP/3が喋れるcurlを定期的にbuildして unasuke/curl-http3 に置いてあります。
また、GitHub Actionsにおいてdocker imageのtagをある程度柔軟に指定したい場合、 docker/metadata-action
が解決策になるかもしれません。
もともとは crazy-max/ghaction-docker-meta@v2
でしたが、この記事を書いている間にdocker org公式でメンテナンスされるようになっていました。すごい! https://github.com/docker/metadata-action/pull/78 ↩