Githubにもワークフローの実行ツールのGithub Actionsとパッケージの管理機能のGitHub Package Registryが追加されました。これらを使うことで、CIプロセスにおけるDockerのbuildやpushをGithubの機能で完結できます。ここでは、Docker imageをGithub Actions、GitHub Package Registry によって公開するまでの手順を解説します。
前準備
手順を進めて最終的に出来上がるリポジトリはこちらです。
準備として、以下のような構成のリポジトリをGithubに作成します。
./
┣ README.md
┗ app/
┗ Dockerfile
Dockerfileは3秒ごとにecho hello
を実行するだけの単純なものです。
# ./app/Dockerfile
FROM alpine:3.10.3
CMD while :; do echo hello; sleep 3; done
上記のリポジトリをpushしたら準備は完了です。
Workflowを追加
GithubのUI上でベースとなるファイルを生成します。
上部のActionsからSet up a workflow yourselfをクリックします。
編集画面が出ますが一旦このまま右上の緑のボタンからcommitしてください。
この操作で.github/workflows/main.yml
が生成されました。ローカルで編集するためgit pull
して中身を確認すると以下のymlファイルが作成されています。
name: CI
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Run a one-line script
run: echo Hello, world!
- name: Run a multi-line script
run: |
echo Add other actions to build,
echo test, and deploy your project.
リポジトリ全体はこのようになりました。
./
┣ README.md
┣ .github/
┃ ┗ workflows/
┃ ┗ main.yml
┗ app/
┗ Dockerfile
Workflowが実行されていることを確認
この時点でmain.ymlがpushされているのでWorkflowが動くことを確認できます。
ActionsのCIをクリックすると実行結果画面になりmain.yml
でechoされたものが確認できます。
secretsの設定
認証情報等の秘密情報はmain.ymlに埋め込むわけには行かないので、リポジトリのsecretsに設定する必要があります。今回は埋め込んでしまっても問題ないのですが、secretsにユーザー名を設定してみます。
Settings > Secrets > Add a new secret と進むと下のような画面になり、ここにsecretを追加しておきます。
一つはGITHUB_DOCKER_USERNAME
でここはリポジトリのオーナー(自分のユーザ名)を指定します。今回は特にこれ以外の登録すべきものはありませんが、他にもパスワード等の情報が必要な場合はここに登録することでGithub Actionsの中で使用できます。
※ Gitlab CIだと$CI_REGISTRY_USER
でregistryにloginできるのでGithub Actionsでもこれに相当するものがありそうな気がするが調べきれませんでした。そのうち見つかれば直します。
Dockerfileをbuildしてpushするようにする。
.github/workflows/main.yml
を編集してDockerのbuildとpushが行われるようにします。以下のように編集してください。test_containerというimageがブランチ名をタグとしてpushされるようになります。
name: CI
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: build Dockerfile and push image # userで外部ファイル or 定義済みの処理を実行できる。ここではリポジトリのcheckout
run: |
IMAGE_NAME=test_container:${GITHUB_REF#refs/heads/} # docer imageの名前とそのタグ、${GITHUB_REF#refs/heads/}でブランチ名を取得している
docker build ./app --tag docker.pkg.github.com/${GITHUB_REPOSITORY}/${IMAGE_NAME}
docker login docker.pkg.github.com --username ${DOCKER_USERNAME} --password ${DOCKER_PASSWORD}
docker push docker.pkg.github.com/k8shiro/github_docker_push_example/${IMAGE_NAME}
env:
DOCKER_USERNAME: ${{ secrets.GITHUB_DOCKER_USERNAME }} # リポジトリのsecretsとして定義した値を環境変数に渡す
DOCKER_PASSWORD: ${{ secrets.GITHUB_TOKEN }}
ファイルの内容の説明です。詳細や今回使用していないものは
https://help.github.com/ja/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions
に記載されています。
name: CI # ワークフローの名前
on: [push] # ワークフローをトリガーするGitHubイベントの名前、ここではリポジトリへのpushでワークフローが実行される
トリガーはwikiの変更やissueに関するイベント等様々なものがあります。
参照: https://help.github.com/ja/actions/automating-your-workflow-with-github-actions/events-that-trigger-workflows
runs-on: ubuntu-latest # ワークフローの実行環境の指定
runs-onでワークフローの実行環境となるrunnerを指定します。Windows Server等も用意されているようです→GitHub-hosted runners。
また自分でrunnerを用意することもできます。
- Self-hosted runners について:
uses: actions/checkout@v1 # 既定のアクションを実行、ここではリポジトリのcheckoutのアクションを実行している
uses
ではGithub既定のアクションの呼び出し、または自分で定義した別ファイルのアクションを呼び出せます。
- name: build Dockerfile and push image
run: |
IMAGE_NAME=test_container:${GITHUB_REF#refs/heads/} # docer imageの名前とそのタグ、${GITHUB_REF#refs/heads/}でブランチ名を取得している
docker build ./app --tag docker.pkg.github.com/${GITHUB_REPOSITORY}/${IMAGE_NAME} # Dockerfileのbuild
docker login docker.pkg.github.com --username ${DOCKER_USERNAME} --password ${DOCKER_PASSWORD} # GitHub Package Registryへのlogin
docker push docker.pkg.github.com/k8shiro/github_docker_push_example/${IMAGE_NAME} # imageのpush
env:
DOCKER_USERNAME: ${{ secrets.GITHUB_DOCKER_USERNAME }} # リポジトリのsecretsとして定義した値を環境変数に渡す
DOCKER_PASSWORD: ${{ secrets.GITHUB_TOKEN }} # Github Actionsで規定で定義されるGITHUB_TOKENを使用
Dockerのbuild・pushを行う処理です。まず、一番下のenv
ですが、ここで環境変数を設定しています。先ほど設定したsecretsがsecrets.*****
で読み込まれ、これがDOCKER_USERNAME
として設定されています。また、secrets.GITHUB_TOKEN
はデフォルトで定義されるTokenでPermissions等はここに記載されています。GITHUB_REF
、GITHUB_REPOSITORY
はデフォルトで定義されている環境変数です。その他の環境変数はこちらです。
ここまで編集が終了したら.github/workflows/main.yml
をcommitとpushしてください。
動作確認
先ほどWorkflowの実行を確認した時と同様に動作確認してください。
また、packageにimageがpushされているかも確認しておきます。packageをクリックすると以下のようにレジストリが作成されていることが確認できます。
これでdocker pullできます。pullする時には先ほどのToken(or 同等の権限を持つもの)でdocker loginする必要があります。pullコマンドは以下のように表示されています。
ImageをPullする
自分の開発環境に作成されたdocker imageを落としてくるには、上記画像の通りdocker pull
コマンドを実行すればよいのですが、pullの前にdocker login
コマンドを実行する必要があります。
docker login docker.pkg.github.com -u <username> -p <personal access token>
docker pull docker.pkg.github.com/k8shiro/github_docker_push_example/test_container:master
ここでは自分のユーザー名でよいのですが、はGithubのパスワードではだめで、Personal Access Tokenを取得する必要があります。
personal access token
GitHub Package Registryへのloginには、personal access tokenを使用する必要があります。
自分のアカウントのSettingsから
Generate new tokenから新しいTokenを作成します。
まずNoteの部分にこのTokenの説明(他のTokenと区別がつくように、今回はリポジトリ名を記載)を設定し、その下のScopeを設定していきます。必要なScopeは
- repo
- write:packages
- read:packages
あたりになります。
これでページ下部のGenerate TokenをクリックするとTokenが表示されます。
Tokenは11aaaa1aba999951abca2406b92a66665d3cb22
のような文字列でこのタイミング以外では二度と表示されないのでからなず確認し、また流出等扱いには気をつけてください。
まとめ
Github Actionsを使ってDocker ImageをGitHub Package Registry にpushする一連の操作を説明しました。CI/CDツールとしての利用は多くの場合、Github ActionsとGitHub Package Registryを利用することで完結できるのではないかと思います。また、課金プランによって使用制限があるようですが無料アカウントでも個人レベルでの使用では問題なさそうです。ただし、使用制限下部に記載がある通り、仮想通貨の採掘やサーバーレスコンピューティングを目的とする場合等、コード開発プロセスの自動化以外の目的に使うことは制限されているようなので注意しましょう。