GitHub ActionsワークフローからDockerHubにイメージをプッシュする
概要
- GitHub ActionsのワークフローからDockerHubにイメージをプッシュする基本的な方法(≒ 最小限の構成)の解説
やってないこと
- コンテナイメージのセキュリティ観点などでの最適化
- コンテナイメージのビルド速度の最適化
ワークフローの流れ
- Checkout
- GitHubのリポジトリをチェックアウトする
- actions/checkoutを利用
-
git clone & git checkout
する
- Login to DockerHub
- DockerHubにログインする
- docker/login-actionを利用
docker login
- Get image tag
- コンテナイメージに付与するタグを指定する
- Set up Docker Buildx
- DockerでコンテナイメージをビルドするためにBuildxをセットアップする
- docker/setup-buildx-action
- Build and Push
- コンテナイメージをビルドしてDockerHub上のイメージリポジトリにプッシュする
- docker/build-push-action
-
docker build
またはdocker buildx build
に等しい
最終的なワークフローはFufuhu/bash_web_serverの.github/workflows/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のリポジトリから取得している。
steps:
- name: Checkout
uses: actions/checkout@v4
actions/checkout
のオプションで任意のブランチやタグ、コミットを指定することもできるがここでは実施しておらず、デフォルトブランチをチェックアウトするようにしている。
Login to DockerHub
docker/login-actionを利用して、DockerHubにログイン(docker login
)している。
- 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を取得してイメージタグとして利用するようにしている。
- 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を使ってコンテナイメージをビルドするためのセットアップをしている。
- 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.tag
とlatest
の2つのタグを付与してDockerHubに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 Variables
のActions
を選択します。
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