Github ActionsでDocker ImageをPackagesにPushする

やりたいこと

Github にリリースタグを打ったら下記を actions で自動化したい.

  • アプリの release 自動化.
  • 開発環境やプロダクション環境などの Docker Image を Github Packages に push.

準備

何でも良いが今回は例として React アプリとアプリ実行するためのコンテナを用意.
あと今回のリポジトリはここ.

React アプリの作成

  1. 下記コマンド実行. node や npm のインストール方法は割愛.

    npx create-react-app my-app
    
  2. package-lock.json の生成

    コンテナ側で使うので一応生成しておく.

    npm i --package-lock-only
    
  3. React アプリの実行

    • 一応 cd my-app; npm run start してアプリが実行できることを確認しておく.

いつもの

コンテナの作成

  1. 下記のような Dockerfile をプロジェクト直下に配置する

    # pull official base image
    FROM node:13.12.0-alpine
    
    # set working directory
    WORKDIR /app
    
    # add `/app/node_modules/.bin` to $PATH
    ENV PATH /app/node_modules/.bin:$PATH
    
    # install app dependencies
    COPY package.json ./
    COPY package-lock.json ./
    RUN npm install --silent
    RUN npm install react-scripts@3.4.1 -g --silent
    
    # add app
    COPY . ./
    
    # start app
    CMD ["npm", "start"]
    
  2. Image の作成

    docker build -t sample-app:latest .
    
  3. コンテナの行

    一応ちゃんと実行できるか確認する

    docker run -it -p 3000:3000 {IMAGE}
    

    問題なければ http://localhost:3000 にアクセスすると先程同様 React のロゴが回転しているはず.

本題

ようやく準備が整ったので github actions を使って自動化していく.
構成としては Tag を打ったら自動で Release する 部分と release を検知して Docker build する 部分をそれぞれ定義していく. としたい所だったが、 actions/create-release@v1.0.0issueを発見 どうやら actions/create-release@v1.0.0 で作成される release 時に他の workflow から release の event が取れない? ぽい.
実際試してみると確かに release をトリガーにした別の workflow は実行されなかった. 回避方法は有るみたいだが、あんまり良さそうではなかったので 今回は release.yml にすべてまとめて定義する方針にした.

Release

  1. プロジェクトに .github/workflows/release.yml を作成

    ポイントとしては下記の用な感じ.
    長いので全体は後述するリポジトリに置いてます.

    • tag をトリガーにする

      on:
        push:
          tags:
            - "v*"
      
    • build/配下を圧縮する

      - name: Zip output
        run: |
        cd build
        zip -r release.zip .
      
    • Release の生成

      - name: Create release
        id: create_release
        uses: actions/create-release@v1.0.0
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: ${{ github.ref }}
          release_name: Release ${{ github.ref }}
          draft: false
          prerelease: false
      
    • 圧縮したファイルのアップロード

      - name: Upload Release Asset
        id: upload-release-asset
        uses: actions/upload-release-asset@v1.0.1
        env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
         with:
           upload_url: ${{ steps.create_release.outputs.upload_url }}
        asset_path: ./build/release.zip
        asset_name: asset.zip
        asset_content_type: application/zip
      

ビルドして Github Packages へのイメージ Push

  1. Dockerビルドのジョブを定義

    公式DOC をほぼコピペで動く. repository などは適宜修正が必要

    push_to_registry:
      name: Push Docker image to GitHub Packages
      runs-on: ubuntu-latest
      steps:
        - name: Check out the repo
          uses: actions/checkout@v2
        - name: Push to GitHub Packages
          uses: docker/build-push-action@v1
          with:
            username: ${{ github.actor }}
            password: ${{ secrets.GITHUB_TOKEN }}
            registry: docker.pkg.github.com
            repository: tkmpypy/github-actions-docker-sample/sample-app
            tag_with_ref: true
    

試してみる

  • 下記のような感じでgitのタグを打つ

    git tag v1.0.0
    git push origin/master v1.0.0
    
  • Githubへ移動してactionが実行されているか確認

action

  • 正常に終了したらreleaseページに移動しみる

release

  • packagesにも移動

release

参考記事