フロントエンドチーム向け GitHub Actions の代替ツール5選
フロントエンドチーム向けのGitHub Actions代替ツール5つを比較。CircleCI、Buildkite、Jenkins、Woodpecker CI、Daggerの設定例と選び方を紹介します。
フロントエンドチームにとって有力な GitHub Actions の代替ツールは次のとおりです。フルホスト型 CI なら CircleCI、ホスト型のコントロールプレーンとホスト型またはセルフホスト型のエージェントを組み合わせるなら Buildkite、完全セルフホスト型 CI なら Jenkins と Woodpecker CI、ラップトップでもどの CI でも同じように動く「コードとしてのパイプライン」なら Dagger です。
乗り換えを検討するきっかけは、たいてい次のいずれかです。ランナーの実行時間(分)で膨れ上がった請求書、キューで待たされ続けるプルリクエスト、自分のマシンでは成功するのに GitHub のランナー上でだけ失敗するワークフロー。本記事は、読者が GitHub Actions のワークフローモデルを理解していることを前提としています。5つの選択肢を、どのようなチームに向いているか、ジョブがどこで実行されるか、Node ベースのフロントエンドで install・lint・test・build を行うジョブがどのような設定になるか、という3つの観点で比較します。
重要なポイント
- すべての CI ジョブが
npm ci、npm run lint、npm test、npm run buildを呼び出すだけであれば、CI ツールの乗り換えは YAML を数行書き換えるだけで済みます。パイプラインのロジック自体を書き直す必要はありません。 - Buildkite はオーケストレーションをホストし、ジョブはエージェント上で実行されます。エージェントには Buildkite がホストする Linux、Buildkite がホストする macOS(有料プランのみ)、または自チームで運用するマシンを使えます。
- CircleCI は
.circleci/config.ymlで設定するホスト型 CI で、Free を含むすべてのプランでセルフホストランナーをサポートしています。 - Jenkins と Woodpecker はセルフホスト型です。従量課金がなくなる代わりに、サーバー費用と保守の負担が発生します。
- Dagger は CI サービスではありません。ローカルでも、既存のどの CI の中でも実行できるパイプラインのコードです。
フロントエンドチームが GitHub Actions の代替を探す理由
フロントエンドチームが GitHub Actions から離れる理由は、主に次の4つです。ホストランナーの実行時間コストが高すぎる、ホストランナーがキューで待たされる、自社のハードウェア上でエージェントを動かす必要がある、そして CI/CD パイプラインをローカルで再現できない、というものです。移行する前に、2つ目の理由に当てはまるかどうかを確認してください。ホストランナーのキュー待ちだけが問題なら、ツールを変えなくても GitHub Actions のセルフホストランナーで解決できる可能性があります。GitLab CI/CD は、リポジトリごと移行する場合に主な検討対象となります。セットアップについては GitLab CI/CD パイプラインで解説しています。
公平に比較するため、ビルドロジックを package.json に集約し、どの CI ツールからも同じスクリプトを呼び出すようにします。
{
"scripts": {
"lint": "eslint .",
"test": "vitest run",
"build": "vite build"
}
}
コマンドは、お使いのフレームワークに合わせて置き換えてください。以下の各例では、CI の設定が担う役割は1つだけです。npm ci を実行し、続いてこれら3つのスクリプトを実行します。
Buildkite
Buildkite は、オーケストレーションはホスト型にしたいものの、ジョブを実行するマシンは自分たちで管理したいチームに向いています。Buildkite は、自分で運用するエージェントと Buildkite がホストするエージェントの両方のモデルに対応しています。Buildkite がホストする Linux エージェントは Free を含むすべてのプランで利用できますが、Free では小さいマシンサイズに限られます。Buildkite がホストする macOS エージェントを使うには、Pro または Enterprise プランが必要です。セルフホスト型のエージェントはBuildkite をポーリングしてジョブを取得するため、インバウンドのポートを開放する必要はありません。Buildkite は無料アカウントから始められます。
# .buildkite/pipeline.yml
steps:
- label: "Install, lint, test, build"
commands:
- npm ci
- npm run lint
- npm test
- npm run build
plugins:
- docker#v5.14.0:
image: "node:<your-node-version>"
Docker プラグインによってコマンドが Node イメージ内で実行されるため、エージェントに必要なのは Docker だけです。エージェントに Node がすでにインストールされている場合は、plugins ブロックを削除してかまいません。
結論: Buildkite は、CI サーバーを運用せずに、コンピューティングリソースを自分たちで保有したい場合に最適です。ただし、ホスト型エージェントを使わない限り、エージェント群の管理は自分たちで行う必要があります。
CircleCI
CircleCI は、インフラ運用を最小限に抑えたフルホスト型サービスを求めるチームに向いています。CircleCI はホスト型を基本としつつ、Free を含むすべてのプランでセルフホストランナーも提供しています。デフォルトでは、コードは CircleCI のインフラ上で実行されます。CircleCI の設定ファイルの概要では、最新バージョンは 2.1 とされています。
# .circleci/config.yml
version: 2.1
jobs:
build:
docker:
- image: cimg/node:<full.node.version>
steps:
- checkout
- run: npm ci
- run: npm run lint
- run: npm test
- run: npm run build
workflows:
ci:
jobs:
- build
cimg/node は、プロジェクトで使用している Node のフルバージョンに固定してください。CircleCI は依存関係のキャッシュにも対応していますが、例を簡潔にするためここでは省略しています。CircleCI への最初のプッシュが失敗する原因として多いのが YAML の記述ミスです。コミット前に OpenReplay YAML バリデーターでファイルをチェックし、構文エラーを検出しておくとよいでしょう。
結論: CircleCI は、GitHub Actions に最も近い感覚で置き換えられるツールです。実行時間やキューが問題でありながら、サーバーは運用したくない場合に適しています。
Jenkins
Jenkins は、オンプレミスに関する厳格な要件があり、なおかつ保守に時間を割ける担当者がいるチームに向いています。Jenkins はセルフホスト専用です。ソフトウェア自体は無料のオープンソースですが、コストは従量課金から、チームが保守するサーバー、プラグイン、アップグレードへと移ります。パイプラインは、宣言型 Pipeline 構文で記述した Jenkinsfile で管理します。
pipeline {
agent any
stages {
stage('Install') { steps { sh 'npm ci' } }
stage('Lint') { steps { sh 'npm run lint' } }
stage('Test') { steps { sh 'npm test' } }
stage('Build') { steps { sh 'npm run build' } }
}
}
agent any は、ジョブを受け取るどのエージェントにも Node がインストールされていることを前提としています。
結論: Jenkins を選ぶのは、セルフホストが必須要件である場合に限りましょう。ほとんどのフロントエンドチームにとっては、保守にかかるコストが節約できる実行時間のコストを上回ります。
Woodpecker CI
Woodpecker CI は、なじみのある YAML で書ける軽量なセルフホスト型 CI を求める小規模チームに向いています。Woodpecker CI はセルフホスト型で、ワークフロー構文で定められているとおり、各ステップのコマンドはそのステップで指定したコンテナ内で実行されます。ワークフローは .woodpecker/ ディレクトリに、1ファイルにつき1ワークフローの形で配置できます。
# .woodpecker/ci.yaml
steps:
- name: install
image: node:<your-node-version>
commands:
- npm ci
- name: lint
image: node:<your-node-version>
commands:
- npm run lint
- name: test
image: node:<your-node-version>
commands:
- npm test
- name: build
image: node:<your-node-version>
commands:
- npm run build
処理を4つのステップに分けても、インストールが4回行われるわけではありません。ステップはデフォルトで順番に実行され、チェックアウトしたワークスペースがすべてのステップにマウントされるため、install で作成された node_modules フォルダは build の時点でも残っています。woodpecker-cli と対応するバックエンドをインストールしておけば、プッシュ前に woodpecker-cli exec でワークフローをローカル実行できます。
結論: セルフホストするなら、Woodpecker CI は Jenkins よりシンプルな選択肢です。ただし、サーバーとエージェントは自分たちで運用する必要があります。
Dagger:CI サービスではなく、コードとしてのパイプライン
Dagger はホスト型の CI サービスではなく、CI サービスの代わりになるものでもありません。Dagger SDK を使ってパイプラインをコードとして記述し、同じコードをラップトップ上でも、GitHub Actions を含むあらゆる CI システム内でも実行できます。SDK ドキュメントでは、Go、Python、TypeScript、Java、PHP、Elixir に加え、Dagger 独自のスクリプト言語である Dang が扱われています。以下は、dagger init --sdk=typescript --name=frontend-ci で作成したモジュールを使い、同じジョブを TypeScript で記述した例です。
import { dag, Directory, object, func } from "@dagger.io/dagger"
@object()
class FrontendCi {
@func()
async check(source: Directory, nodeVersion: string): Promise<string> {
return await dag
.container()
.from(`node:${nodeVersion}`)
.withMountedDirectory("/src", source)
.withWorkdir("/src")
.withExec(["npm", "ci"])
.withExec(["npm", "run", "lint"])
.withExec(["npm", "test"])
.withExec(["npm", "run", "build"])
.stdout()
}
}
ローカルでは dagger call check --source=. --node-version=<your-node-version> で実行します。既存の CI ジョブでは、これと同じコマンドを実行するだけです。ローカル実行が成功すれば、CI でもまったく同じコンテナステップが実行されます。その代わり、チームは SDK とエンジンをもう1つ習得する必要があります。
これらのコマンドは Dagger 0.x 向けです。2026年10月にベータ版が発表された Dagger 1.0 ではコマンド名が変更され、モジュールの作成は dagger module init、dagger call は dagger api call になります。TypeScript のコード自体は変わりません。
GitHub Actions の代替ツールはどう選ぶべきか
最適な GitHub Actions の代替ツールは、ジョブをどこで実行したいかによって決まります。
- 運用不要のフルホスト型 CI が欲しい場合は、 CircleCI を使いましょう。設定内容が現在のものとほぼ対応します。
- 自社またはベンダーがホストするマシン上でホスト型のオーケストレーションを使いたい場合は、 Buildkite を使いましょう。特に macOS でのビルドが必要な場合に適しています。
- セルフホストが必須で、保守できる人員がいる場合は、 Jenkins を使いましょう。
- セルフホストが必須で、小規模なものが欲しい場合は、 Woodpecker CI を使いましょう。
- 本当の問題が「ローカルでは動くのに CI で失敗する」ことである場合は、 Dagger を導入し、ランナーとしては上記のいずれかのツール、または GitHub Actions 自体をそのまま使いましょう。
- 問題がキュー待ち時間だけの場合は、 まず GitHub Actions のセルフホストランナーを試しましょう。
Woodpecker の Docker バックエンドと Dagger は、いずれもコンテナランタイムを必要とします。Docker Desktop が自社のマシン環境に合わない場合、Dagger は Podman や nerdctl でも動作し、Woodpecker は Kubernetes 上で動かすことも、ローカルバックエンドでホスト上で直接実行することもできます。
どのツールを選ぶにしても、まずはすべてのビルドロジックを npm スクリプトに移すことから始めましょう。そのうえで、1つのブランチで GitHub Actions と並行して移行先のツールを試験運用し、1週間ほど結果を比較してから切り替えてください。
よくある質問
GitHub Actions のセルフホストランナーには分単位の料金がかかりますか?
いいえ。GitHub はセルフホストランナーの利用に対して分単位の料金を請求しないため、コストはランナーを動かすマシンの費用のみです。2025年12月、GitHub は2026年3月1日からセルフホストランナーに1分あたり0.002米ドルのプラットフォーム料金を課すと発表しましたが、その後、方針を再検討するとして延期しました。いずれの数字をもとにコスト比較を行う場合も、事前に GitHub Actions の課金に関するドキュメントを確認してください。
CircleCI のジョブをプッシュ前にローカルで実行できますか?
はい、一度に1つのジョブであれば可能です。CircleCI CLI の circleci local execute を使うと、単一のジョブを手元のマシンの Docker 内で実行できます。ワークフローはローカルでは実行できず、machine executor にも対応していません。バージョン 2.1 の設定ファイルの場合は、まず circleci config process で処理済みの設定をエクスポートし、そのファイルを -c フラグとジョブ名とともに circleci local execute に渡します。
Woodpecker CI は GitHub でホストされているリポジトリに対応していますか?
はい。Woodpecker は GitHub(GitHub Enterprise を含む)のほか、GitLab、Gitea、Forgejo、Bitbucket Cloud に対応しています。フォージ側で OAuth アプリケーションを登録し、そのクライアント ID とシークレットを WOODPECKER_GITHUB_CLIENT や WOODPECKER_GITHUB_SECRET などの環境変数で Woodpecker サーバーに渡します。リポジトリは GitHub に置いたままで、Woodpecker はパイプラインのステータスを GitHub に報告します。自社のインフラ上で動かすのはサーバーとエージェントだけです。
既存の GitHub Actions ワークフローから Dagger の関数を実行するにはどうすればよいですか?
actions/checkout の後に、公式の dagger/dagger-for-github アクションを使うステップを追加します。このアクションは Dagger CLI をインストールし、ランナー上で Dagger Engine を起動して関数を呼び出します。verb に call を設定し、ソースディレクトリと Node のバージョンを指定した check など、ローカルで使っているものと同じ引数を渡してください。パイプラインのロジックはモジュール内にとどまるため、将来 GitHub Actions から移行する場合も、変更が必要なのはこの薄いラッパー部分だけです。