目的
- Dockerコンテナイメージを生成しghcr.ioへPushできるようになる。
- GitHub Actions内でghcr.ioからコンテナイメージをPullし、コンテナ内でテストができるようになる。
- ghcr.ioへPushしたコンテナイメージを編集することができるようになる。(サブクエ)
背景
GitHub ActionsのworkflowでDockerコンテナを利用したテストを導入する方法を知りたいと思っていた。
今回はやっていないが、制限された環境(メモリ制約など)における試験などは、コンテナを使って試験をするのが簡単なため、まずはDockerコンテナをActions内で利用するところから知識を蓄えたいと思った。
ghcr.ioとは
Dockerコンテナイメージを保存、管理することができるコンテナレジストリです。
Docker公式にもDocker Hubがありますが、同様のコンテナレジストリです。
サンプルコード
今回のサンプルコードは下記リポジトリにあります。
1.Dockerfileからコンテナイメージを作成しghcr.ioへPush
1.1.Dockerfileを作成
コンテナイメージの元となるDockerfileを作成します。
FROM python:3.10
WORKDIR /app
RUN pip install --upgrade pip && \
pip install pytest \
pip install pytest-cov
1.2.コンテナイメージを作成
ghcr.io/OWNER/IMAGE_NAME:TAGの部分については適宜置き換えてください。
% docker build . -t ghcr.io/OWNER/IMAGE_NAME:TAG
1.3.作成したコンテナイメージの構築確認
pythonバージョンと、pytest、pytest-covが入っていることを確認します。
% docker run -it 32 /bin/bash
root@e162a649e4d6:/app# python -V
Python 3.10.6
root@e162a649e4d6:/app# pip freeze
attrs==22.1.0
coverage==6.4.4
iniconfig==1.1.1
install==1.3.5
packaging==21.3
pluggy==1.0.0
py==1.11.0
pyparsing==3.0.9
pytest==7.1.2
pytest-cov==3.0.0
tomli==2.0.1
1.4.コンテナイメージをPush
こちらの公式ドキュメントを参考に、自身が必要な箇所のみをピックアップしました。
まずはアクセストークンの生成です。
生成方法は下記に手順があるのでそちらを参照とします。
アクセストークンの生成にてスコープの選択がありますが、コンテナイメージの操作を行う場合は下記スコープを選択してください。
次にログインとコンテナイメージのPushを行います。
YOUR_TOKEN
を生成したトークンに置き換えて実行してください。
USERNAME、ghcr.io/OWNER/IMAGE_NAME:TAGの部分についても適宜置き換えてください。
% export CR_PAT=YOUR_TOKEN
% echo $CR_PAT | docker login ghcr.io -u USERNAME --password-stdin
% docker push ghcr.io/OWNER/IMAGE_NAME:TAG
2.GitHub Actionsでghcr.ioからコンテナイメージをPullしテストを実行
2.1.ワークフローを作成
すぐに試せるように実行トリガーはon: workflow_dispatch
としています。
コード中のdockerリポジトリは公開しているため、ログイン処理をコメントアウト、リポジトリURLも固定としてあります。
非公開のリポジトリの場合は、コメントアウト箇所を戻す、または、置き換えて利用してください。
IMAGE_NAME:TAGの部分については適宜置き換えてください。
name: unit-test
on: workflow_dispatch
jobs:
unit-test-job:
name: run unit-test job
runs-on: ubuntu-latest
steps:
- name: checkout code
uses: actions/checkout@v3
# - name: Login to Docker
# uses: docker/login-action@v1
# with:
# registry: ghcr.io
# username: ${OWNER,,}
# password: ${{ secrets.GHCR_PAT }}
# env:
# OWNER: ${{ github.repository_owner }}
- name: Set up Docker
run: |
docker pull ghcr.io/mamedenq/python-test-env:latest
docker-compose up -d
# run: |
# docker pull ghcr.io/${OWNER,,}/python-test-env:latest
# docker-compose up -d
# env:
# OWNER: ${{ github.repository_owner }}
- name: test
run: docker-compose exec -T app pytest --cov
コメントアウトしている箇所で、小文字変換している処理があります。
- name: Login to Docker
uses: docker/login-action@v1
with:
username: ${OWNER,,}
env:
OWNER: ${{ github.repository_owner }}
最近登録した人はどうなのかわかりませんが、私の場合はオーナー名称に大文字が入っており、dockerリポジトリ名のルールに抵触しエラーが出るため、リポジトリオーナーの変数をそのまま使わず小文字変換するようにしないといけません。固定文字列で指定してしまう、また、不要な人は取り除いても構わないかと思います。
2.2.docker-compose.ymlを作成
docker-compose実行時に立ち上げるサービスを指定します。
指定するイメージはPullしたイメージとなるよう、image
に指定します。
version: "3"
services:
app:
image: ghcr.io/mamedenq/python-test-env:latest
volumes:
- ./:/app
tty: true
2.3.シークレット値を追加(Dockerリポジトリが公開されている場合は不要)
unit-test.yml
から参照しているシークレット値GHCR_PAT
を追加します。
リポジトリの設定から追加します。
2.4.ワークフローを実行
リポジトリのActionsからworkflowを実行します。
無事成功し、テスト結果も良好です。
3.(サブクエ)ghcr.ioへPushしたコンテナイメージを編集
一応PushしたイメージのPull、編集、コミット、Push方法も載せます。
3.1.コンテナイメージをPull
ghcr.io/OWNER/IMAGE_NAME:TAGの部分については適宜置き換えてください。
% docker pull ghcr.io/OWNER/IMAGE_NAME:TAG
3.2.コンテナイメージを修正してPush
1つのターミナルでできるのかもしれませんが、やり方がわからなかったため、2ターミナルに分かれての操作となります。
コンテナを起動し任意の修正を入れます。
% docker run -it ea /bin/bash
root@4f0465605a3f:/app# mkdir /new_dir
コンテナの修正差分をcommitします。
AUTHOR_NAME、MESSAGE、CONTAINER_ID、ghcr.io/OWNER/IMAGE_NAME:TAGの部分については適宜置き換えてください。
% docker container commit -a AUTHOR_NAME -m MESSAGE CONTAINER_ID ghcr.io/OWNER/IMAGE_NAME:TAG
コンテナから抜け、修正したコンテナイメージをPushします。
ghcr.io/OWNER/IMAGE_NAME:TAGの部分については適宜置き換えてください。
root@4f0465605a3f:/app# exit
% docker push ghcr.io/OWNER/IMAGE_NAME:TAG
最後に
シンプルにGitHub ActionsでDockerコンテナを動かすことはできた。
一部大変だったところは、リポジトリオーナー名に大文字が入っていたこと。最近は登録時に制限されているのだろうなとは思うが、これをworkflow内で小文字に変換するにはどうしたらいいか時間がかかってしまった。
ここについては、GitHub Actionsの基礎や構文についての知識がまだ不足しており、shell上でやり方はわかっても、GitHub Actions上でどう表現するかのボキャブラリーがなく対処ができなかった。やってきたことをテンプレ的にやるのであれば問題ないが、例外的なことに対処ができていないため、もう少し基礎的なことを身につける必要があると感じた。
背景にある制限された環境における試験については、コンテナを作る際にメモリ制限などの環境情報を設定できるため、今後習得しておきたいと思う。