前置き
この記事は GitHub ActionsからGitHub Container registryへイメージをプッシュする - Qiita の続編です。
前の記事を前提にしているのでまずはそちらをご覧ください。
GitHub Container registryで作ったイメージを使いたい
前回の記事ではGitHub Actions上で作ったイメージをGitHub Container registryにプッシュするまでを行いました。
今度はGitHub Actionsでそのイメージを使ってみましょう。
前回同様作ったソースコートはhttps://github.com/Umekawa/github-actions-sampleにあります。
docker-compose.ymlをロードしてみる
前回作ったDockerfileをそのまま使っても良いですが、今回はdocker-compose.ymlを作ってみましょう。
envとvolumesは特に指定がない場合は省略できますが、今回はサンプルとしてあえて記述しています。
version: "3.8"
services:
sample:
image: $REGISTRY/$DOCKER_REPOSITORY:$DOCKER_TAG
build:
context: .
dockerfile: ./Dockerfile
environment:
SAMPLE_ENV: SAMPLE
volumes:
- ./sample_folder:/app/sample_folder
networks:
default:
dockerfileの指定に関しては前回作ったdockerfileを指定しています。
イメージを使ってみる
それでは実際に前回作ったイメージを使ってGitHub Actionsでコンテナを動かしてみましょう。
今回は動いていることが確かめられればなんでも良いので、適当にcheck-envブランチにプッシュされた時にコンテナでenvコマンドを叩いてみます。
全容は以下になります(長いので閉じています)。
details
name: Check Environment
on:
push:
branches:
- check-env
workflow_dispatch:
permissions:
contents: read
packages: read
env:
COMPOSE_DOCKER_CLI_BUILD: 1
DOCKER_BUILDKIT: 1
DOCKER_CACHE_TAG: master
DOCKER_REPOSITORY: umekawa/github-actions-sample
DOCKER_TAG: check_env
REGISTRY: ghcr.io
jobs:
use_cache_sample:
runs-on: ubuntu-latest
timeout-minutes: 120
steps:
- uses: actions/checkout@v3
- name: Log in to the Container registry (GitHub Container registry)
uses: docker/login-action@v2
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- uses: docker/setup-qemu-action@v2
- uses: docker/setup-buildx-action@v2
- uses: docker/build-push-action@v3
id: docker_build
with:
context: .
file: ./Dockerfile
load: true
tags: ${{ env.REGISTRY }}/${{ env.DOCKER_REPOSITORY }}:${{ env.DOCKER_TAG }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: |
type=gha
${{ env.REGISTRY }}/${{ env.DOCKER_REPOSITORY }}:${{ env.DOCKER_CACHE_TAG }}
cache-to: type=gha,mode=max
- name: Check Env
run: >
docker compose -f docker-compose.yml run
sample bash -c "env"
env:
SAMPLE_TEXT: sample_text
まず、前回と違うのがpermissionsのpackages部分です。
permissions:
contents: read
packages: read
前回はpushをするためにwrite権限になっていましたが、今回はpushはせずに使いたいだけなのでreadになっています。
writeでも動きますが、権限に関しては最小限の方が良いのでreadにしておきましょう。
そこからログインしてbuildする手前までは変わりませんが、build-push-actionに関して若干変わっています。
- uses: docker/build-push-action@v3
id: docker_build
with:
context: .
file: ./Dockerfile
load: true
tags: ${{ env.REGISTRY }}/${{ env.DOCKER_REPOSITORY }}:${{ env.DOCKER_TAG }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: |
type=gha
${{ env.REGISTRY }}/${{ env.DOCKER_REPOSITORY }}:${{ env.DOCKER_CACHE_TAG }}
cache-to: type=gha,mode=max
注目するのはまずloadオプションです。
前回はイメージをプッシュすればよかったですが、今回はそのイメージを使って作ったコンテナを利用するためloadオプションが必要になります。
このloadオプションはpushと併用できない点に注意してください(loadオプションとpushオプションが両方trueの時エラーになります)。
次に注目するのは、tagsオプションとcache-fromオプションです。
tagsが環境変数を読み替えるとghrc.io/umekawa/github-actions-sample:check-env
となっているので、前回作った、ghrc.io/umekawa/github-actions-sample:master
と異なっています。
そのため、cache-fromには明示的にどのイメージを使うのか記述する必要があります。
また、tagsはdocker-compose.ymlのimageと合致させるようにしましょう。
イメージを動かしてみる
それではロードしたイメージを使って、実際に動かしてみましょう。
- name: Check Env
run: >
docker compose -f docker-compose.yml run
sample bash -c "env"
コマンド自体は特に変哲もなく問題ないと思います。: >
の形で長くなりそうな時簡単に複数行かけるので便利ですね。
実際にキャッシュ効いてるかみてみる
それではこちらのコードをGitHubに上げてみて、キャッシュを使っているかみてみましょう。
こちらのリンクで実際に動かしてみています。(数日経ったら消えるかも)
https://github.com/Umekawa/github-actions-sample/actions/runs/3194753301/jobs/5214652322
長いので、各フェーズでわけて折りたたんでいます。
Run docker/build-push-action@v3
詳細を見る
Run docker/build-push-action@v3
Docker info
Buildx version
/usr/bin/docker buildx build --cache-from type=gha --cache-from ghcr.io/umekawa/github-actions-sample:master --cache-to type=gha,mode=max --file ./Dockerfile --iidfile /tmp/docker-build-push-lpBITm/iidfile --label org.opencontainers.image.title=github-actions-sample --label org.opencontainers.image.description= --label org.opencontainers.image.url=https://github.com/Umekawa/github-actions-sample --label org.opencontainers.image.source=https://github.com/Umekawa/github-actions-sample --label org.opencontainers.image.version=check-env --label org.opencontainers.image.created=2022-10-06T05:30:08.333Z --label org.opencontainers.image.revision=921dbfbe14b1bc67dd695035c0c550d981786d26 --label org.opencontainers.image.licenses= --tag ghcr.io/umekawa/github-actions-sample:check_env --load --metadata-file /tmp/docker-build-push-lpBITm/metadata-file .
#1 [internal] load .dockerignore
#1 transferring context: 2B done
#1 DONE 0.0s
#2 [internal] load build definition from Dockerfile
#2 transferring dockerfile: 201B done
#2 DONE 0.0s
#3 [internal] load metadata for docker.io/library/ruby:3.1.2-buster
#3 ...
#4 [auth] library/ruby:pull token for registry-1.docker.io
#4 DONE 0.0s
#3 [internal] load metadata for docker.io/library/ruby:3.1.2-buster
#3 DONE 0.9s
#5 importing cache manifest from ghcr.io/umekawa/github-actions-sample:master
#5 ...
#6 [internal] load build context
#6 DONE 0.0s
#7 [1/5] FROM docker.io/library/ruby:3.1.2-buster@sha256:d7f09eedf86908861a1812ea89016c264e5758d80fa716e6fe50045e6f007b52
#7 resolve docker.io/library/ruby:3.1.2-buster@sha256:d7f09eedf86908861a1812ea89016c264e5758d80fa716e6fe50045e6f007b52 done
#7 DONE 0.0s
#8 [auth] umekawa/github-actions-sample:pull token for ghcr.io
#8 DONE 0.0s
#9 importing cache manifest from gha:13843386142859174583
#9 DONE 0.1s
#5 importing cache manifest from ghcr.io/umekawa/github-actions-sample:master
#5 DONE 0.5s
#7 [1/5] FROM docker.io/library/ruby:3.1.2-buster@sha256:d7f09eedf86908861a1812ea89016c264e5758d80fa716e6fe50045e6f007b52
#7 DONE 0.0s
#6 [internal] load build context
#6 transferring context: 105B done
#6 DONE 0.0s
#10 [3/5] RUN gem install bundler -v 2.3.8 --no-document
#10 CACHED
#11 [4/5] COPY Gemfile /app/
#11 CACHED
#12 [2/5] WORKDIR /app
#12 CACHED
#13 [5/5] RUN bundle install
#13 sha256:891cd9999eacd9540296509832b337c2a4f494e5be634cc6582691614350baf4 175B / 175B 0.0s done
(中略)
#13 sha256:2a0ae5ed3318e8db87d129f9c2652dddc78c89f223625a345ec1b7b84149a882 192.51MB / 192.51MB 6.1s done
#13 DONE 6.9s
#14 exporting to oci image format
#14 exporting layers done
#14 exporting manifest sha256:0c138c0ef7902e650c54557a191a665e087f8730b19b2b5449e878951d32d868 0.0s done
#14 exporting config sha256:324bedbe234325cbedccf5800bcefbb3ee87bf7d96cc5e6e5a8c546ffe85b799 done
#14 sending tarball
#14 ...
#15 importing to docker
#15 DONE 18.1s
#14 exporting to oci image format
#14 sending tarball 24.3s done
#14 DONE 31.1s
#16 exporting cache
#16 preparing build cache for export
#16 preparing build cache for export 0.2s done
#16 DONE 0.5s
ImageID
Digest
Metadata
Check Env
詳細を見る
Run docker compose -f docker-compose.yml run sample bash -c "env"
docker compose -f docker-compose.yml run sample bash -c "env"
shell: /usr/bin/bash -e {0}
env:
COMPOSE_DOCKER_CLI_BUILD: 1
DOCKER_BUILDKIT: 1
DOCKER_CACHE_TAG: master
DOCKER_REPOSITORY: umekawa/github-actions-sample
DOCKER_TAG: check_env
REGISTRY: ghcr.io
SAMPLE_TEXT: sample_text
Network github-actions-sample_default Creating
Network github-actions-sample_default Created
HOSTNAME=2194e2bc6ed4
RUBY_DOWNLOAD_SHA256=ca10d017f8a1b6d247556622c841fc56b90c03b1803f87198da1e4fd3ec3bf2a
SAMPLE_ENV=SAMPLE
RUBY_VERSION=3.1.2
***
BUNDLE_APP_CONFIG=/usr/local/bundle
RUBY_MAJOR=3.1
HOME=/root
LANG=C.UTF-8
BUNDLE_SILENCE_ROOT_WARNING=1
GEM_HOME=/usr/local/bundle
SHLVL=0
PATH=/usr/local/bundle/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
_=/usr/bin/env
キャッシュが効いていない場合、Dockerfileに沿ってビルドが実行されますが、それがうまく省略されキャッシュが効いているのがわかります。
まとめ
前回の記事からこの記事までで、GitHub ActionsでGitHub Container registryにイメージをプッシュして、さらにそれを別のアクションで使う例を作成してみました。
細かいところを間違えると、キャッシュが効かない場合がある(自分の場合、docker-compose.ymlにcacheの設定を書いてしまって逆にビルドが走ってしまった)など、罠は多いのですが正しく記述することで強力な恩恵を得ることができます。
実用に乗せるにはまあまあな料金がかかってきますが、ちょっと軽いイメージを動かしてみるくらいなら問題ないので是非お試しください。