Help us understand the problem. What is going on with this article?

【CI/CD】 Github Actionsを使ってDocker ImageをGitHub Package Registry にpushする

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をクリックします。

スクリーンショット 2019-11-24 11.26.32.png

編集画面が出ますが一旦このまま右上の緑のボタンからcommitしてください。

スクリーンショット 2019-11-24 11.27.07.png

この操作で.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されたものが確認できます。

スクリーンショット 2019-11-24 11.29.45.png

スクリーンショット 2019-11-24 11.30.12.png

secretsの設定

認証情報等の秘密情報はmain.ymlに埋め込むわけには行かないので、リポジトリのsecretsに設定する必要があります。今回は埋め込んでしまっても問題ないのですが、secretsにユーザー名を設定してみます。

Settings > Secrets > Add a new secret と進むと下のような画面になり、ここにsecretを追加しておきます。

スクリーンショット 2019-11-24 12.50.51.png

一つは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を用意することもできます。

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_REFGITHUB_REPOSITORYはデフォルトで定義されている環境変数です。その他の環境変数はこちらです。

ここまで編集が終了したら.github/workflows/main.ymlをcommitとpushしてください。

動作確認

先ほどWorkflowの実行を確認した時と同様に動作確認してください。

スクリーンショット 2019-11-24 14.07.58.png

また、packageにimageがpushされているかも確認しておきます。packageをクリックすると以下のようにレジストリが作成されていることが確認できます。

スクリーンショット 2019-11-24 14.10.33.png

スクリーンショット 2019-11-24 14.27.19.png

これでdocker pullできます。pullする時には先ほどのToken(or 同等の権限を持つもの)でdocker loginする必要があります。pullコマンドは以下のように表示されています。

スクリーンショット 2019-11-24 14.30.44.png

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から

スクリーンショット 2019-11-24 13.37.55.png

Developer settingsに移動しスクリーンショット 2019-11-24 13.41.03.png

スクリーンショット 2019-11-24 13.39.37.png

Generate new tokenから新しいTokenを作成します。

スクリーンショット 2019-11-24 13.41.03.png

まずNoteの部分にこのTokenの説明(他のTokenと区別がつくように、今回はリポジトリ名を記載)を設定し、その下のScopeを設定していきます。必要なScopeは

  • repo
  • write:packages
  • read:packages

あたりになります。

スクリーンショット 2019-11-24 12.58.20.png

これでページ下部のGenerate TokenをクリックするとTokenが表示されます。
Tokenは11aaaa1aba999951abca2406b92a66665d3cb22のような文字列でこのタイミング以外では二度と表示されないのでからなず確認し、また流出等扱いには気をつけてください。

まとめ

Github Actionsを使ってDocker ImageをGitHub Package Registry にpushする一連の操作を説明しました。CI/CDツールとしての利用は多くの場合、Github ActionsとGitHub Package Registryを利用することで完結できるのではないかと思います。また、課金プランによって使用制限があるようですが無料アカウントでも個人レベルでの使用では問題なさそうです。ただし、使用制限下部に記載がある通り、仮想通貨の採掘やサーバーレスコンピューティングを目的とする場合等、コード開発プロセスの自動化以外の目的に使うことは制限されているようなので注意しましょう。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした