🐥

GitHub ActionsでDocker ImageをビルドしてPushする

2022/01/06に公開

Docker Hubでの自動ビルドが動かなくなっていたのでGitHub Actionsに移行してみた。
要件としては、

  1. タグをつけたらDocker Imageを作成する
  2. DockerHubに1のイメージをPushする
  3. GitHub Container Registryに1のイメージをPushする

2と3を両方やる例を書いておくが2,3のどちらか一方でもいい。

Circle CI用のベースとなるイメージ作成の https://github.com/taka0125/circleci-ruby を元に記事に起こした。

タグからRubyのバージョン・Bundlerのバージョン決めるとか余計な事もやっている

Secretsの設定

該当リポジトリの Settings > Secrets から設定する。

DockerHubへのログイン用の情報とGitHub Container Registryのログイン用の情報を設定する

という名前で設定した

GitHub Actionsの設定

.github/workflows/docker.yml を設置する

name: Publish Docker image

on:
  push:
    tags:
      - '*'

jobs:
  push_to_registry:
    name: Push Docker image to Docker Hub
    runs-on: ubuntu-latest
    steps:
      - name: Check out the repo
        uses: actions/checkout@v2

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v1

      - name: Cache Docker layers
        uses: actions/cache@v2
        with:
          path: /tmp/.buildx-cache
          key: ${{ runner.os }}-buildx-${{ github.sha }}
          restore-keys: |
            ${{ runner.os }}-buildx-

      - name: Prepare Build Arg
        id: prepare_build_arg
        run: |
          CURRENT_TAG=${GITHUB_REF#refs/tags/}
          echo ::set-output name=CURRENT_TAG::${CURRENT_TAG}
          echo ::set-output name=RUBY_VERSION::${CURRENT_TAG%-*}
          echo ::set-output name=BUNDLER_VERSION::${CURRENT_TAG##*-}

      - name: Log in to Docker Hub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Build and push Docker image to Docker Hub
        uses: docker/build-push-action@v2
        with:
          push: true
          tags: taka0125/cimage-ruby:${{ steps.prepare_build_arg.outputs.CURRENT_TAG }}
          labels: |
            org.opencontainers.image.source=${{ github.event.repository.clone_url }}
          cache-from: type=local,src=/tmp/.buildx-cache
          cache-to: type=local,dest=/tmp/.buildx-cache-new
          build-args: |
            RUBY_VERSION=${{ steps.prepare_build_arg.outputs.RUBY_VERSION }}
            BUNDLER_VERSION=${{ steps.prepare_build_arg.outputs.BUNDLER_VERSION }}

      - name: Login to GitHub Container Registry
        uses: docker/login-action@v1
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.PERSONAL_ACCESS_TOKEN }}

      - name: Build and push Docker image to GitHub Container Registry
        uses: docker/build-push-action@v2
        with:
          push: true
          tags: |
            ghcr.io/${{ github.repository_owner }}/cimage-ruby:${{ steps.prepare_build_arg.outputs.CURRENT_TAG }}
          labels: |
            org.opencontainers.image.source=${{ github.event.repository.clone_url }}
          cache-from: type=local,src=/tmp/.buildx-cache
          cache-to: type=local,dest=/tmp/.buildx-cache-new
          build-args: |
            RUBY_VERSION=${{ steps.prepare_build_arg.outputs.RUBY_VERSION }}
            BUNDLER_VERSION=${{ steps.prepare_build_arg.outputs.BUNDLER_VERSION }}

      - name: Move cache
        run: |
          rm -rf /tmp/.buildx-cache
          mv /tmp/.buildx-cache-new /tmp/.buildx-cache

DockerHub用の設定

      - name: Log in to Docker Hub
        uses: docker/login-action@v1
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Build and push Docker image to Docker Hub
        uses: docker/build-push-action@v2
        with:
          push: true
          tags: taka0125/cimage-ruby:${{ steps.prepare_build_arg.outputs.CURRENT_TAG }}
          labels: |
            org.opencontainers.image.source=${{ github.event.repository.clone_url }}
          cache-from: type=local,src=/tmp/.buildx-cache
          cache-to: type=local,dest=/tmp/.buildx-cache-new
          build-args: |
            RUBY_VERSION=${{ steps.prepare_build_arg.outputs.RUBY_VERSION }}
            BUNDLER_VERSION=${{ steps.prepare_build_arg.outputs.BUNDLER_VERSION }

この部分がDockerHub用の設定。

GitHub Container Registry用の設定

      - name: Login to GitHub Container Registry
        uses: docker/login-action@v1
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.PERSONAL_ACCESS_TOKEN }}

      - name: Build and push Docker image to GitHub Container Registry
        uses: docker/build-push-action@v2
        with:
          push: true
          tags: |
            ghcr.io/${{ github.repository_owner }}/cimage-ruby:${{ steps.prepare_build_arg.outputs.CURRENT_TAG }}
          labels: |
            org.opencontainers.image.source=${{ github.event.repository.clone_url }}
          cache-from: type=local,src=/tmp/.buildx-cache
          cache-to: type=local,dest=/tmp/.buildx-cache-new
          build-args: |
            RUBY_VERSION=${{ steps.prepare_build_arg.outputs.RUBY_VERSION }}
            BUNDLER_VERSION=${{ steps.prepare_build_arg.outputs.BUNDLER_VERSION }}

この部分がGitHub Container Registry用の設定。
DockerHubとさほど変わらない。

コミットして、 Pushして、タグをつけてみる

3.0.0-node-2.3.4 というタグをつけると

cimage/ruby:3.0.0-node をベースにして bundler の 2.3.4 を入れたイメージができあがる。

DockerHubは https://hub.docker.com/repository/docker/taka0125/cimage-ruby
GitHub Container Registryは https://github.com/taka0125/circleci-ruby/pkgs/container/cimage-ruby

GitHub Container Registry側は最初にイメージをPushしてからPublicにしたりリポジトリをリンクしたり手動で設定した。

これもGitHub Actionsでやれればいいのだが…。

Discussion