GitHub Actions上で docker compose を爆速に使うための GitHub Action 「Spin-Up Docker Compose」を Marketplace に出しました。
背景
先日、「GitHub Actions上でdocker composeを使ってCIを回すためにうまいことキャッシュする方法」という記事を投稿させていただきました。
ありがたいことにさまざまな方にLGTMをいただくことができ、参考にしていただけたのかなと思っています。
さて、当該の記事への反応を確認しようとはてなブックマークなども閲覧させていただいていたのですが、気になるコメントを見つけました
たしかに!いい感じの docker compose 環境を作れたとして、プロジェクトごとにあの分量のymlをコピペして調整して回るのは大変ですよね。
ということで、前回の記事で用意した環境をパッケージ化し、単一のGitHub Actionとしてさまざまなプロジェクトに簡単に導入できるようにしてみました。(naari_3さん、ありがとうございます!)
使い方
基本的な使い方は以下のようになっています。fileオプションのみが必須となっています。
name: CI
on:
push:
jobs:
# イメージのビルド
build_image:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Docker Compose
uses: yu-ichiro/spin-up-docker-compose-action@v1
with:
file: app/compose.yml # ターゲットとなる yaml ファイルを指定
# この step 以下で docker compose が up された状態になっている
- name: Check Batch Runner
run: docker compose exec my-runner bash -c 'cat <(curl -s echo:5678) /the_message'
オプションの説明
より詳しい情報はレポジトリのREADMEもご参照ください
file
ターゲットとなる yaml ファイルを指定します。必須です。レポジトリのルートからの相対パスで指定します。
- name: Setup Docker Compose
uses: yu-ichiro/spin-up-docker-compose-action@v1
with:
file: app/compose.yml # ターゲットとなる yaml ファイルを指定
registry
GitHub Actions内でキャッシュされる、localhost上で動くregistry立ち上げるためのオプションです。
- name: Setup Docker Compose
uses: yu-ichiro/spin-up-docker-compose-action@v1
with:
file: app/compose.yml
registry: true # registry を使用する
localhost
後述する、ビルドするイメージのregistryを書き換え、localhostへ向け直すためのオプションです。registryとともに利用します
- name: Setup Docker Compose
uses: yu-ichiro/spin-up-docker-compose-action@v1
with:
file: app/compose.yml
registry: true # registry を使用する
localhost: true # ビルドしたイメージのregistryをlocalhostに書き換える
shared
registry と localhost を同時に指定する場合の syntax sugar になっています。
- name: Setup Docker Compose
uses: yu-ichiro/spin-up-docker-compose-action@v1
with:
file: app/compose.yml
- registry: true # registry を使用する
- localhost: true # ビルドしたイメージのregistryをlocalhostに書き換える
+ shared: true # 以上二つを指定した場合と同じ
pull
docker compose pull を実行するか、のオプションになります。pull-optsにオプションを渡すことで細かい挙動を変えることができます。
- name: Setup Docker Compose
uses: yu-ichiro/spin-up-docker-compose-action@v1
with:
file: app/compose.yml
pull: true # docker compose pull を実行する
pull-opts: "--ignore-pull-failures" # pull時のエラーを無視する
bake
docker buildx bake を実行するか、のオプションになります。このオプションが有効になると、buildxのセットアップなども走るようになり、ビルドキャッシュも効くようになります。bake-optsにオプションを渡すことで挙動を変更できます
- name: Setup Docker Compose
uses: yu-ichiro/spin-up-docker-compose-action@v1
with:
file: app/compose.yml
bake: true # docker buildx bake を実行する
bake-opts: --metadata-file metadata.json # ビルド時のメタデータをjsonに吐き出す
push
docker buildx bake 時に push を実行するかを設定できます。【注意】 localhost オプションを設定していない場合、push 先は compose.yml に従います。
- name: Setup Docker Compose
uses: yu-ichiro/spin-up-docker-compose-action@v1
with:
file: app/compose.yml
registry: true # registry を使用する
localhost: true # ビルドしたイメージのregistry(プッシュ先)をlocalhostに書き換える
bake: true # docker buildx bake を実行する
push: true # localhostにプッシュする
up
docker compose up を実行します。デフォルトで true になっており、 up-opts のデフォルトが "-d" であるため、何も設定しなければdocker compose環境が立ち上がるようになっています。
- name: Setup Docker Compose
uses: yu-ichiro/spin-up-docker-compose-action@v1
with:
file: app/compose.yml
# デフォルトの挙動
up: true
up-opts: -d
# ここ以下で docker compose 環境が使える
localhost オプションについて
デフォルトでは渡された compose.yml をそのまま読むようになっていますが、このオプションを使うと image: を書き換え、イメージの registry が localhost:5000 を向くように変更されます。これによって、セットアップを意識しない yaml の記述が可能になります。(正確な動作は convert.py を参照していただければと思います)
なお、名前とタグは自動で設定される(なにも名前などを指定しなかった場合のdocker composeの挙動を模しています)ため、微調整を行いたい場合は適宜特化したymlを用意し、localhostオプションはオフにしてご利用ください。
version: 'Compose-Spec'
services:
hoge:
image: ghcr.io/hoge:v1
fuga:
# 以下が自動で書き換えられます(タグは自動設定)
- image: ghcr.io/fuga:v2
+ image: localhost:5000/app_fuga:latest
build:
context: .
前回の記事の動作を再現したもの
以上のオプションを組み合わせることで、前回の記事でご紹介させていただいたセットアップを再現することができます。
name: CI
on:
push:
jobs:
# イメージのビルド
build_image:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Docker Compose
uses: yu-ichiro/spin-up-docker-compose-action@v1
with:
file: app/compose.yml
shared: true # localhost の registryを使い、ビルドの向き先を書き換える
bake: true # docker buildx bake を実行する
push: true # localhostにプッシュする
up: false # docker compose up は実行しない
use_image:
needs: build_image # ビルド用のjobの完了を待つ
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Docker Compose
uses: yu-ichiro/spin-up-docker-compose-action@v1
with:
file: app/compose.yml
shared: true # localhost の registryを使い、プルの向き先を書き換える
pull: true # build_image で作ったイメージをプルする
# up を指定していないので docker compose up -d が実行される
- name: Check Batch Runner
run: docker compose exec my-runner bash -c 'cat <(curl -s echo:5678) /the_message'
# 複数のjobで並列に利用することができます
use_image2:
needs: build_image # ビルド用のjobの完了を待つ
# ... 省略 ...
詰まったところ
さて今回、汎用的なActionsを作るために一連の動作をオプションで区切れるようにしていったのですが、一箇所解決できなくて詰まったところがありました。それが、buildxでビルドしたイメージが docker compose up -d で使われない、というものでした。
結論としては、imageタグが指定されていない場合の動作が、docker compose build と docker buildx bake で異なっており、前者は compose.yml が存在するディレクトリ名とサービス名を組み合わせて自動的にイメージ名・タグを割り振ってくれるのに対し、後者は <none>
となってしまっていたからでした。( https://github.com/docker/buildx/issues/902 )
解決方法として、buildだけが指定されていてimageがない場合はdocker compose buildの挙動に合わせたイメージ名、タグを指定するようにyamlを書き換えるようになっています。(→ convert.py )
このワークアラウンドを使用することで、buildxサブコマンドをシームレスに使うことができるようになっています。
ぜひご利用ください
他の細かい挙動は基本的に前回の記事でご紹介したものがそのまま詰まったものになっています。GitHub Actionsで docker compose をストレスなく使えるようになると、CI をとっても簡単に整備することができるようになります。ぜひ便利にご利用いただければと思います!