4
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Docker Hub代わりのGitHub Container Registry入門

Last updated at Posted at 2020-09-16

一生懸命まとめましたが、公式ドキュメントに丁寧で正確な説明があることに最近気づきました。

概要

Docker Hubの無料枠に制限がかかるという話もあり、GitHub Container Registryの使い方を調べたのでメモする。具体的には以下を実現したい。

  1. GitHubへpushする度、GitHub Actionsでdockerイメージをbuildし、GitHub Container Registryにpush
  2. その際、GitHubへpushしたタグに応じて、dockerイメージのタグも変更する

環境

  • wsl2のDebian
  • Docker version 19.03.12, build 48a66213fe

事前準備

GitHub Container Registryに自動でdockerイメージをpushするには、Personal Access Tokenが必要1。GitHub右上の自分のアイコンからSettings > Developer settings > Personal access tokens > Generate new tokenの手順で作成する。スコープは以下の画像のもので大丈夫そう。

image.png

得られたトークンはDockerfileなどを管理しているGitHubリポジトリでSetting > Secrets > New secretの手順で登録しておく(ここではCR_PATという名前で保存したことにする)。

YAMLファイル作成①

GitHub Actionsを制御するためのYAMLファイルを作成する。以下のようなディレクトリ構成を想定2

.
├── .git
├── .github
│   └── workflows
│       └── build_on_push.yaml
└── Dockerfile
name: Publish Docker image
on: push
jobs:
  main:
    name: Push Docker image to Github Container Registry
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v2
      - name: Set up QEMU
        uses: docker/setup-qemu-action@v1
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1
      - name: Login to GitHub Container Registry
        uses: docker/login-action@v1
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.CR_PAT }}
      - name: Push to GitHub Container Registry
        uses: docker/build-push-action@v2
        with:
          push: true
          tags: ghcr.io/dr666m1/qiita_starwars:latest

name:はworkflowやjobを命名しているだけなので任意の値。on:ではトリガーとなるイベントを指定(ここではpush)。3行目のjobs:で5つのstepからなるjobを定義しているので、以降で各stepについて簡単に解説する(ちなみにruns-on:はjobを実行する仮想マシンの指定で、ここではGitHubホストランナーを選択している)。

Checkout

actions/checkout@v2というactionで、GitHubリポジトリにアクセスできる状態にする。逆に言えば、このstepがないと「Dockerfileが見つかりません」といったエラーに陥るはず。ドキュメントはこちら

Set up QEMU, Set up Docker Buildx

docker/setup-qemu-action@v1 docker/setup-buildx-action@v1はいずれも必要な機能を利用可能にするためのactionという程度の認識でよいと思う。

Login to GitHub Container Registry

docker/login-action@v1というactionでログイン処理を行う。${{ secrets.CR_PAT }}は先ほど作成したPersonal Access Tokenを参照している。Docker Hub やGitLabにも対応していて、ドキュメントにはそれぞれの対応方法が記載されている。

Push to GitHub Container Registry

docker/build-push-action@v2というactionでdockerイメージのbuildとpushを行う。tags:でタグも指定できるが、この段階ではlatestとしておく。

動作確認

ファイルの準備ができたらgit pushするだけで、YAMLで定義したワークフローが実行される。以下の画面のようにログも確認できる。

image.png

問題なければGitHub右上の自分のアイコンからYour profile > Packagesでbuildされたdockerイメージを確認できる。デフォルトでprivateになるようなので、publicにしたければ変更してしまう。あとはdocker runして問題なければOK3

docker run -it --rm ghcr.io/dr666m1/qiita_starwars:latest

YAMLファイル作成②

次にタグを指定できるよう、YAMLファイルを以下の通り変更する。

name: Publish Docker image
on: push
jobs:
  main:
    name: Push Docker image to Github Container Registry
    runs-on: ubuntu-latest
    steps:
      - name: Prepare # 追加
        id: prep
        run: |
          if [[ $GITHUB_REF == refs/tags/* ]]; then
            TAG=${GITHUB_REF#refs/tags/}
          else
            TAG="latest"
          fi
          echo "::set-output name=tag::${TAG}"
      - name: Checkout
        uses: actions/checkout@v2
      - name: Set up QEMU
        uses: docker/setup-qemu-action@v1
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1
      - name: Login to GitHub Container Registry
        uses: docker/login-action@v1
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.CR_PAT }}
      - name: Push to GitHub Container Registry
        uses: docker/build-push-action@v2
        with:
          push: true
          tags: ghcr.io/dr666m1/qiita_starwars:${{ steps.prep.outputs.tag }} # 変更

主な変更点はPrepareというstepの追加。run:でshell(デフォルトはbash4)で実行されるコマンドを指定する。ここでは$GITHUB_REF環境変数5によって処理を変えていて、タグの名前を含めばそれを、なければlatestTAGに代入している。echo "::set-output name=tag::${TAG}"ワークフローコマンドと呼ばれるもので、ここではTAGの値を後続のstepで参照できるようにしている。${{ steps.prep.outputs.tag }}が実際に参照している部分。

この変更によって、GitHubにpushしたタグに応じてdockerイメージのタグも変更されるようになる。例えば以下のように実行すれば、dockerイメージのタグも1.0になる。

git tag 1.0
git push --tags

image.png

最後に

もしDocker HubからGitHub Container Registryに移行したくなっても、これで概ね困らなそう。GitHub Actionsは自動テストなど、もっといろいろなことに使えるはずなので、時間があるときに勉強したい。

  1. Github Packagesでは、代わりにGITHUB_TOKENが使えたらしい

  2. 実際に使ったGitHubリポジトリはこちら
    build_on_push.yamlの内容は以下の通り。

  3. Dockerfileを見ての通りだが、この例だとスターウォーズの上映が始まる(telnet towel.blinkenlights.nl)のでCtrl+] > quitで抜けるこのサンプルdockerイメージは削除済み

  4. 利用可能なshellは公式ドキュメントを参照

  5. 利用可能な環境変数は公式ドキュメントを参照

4
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?