👻

GitHub ActionsワークフローからDockerHubにイメージをプッシュする

に公開

概要

  • GitHub ActionsのワークフローからDockerHubにイメージをプッシュする基本的な方法(≒ 最小限の構成)の解説

やってないこと

  • コンテナイメージのセキュリティ観点などでの最適化
  • コンテナイメージのビルド速度の最適化

ワークフローの流れ

  • Checkout
    • GitHubのリポジトリをチェックアウトする
    • actions/checkoutを利用
    • git clone & git checkoutする
  • Login to DockerHub
  • Get image tag
    • コンテナイメージに付与するタグを指定する
  • Set up Docker Buildx
  • Build and Push
    • コンテナイメージをビルドしてDockerHub上のイメージリポジトリにプッシュする
    • docker/build-push-action
    • docker buildまたはdocker buildx buildに等しい

最終的なワークフローはFufuhu/bash_web_server.github/workflows/main.ymlに記載しています。

全体像を示すと次のようになっています。

main.ymlのワークフロー定義の全体像
name: Build and Push Docker Image

on:
  push:
    branches: [ main ]
  workflow_dispatch:

jobs:
  build-and-push:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4

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

      - name: Get image tag
        id: get-image-tag
        run: |
          IMAGE_TAG=$(git rev-parse --short HEAD)
          echo "tag=$IMAGE_TAG" >> $GITHUB_OUTPUT

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

      - name: Build and Push
        uses: docker/build-push-action@v6
        with:
          push: true
          context: .
          file: Dockerfile
          tags: |
            fufuhu/bash_webserver:${{ steps.get-image-tag.outputs.tag }}
            fufuhu/bash_webserver:latest

name: Build and Push Docker Imageから分かる通り、Build and Push Docker Imageワークフローとして定義しています。

個別ステップの詳細

Checkout

actions/checkoutを利用して、ソースコードをGitHubのリポジトリから取得している。

Checkoutステップの記述
    steps:
      - name: Checkout
        uses: actions/checkout@v4

actions/checkoutのオプションで任意のブランチやタグ、コミットを指定することもできるがここでは実施しておらず、デフォルトブランチをチェックアウトするようにしている。

Login to DockerHub

docker/login-actionを利用して、DockerHubにログイン(docker login)している。

Login to Docker Hubステップの記述
      - name: Login to Docker Hub
        uses: docker/login-action@v3
        with:
          username: fufuhu
          password: ${{ secrets.DOCKERHUB_TOKEN }}

ログイン時のパスワードについてはDockerHubのパーソナルアクセストークンを利用している(password: ${{ secrets.DOCKERHUB_TOKEN }}部分)。
セキュリティの担保のため、GitHubのシークレットを利用している(GitHub Actions でのシークレットの使用を参照)。

DockerHubのパーソナルアクセストークンの取得方法については後述。

Get image tag

ビルドしたコンテナイメージに付与するタグを生成している。
ここでは、git rev-parse --short HEADでgitのショートコミットIDを取得してイメージタグとして利用するようにしている。

Get image tagステップの記述
      - name: Get image tag
        id: get-image-tag
        run: |
          IMAGE_TAG=$(git rev-parse --short HEAD)
          echo "tag=$IMAGE_TAG" >> $GITHUB_OUTPUT

echo "tag=$IMAGE_TAG" >> $GITHUB_OUTPUTで、ステップのoutputsとして後段のステップで参照できるようにしている。

Set up Docker Buildx

docker/setup-buildx-actionを用いてBuildxを使ってコンテナイメージをビルドするためのセットアップをしている。

Set up Docker Buildxステップの記述
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

Build and Push

docker/build-push-actionによって、Buildxを使ったコンテナイメージのビルドをしている。
tagsの配下にfufuhu/bash_webserver:${{ steps.get-image-tag.outputs.tag }}
fufuhu/bash_webserver:latestがあるように、同一イメージにsteps.get-image-tag.outputs.taglatestの2つのタグを付与してDockerHubにpushしている。

Build and Pushステップの記述
      - name: Build and Push
        uses: docker/build-push-action@v6
        with:
          push: true
          context: .
          file: Dockerfile
          tags: |
            fufuhu/bash_webserver:${{ steps.get-image-tag.outputs.tag }}
            fufuhu/bash_webserver:latest

Login to DockerHubの準備事項

Login to DockerHubでは、docker loginの実行の際に、ユーザー名とパスワードが必要。
パスワードについては、DockerHubのパーソナルアクセストークンを利用している。
このパーソナルアクセストークンは認証情報であるため、公開するのは不適切なため、GitHubのシークレットを用いて安全に利用できるようにしている。

DockerHubのパーソナルアクセストークンの取得手順

DockerHubのパーソナルアクセストークンは、Docke Hubにログインしてから取得する必要があります。

Docker Hubにログインしたら、右上のメニューを開いてMy profileを選択します。

左側メニューからPersonal Access Tokenを選択します。

Generate new access tokenボタンをクリックします。

名前とAccess Permissionを設定します。
Access PermissionにはRead & Writeを指定します。

画面下部のGenerateボタンをクリックすると、パーソナルアクセストークンが生成されます。

dckr_pat_で始まるトークンを保存しておきます。

パーソナルアクセストークンのGitHub Secretへの保存

次に、Login to DockerHubステップでDocker Hubのパーソナルアクセストークンを安全に参照できるように、GitHubのシークレットにパーソナルアクセストークンを保存します。

GitHubリポジトリのSettingsタブを選択します。

Secrets and VariablesActionsを選択します。

New Repository Secretボタンをクリックします。

シークレットの名前にDOCKERHUB_TOKENを指定し、シークレットにパーソナルアクセストークンの値を指定します。

Add secretボタンをクリックすれば、シークレットの作成は完了です。

あとは、GitHub ActionワークフローとしてBuild and Push Docker Imageを実行すれば良いです。

ワークフローのトリガー設定
on:
  push:
    branches: [ main ]
  workflow_dispatch:

ワークフローのトリガーとしてはmainブランチへのコミットのプッシュ(push.branches)、またはGitHub ActionのUIから明示的に呼び出せるようになっています(workflow_dispatch)。

Discussion