Docker Image を手動で管理するのは面倒なので、何らかの形で自動化する事にしました。
最終的に、 Dockerfile が更新された際に build して DockerHub に push する GitHub Actions を作成しました。
GitHub Actions を作成する際に考慮した条件
- Dockerfile が増えた場合も自動で対応する(現時点では2つ)
- Dockerfile や関連ファイルに更新が無い Image は Push しない
- GitHub Actions だけでなく、ローカルの環境でも build できる
具体的な GitHub Actions の内容
作成した .github/workflows/build-and-push.yml とbuild.sh は以下です(commit: 427f143)。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Original: https://github.com/atton/dockerfiles/blob/1566be5489c34ba743dd5735f6584d3ef213cdb5/.github/workflows/build-and-push.yml | |
name: Build and Push Docker Images | |
on: push | |
jobs: | |
build-and-push: | |
runs-on: ubuntu-latest | |
steps: | |
- name: Clone repository | |
run: git clone https://github.com/atton/dockerfiles | |
- name: Build and Push Docker Images | |
run: sh dockerfiles/build.sh ${{ secrets.DOCKER_PASSWORD }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Original: https://github.com/atton/dockerfiles/blob/1566be5489c34ba743dd5735f6584d3ef213cdb5/build.sh | |
#!/bin/sh | |
cd `dirname $0` | |
git show --name-only | |
if [ -n "$1" ]; then docker login -u atton -p $1; fi | |
for name in `ls`; do | |
if [ ! -d $name ]; then continue; fi | |
if [ ! -f $name/Dockerfile ]; then continue; fi | |
tag="atton/$name" | |
docker build --compress --pull -t $tag $name | |
git diff-tree --no-commit-id --name-only -r master | grep "$name/" >/dev/null 2>&1 | |
if [ $? -eq 0 ]; then docker push $tag; fi | |
done | |
if [ -n "$1" ]; then docker logout; fi |
自動化できたので手動 push の必要は無くなりました。べんり。
これ以降は作業ログなどを書いておきますが、かなり長いです。
これ以降は作業ログなどを書いておきますが、かなり長いです。
第一条件: Dockerfile が増えた場合も自動で対応する
この条件については、特定の構成をしているディレクトリを build 対象にする事で対応しました。具体的には
- ディレクトリ名は任意
- ls と [ -d ] で確認
- ディレクトリの直下に Dockerfile が存在する
- ls と [ -f ] で確認
といったディレクトリです。なお、ディレクトリ名は Docker Image の tag を決める際に使っています。
第二条件: Dockerfile や関連ファイルに更新が無い Image は Push しない
Docker Image を自動 build する際、最初は elgohr/Publish-Docker-Github-Action@master を使っていました。
ここで問題が発生。README.md を変更しただけの commit でも Docker Image の更新が行なわれました。
幸い、GitHub Actions の step では if が使えるようなので試してみましたが改善せず。
なので elgohr/Publish-Docker-Github-Action@master は利用しない方針に変更。
使わない事になりましたが、 entrypoint.sh に書かれた(docker login/logout など)内容は参考にできそうです。
使わない事になりましたが、 entrypoint.sh に書かれた(docker login/logout など)内容は参考にできそうです。
さて、次は「Dockerfile や関連ファイルに更新が無い」事を判定をできれば解決しそうです。ググってみると
で確認できるとの事。ではこれを grep して exit code で判定すれば解決、しませんでした。
更新の有無に関わらず、全ての grep の exit code が 1 になっていました。
加えて、ローカル環境では想定通りの exit code が得られるので、どうやら原因は実行環境固有のようです。
加えて、ローカル環境では想定通りの exit code が得られるので、どうやら原因は実行環境固有のようです。
「ローカルでは動くが、別環境では動かない」という悲しい事態なので、 printf debug で少しずつ状態を確認していきます。
- git は存在するか
- git の version は何か
- git は実行できるか
- remote origin は存在するか
- commit log は辿る事ができるか
- grep の version は何か
- ...
結果、「actions/checkout@master を使うと repository の情報が消える(?)」事が判明しました。具体的には
- git コマンドは実行できる
- git show を行なうと、全ファイルが新規作成扱いになっている
- origin を fetch しても commit が取得できない
という謎の状態でした。その為、 actions/checkout@master は利用せずに直接 git clone を実行。
clone した repository では diff-tree が実行可能で、更新の有無が判定可能になりました。
clone した repository では diff-tree が実行可能で、更新の有無が判定可能になりました。
余談: 第二条件の部分を書いている時に思った事
- elgohr/Publish-Docker-Github-Action@master のソースを確認すると、 action.yml に if はありませんでした。
- Pull Request を作成して提案する手がある
- 「ローカルでは動くが、別環境では動かない」
- GitHub で動作 Image を提供している可能性がある
- 「actions/checkout@master を使うと repository の情報が消える(?)」
- 今は git clone で対応できるが、 branch の指定といったオプションに対応できない
第三条件: GitHub Actions だけでなく、ローカルの環境でも build できる
この条件は「ローカル環境でも Docker Image を作成可能」にする為につけました。メリットとしては
- 問題発生時の再現に使用できる
- commit 前の Dockerfile も試しに build できる
- 新しい Image 作成時の build が楽
等があります。なお、この条件は build.sh に与える引数の有無で解決しました。
まとめ
結構な文量になりました。debug の説明を含めると長くなりますね。
結果的に「uses を排除して自前の run で記述する」というオレオレ GtiHub Actions で解決。
前回も書いた気がしますが、「個人的には十分満足しているので良しとします。」
参考文献や関連した文献など
- GitHub - atton/dockerfiles: Dockerfiles of published my docker images
- atton.blog: chromium-browser を使って記事のタイトルを取得する
- atton's Profile - Docker Hub
- Set TZ in "latex-make" image · atton/dockerfiles@427f143 · GitHub
- Publish Docker · Actions · GitHub Marketplace · GitHub
- Setup GitHub Actions for publish atton/webpage-title · atton/dockerfiles@6781d4e · GitHub
- Workflow syntax for GitHub Actions - GitHub Help
- GitHub - elgohr/Publish-Docker-Github-Action at 5d8ac991f54837cdbd0b34fc627e9e83c500fa43
- Publish-Docker-Github-Action/action.yml at 5d8ac991f54837cdbd0b34fc627e9e83c500fa43 · elgohr/Publish-Docker-Github-Action · GitHub
- Publish-Docker-Github-Action/entrypoint.sh at 5d8ac991f54837cdbd0b34fc627e9e83c500fa43 · elgohr/Publish-Docker-Github-Action · GitHub
- Find what files changed in a pushed commit? - GitHub Actions - GitHub Support Community
- Checkout · Actions · GitHub Marketplace · GitHub