やりたかったこと

コードをpushするたびに自動でDockerイメージをビルドしてDocker Hubにプッシュしたかった。 毎回手動でビルドするのが面倒になってきて、GitHub Actionsで自動化してみた。

Docker Hubの認証情報をSecretsに登録する

まずDocker Hubのアクセストークンを取得する。 Docker Hub → Account Settings → Security → New Access Token で作成できる。

GitHubのリポジトリの Settings → Secrets and variables → Actions に以下を登録する:

  • DOCKERHUB_USERNAME:Docker HubのユーザーID
  • DOCKERHUB_TOKEN:取得したアクセストークン

パスワードではなく必ずAccess Tokenを使う。

ワークフローファイルを作成する

mkdir -p .github/workflows

.github/workflows/docker-push.yml を作成する:

name: Docker Build and Push

on:
  push:
    branches:
      - main

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Log in to Docker Hub
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: ${{ secrets.DOCKERHUB_USERNAME }}/my-app:latest

タグにgitのSHAを使う

latest だけだとどのコードのイメージかわからなくなる。 commitのSHAも一緒にタグとしてつけておくと追跡しやすい:

      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: |
            ${{ secrets.DOCKERHUB_USERNAME }}/my-app:latest
            ${{ secrets.DOCKERHUB_USERNAME }}/my-app:${{ github.sha }}

プルリクでビルドだけ確認したい

mainにマージする前にビルドが通るか確認したいことがある。 push: false にしておけばDocker Hubへのプッシュなしでビルドだけ実行できる:

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  build-and-push:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Log in to Docker Hub
        if: github.event_name == 'push'
        uses: docker/login-action@v3
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_TOKEN }}

      - name: Build and push
        uses: docker/build-push-action@v5
        with:
          context: .
          push: ${{ github.event_name == 'push' }}
          tags: ${{ secrets.DOCKERHUB_USERNAME }}/my-app:latest

ハマったポイント

  • Docker HubのパスワードではなくAccess Tokenを使わないと認証エラーになる
  • docker/build-push-action はDockerfileがリポジトリルートにある前提。別の場所にある場合は contextfile オプションで指定する
  • tags にユーザー名を直書きするとSecretsを変えた時に壊れる。Secretsから読むようにしておく
  • GitHub Actionsの無料枠はパブリックリポジトリは無制限、プライベートは月2000分まで

関連記事

おすすめのVPS/ドメイン/スクール