概要
この記事では、GitHub Actions を使ってタグ push(v*)をトリガーに Docker イメージをビルドしてプライベートなコンテナレジストリ(registry.uniproject.jp)へプッシュするワークフローの設定例を解説します。実際のワークフローは以下のようになっていて、ポイントごとに詳しく説明します。
name: Docker Build and Push
on:
push:
tags:
- "v*"
concurrency:
group: docker-build-push
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Extract tag name
run: tagname=${GITHUB_REF#refs/*/} && echo "TAG_NAME=${tagname#v}" >> $GITHUB_ENV
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: registry.uniproject.jp
username: robot$github-publisher
password: ${{ secrets.HARBOR_TOKEN }}
- name: Add metadata
id: meta
uses: docker/metadata-action@v5
with:
images: registry.uniproject.jp/infra/unibot
tags: |
type=raw,value=latest
type=semver,pattern={{version}}
type=sha,prefix=,suffix=,format=short
- name: Push Docker image
uses: docker/build-push-action@v5
with:
file: ./Dockerfile
push: true
context: .
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=registry,ref=registry.uniproject.jp/infra/unibot:buildcache
cache-to: type=registry,ref=registry.uniproject.jp/infra/unibot:buildcache,mode=max
各セクションの解説
- トリガー(on: push tags)
-
v*のタグが push されたときのみ動きます。リリースタグ(例:v1.2.3)を push したタイミングで自動でイメージを作る運用に向きます。
-
-
concurrency- 同じグループのジョブが並列で走らないようにします。
cancel-in-progress: trueにしておくと新しいビルドで古いビルドをキャンセルしてくれるので、無駄なビルドを減らせます。
- 同じグループのジョブが並列で走らないようにします。
-
actions/checkout@v4- リポジトリのファイルをチェックアウトします。Dockerfile がリポジトリルートにある想定です。
-
docker/setup-buildx-action@v3- Buildx を使うことでマルチプラットフォームビルドやキャッシュが使いやすくなります。将来的に
platforms: linux/amd64,linux/arm64を追加するとマルチアーキに対応できます。
- Buildx を使うことでマルチプラットフォームビルドやキャッシュが使いやすくなります。将来的に
- タグ名の抽出
-
GITHUB_REFはrefs/tags/v1.2.3のような形式なので、シェルでvを取り除きTAG_NAME環境変数に入れています。後段でバージョンラベルに使えます。
-
- レジストリへのログイン
-
docker/login-actionを使ってregistry.uniproject.jpにログインします。ここではusername: robot$github-publisherとpassword: ${{ secrets.HARBOR_TOKEN }}を利用しています。HARBOR_TOKENは GitHub リポジトリのSettings > Secrets and variables > Actionsに登録して使ってください。
-
-
docker/metadata-action@v5- ここでイメージ名やタグの組み立てを行っています。
type=raw,value=latestでlatestタグを付与し、type=semver,pattern={{version}}で semver に応じたタグ(1.2.3)を付与します。type=shaは短いコミット SHA を付ける設定です。
- ここでイメージ名やタグの組み立てを行っています。
-
docker/build-push-action@v5-
file,context,tags,labels,cache-from,cache-toを指定してビルドとプッシュを行います。 -
cache-from/cache-toに registry の参照を使うことで、レジストリに保存したキャッシュを再利用できます。ビルド時間短縮に有効です。
-
注意点とおすすめ設定
- Secrets の準備
-
HARBOR_TOKENのようなトークンは GitHub の Actions Secrets に登録してください。もし Harbor 側でアクセストークンを作る場合は、必要な権限(push, pull, read)を付与しておきます。
-
- ユーザー名の扱い
-
username: robot$github-publisherのような syntactic な名前は Harbor 側で事前に用意された robot アカウントを使う想定です。環境に合わせて書き換えてください。
-
- マルチアーキテクチャ対応
-
docker/build-push-actionにplatforms: linux/amd64,linux/arm64を追加すると複数アーキ向けイメージを同時にビルドできます。Buildx のセットアップが必須です。
-
- キャッシュの運用
-
cache-toにmode=maxを指定するとキャッシュを最大限に使いますが、キャッシュのサイズやレジストリのポリシーに注意してください。必要に応じて TTL を設定したり、専用の buildcache タグを管理するとよいです。
-
よくあるトラブルと対処法
- 認証エラー
-
unauthorizedなどのエラーが出る場合は、HARBOR_TOKENが正しいか、トークンに push 権限があるかを確認してください。
-
- タグが生成されない(version が空)
-
GITHUB_REFの形式を確認してください。リリースフローでタグをプッシュしているか、または Actions 上で手動トリガーを使っている場合は入力に注意が必要です。
-
- キャッシュが効かない
-
cache-fromの参照イメージが存在しないと効きません。最初のビルドではキャッシュがないため時間がかかる点は想定内です。レジストリにbuildcacheタグが成功時に残るか確認してください。
-
まとめ
このワークフローは、タグベースのリリースで自動的に Docker イメージをビルドしてプライベートレジストリにプッシュする構成例です。ポイントはタグの取り扱い、レジストリ認証、そしてビルドキャッシュの活用です。必要に応じて platforms を追加したり、ビルド引数を渡してカスタマイズしてください。
署名の方法とかがあまりわかってないので、わかる方いたら教えてください...