こんにちは。現場の最前線で、日々「1秒でも速いパイプライン」を追い求めているシニアDevOpsエンジニアです。
GitHub Actionsを使っていると、「独自のツールをコンテナに閉じ込めて、どのリポジトリでも同じ環境で動かしたい」という場面に遭遇します。これが「Dockerベースのアクション」の真骨頂ですが、多くの人が最初の一歩で陥る罠があります。
それは、「実行するたびにビルドが走り、数分待たされる」というストレスです。
今日は、初心者の方でも今日から実践できる「Dockerベースのアクション」の基本セットアップから、ベテランも唸る「爆速化の極意」まで、丁寧に解説していきます。これをマスターすれば、あなたのチームの生産性は劇的に向上しますよ。
—
1. なぜ「Dockerベースのアクション」を使うのか?
GitHub Actionsには、JavaScriptで書く方法とDockerで動かす方法の2種類があります。
Dockerベースを選ぶ最大の理由は、「環境の完全な隔離」です。
- 特定のバージョンのPythonやGo、あるいは複雑な依存ライブラリが必要。
- ランナー(GitHubが用意したマシン)の環境を汚したくない。
- ローカルで動作確認したコンテナを、そのままCIで動かしたい。
これらを実現できるのがDockerベースのアクションですが、何も考えずに作ると「毎回 `docker build` が実行される」ため、非常に重くなります。ここを魔法のように速くしていきましょう。
—
2. まずは基本:Hello World構成
まずは、最もシンプルな構造を理解しましょう。必要なファイルは3つだけです。
① action.yml (アクションの定義)
アクションの「顔」となる設定ファイルです。
name: ‘Fast Docker Action Hello’
description: ‘Dockerベースのアクションの基本形です’
inputs:
who-to-greet:
description: ‘挨拶する相手の名前’
required: true
default: ‘World’
runs:
using: ‘docker’
image: ‘Dockerfile’ # ここがポイント:通常はDockerfileを指定
args:
- ${{ inputs.who-to-greet }}
② Dockerfile (環境の定義)
ここでは、軽量な `alpine` をベースにするのが鉄則です。
軽量なイメージを選択
FROM alpine:3.18
実行スクリプトをコピー
COPY entrypoint.sh /entrypoint.sh
実行権限を付与
RUN chmod +x /entrypoint.sh
実行
ENTRYPOINT [“/entrypoint.sh”]
③ entrypoint.sh (実行される処理)
コンテナの中で動く中身です。
!/bin/sh -l
第1引数を受け取る
echo “Hello, $1! This is running inside a Docker container.”
—
3. 【極限の知見】Dockerアクションを爆速化する2つの秘策
さて、ここからが本題です。標準的な `image: ‘Dockerfile’` 指定では、ワークフローが動くたびにビルドが発生します。これを回避する「プロの技」を伝授します。
秘策A:GitHub Container Registry (GHCR) をキャッシュソースにする
毎回ビルドするのではなく、「事前にビルドしたイメージをレジストリに置いておき、それを再利用する」のが最速への近道です。
`action.yml` を以下のように書き換えます。
runs:
using: ‘docker’
# Dockerfileではなく、事前にビルドされたイメージを直接参照する
image: ‘docker://ghcr.io/your-username/your-action-repo:latest’
これだけで、ビルド時間は「ゼロ」になり、イメージのプル時間(数秒)だけで済むようになります。
秘策B:マルチステージビルドで実行用イメージを極限まで削る
もし複雑なツールをビルドする必要があるなら、Dockerfile内で「ビルド用」と「実行用」を分けましょう。
— ステージ1: ビルド用 —
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o mytool main.go
— ステージ2: 実行用 (ここが重要!) —
FROM alpine:3.18
ビルド済みのバイナリだけをコピー(余計なSDKは含めない)
COPY –from=builder /app/mytool /usr/local/bin/mytool
ENTRYPOINT [“mytool”]
—
4. 上級テクニック:GitHub Actionsでのキャッシュ戦略
「イメージを事前にビルドしてGHCRにプッシュする」作業自体も自動化しましょう。その際、GitHub Actions専用のキャッシュバックエンド (`type=gha`) を使うと、ビルドがさらに加速します。
以下は、アクション自体のイメージを更新するためのワークフロー例です。
name: Build and Push Action Image
on:
push:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ghcr.io/${{ github.repository }}:latest
# ここが「現場の知恵」:GitHub Actionsの高速キャッシュを利用
cache-from: type=gha
cache-to: type=gha,mode=max
—
5. 最後に:なぜこれが大切なのか
「動けばいい」というCI/CDは卒業しましょう。
開発者が `git push` してからフィードバックが来るまでの時間は、短ければ短いほど、チームの集中力は維持されます。
今回紹介した 「GHCRの事前ビルド参照」 と 「マルチステージビルド」 を組み合わせれば、重たいDockerアクションも数秒で起動するようになります。
「Dockerベースのアクションは遅いから敬遠していた」という方も、この方法ならストレスなく開発できるはずです。ぜひ、あなたのプロジェクトに取り入れて、爆速の自動化ライフを楽しんでください。
もし設定で迷うことがあれば、いつでも聞いてくださいね。応援しています!