GitHubセルフホストランナー: Linuxでのセットアップ、Docker、Kubernetes
GitHubのセルフホストランナーは、GitHubのオープンソースエージェントactions/runnerを使い、自分で用意したマシン上でGitHub Actionsのジョブを実行します。ランナーはHTTPSでGitHubへアウトバウンド接続し、処理を受け取ります。2026年11月4日時点で、GitHubの課金ドキュメントではセルフホストランナーのコンピュートは無料とされており、マシンとその保守の費用は利用者が負担します。GitHubのランナーリファレンス、GitHub Actionsの課金。
私たちはGitHub Actionsランナーを販売するLizardを開発しており、料金は2026年11月4日に確認しました。
最短で始めるには、Linux VM、リポジトリ設定から取得した登録トークン、ランナーのラベルと一致するワークフローを用意します。まずはプライベートなテスト用リポジトリから始めてください。複数のランナーを運用する場合は、エフェメラルVM、KubernetesとARC、AWS向けTerraformモジュールから選びます。既存のランナーについては、セキュリティ、トラブルシューティング、マシンの費用へ進んでください。
セルフホストランナーとGitHubホステッドランナーの比較
GitHubは、ホステッドランナーのジョブごとに新しい環境を用意し、管理します。セルフホストランナーでは、マシンの用意、パッチ適用、セキュリティ対策を自分で行います。
| 自分が担うもの | セルフホスト | GitHubホステッド |
|---|---|---|
| コンピュートの請求 | 自分のマシンまたはプロバイダーの料金。GitHubのセルフホストコンピュート料金はなし(2026年11月4日) | パブリックリポジトリの標準ランナーでのジョブは無料。プライベートリポジトリの使用量は、超過料金が発生する前にプランの利用枠を消費 |
| ハードウェア | CPU、メモリ、GPU、ネットワークを自分で選択 | GitHubのランナーの種類から選択 |
| ジョブ間の環境 | 残る場合があるため、ジョブごとにクリーンなマシンを用意する必要あり | GitHubがジョブごとに新しい環境を用意 |
| 保守 | OS、ツール、イメージのパッチは自分で適用。ランナーエージェントは自動更新が可能 | GitHubが標準イメージとランナーのインフラを管理 |
| セキュリティ境界 | マシンの分離、認証情報、ネットワークアクセスを自分で制御 | 実行環境はGitHubが運用。ワークフローのセキュリティ対策は引き続き自分で担当 |
| インストール済みソフトウェア | ジョブに必要なものを自分でインストール | 標準イメージにはツールが付属。イメージのソフトウェア一覧を確認 |
出典: GitHubのセルフホストランナーの概要、ホステッドランナーの概要、課金ドキュメント。
オープンソースプロジェクトですでに無料で実行できている場合や、チームでビルド用マシンを保守したくない場合は、GitHubホステッドランナーを使い続けてください。特定のハードウェア、プライベートネットワークへのアクセスが必要な場合や、マシンを運用するだけの価値がある継続的な処理量がある場合は、セルフホストが適しています。
どの構成が適していますか?
| 構成 | 適した場面 | 自分で担う保守 |
|---|---|---|
| 単一のVM | 信頼できるジョブ向けに最初のランナーが必要 | OS、ツール、サービス、ディスクのクリーンアップ |
| エフェメラルVMまたはJIT | ジョブごとにクリーンなマシンが必要 | プロビジョニング、イメージ、ログ、VMの破棄 |
| Docker | 再現可能なエージェントイメージが欲しい | Dockerホスト、イメージの更新、ジョブの分離 |
| Kubernetes上のARC | チームがすでにKubernetesを運用している | クラスター容量、チャート、シークレット、イメージ |
| AWS上のTerraform | ランナーを自分のAWSアカウント内に置く必要がある | AWSリソース、IAM、イメージ、スケーリングの失敗 |
| Lizardなどのマネージドランナー | プロバイダーにランナーのマシン運用を任せたい | ワークフロー、権限、プロバイダーの制限 |
LinuxでGitHub Actionsのセルフホストランナーをセットアップするには?
GitHub Actionsのセルフホストランナーを追加する手順は次のとおりです。
- リポジトリでSettings → Actions → Runners → New self-hosted runnerを開きます。
actions/runnerをダウンロードし、SHA-256チェックサムを確認します。./config.sh、リポジトリのURL、そのページの登録トークンを使って登録します。./run.shを起動し、待ち受け状態になったことを確認します。- 以下のカスタムラベルと一致する
runs-on: [self-hosted, linux, x64, linux-build]でジョブを送ります。
systemdを備えたUbuntu 24.04またはDebian 12のx64 VMを使ってください。sudoを使える、root以外の一般ユーザーとしてログインします。自分が管理するプライベートなGitHubリポジトリ、インターネットへのアウトバウンド接続、ビルドに十分なディスク容量とメモリが必要です。GitHubのランナー要件は両方のOSをサポートし、ポート443でのアウトバウンドHTTPS接続を必要としています。ランナーにインバウンドのWebhookポートは不要です。
2026年11月4日、私たちはsystemdとactions/runner v2.338.2を使う新しいDebian 12 x64 VMで、ダウンロードとチェックサム確認、プライベートなテスト用リポジトリへの登録、スモークテスト用ワークフロー、サービスのインストール、削除、リポジトリ単位のJITランナーという一連の手順を検証しました。以下の出力はそのテストからの抜粋で、テスト時のログインユーザーはbuilderでした。
ランナーをダウンロードして検証する
リポジトリでSettings → Actions → Runners → New self-hosted runnerを開き、Linuxとx64を選択します。組織ランナーの場合は、組織の設定と組織オーナーのアカウントを使います。Enterprise管理者は、Enterpriseのスコープでランナーを追加することもできます。GitHubのセットアップ手順に、各スコープの説明があります。
root以外のログインユーザーで、Bashから次を実行してください。GitHubのリリースAPIから現在のリリースとそのSHA-256ダイジェストを取得し、アーカイブを検証してから展開します。
sudo apt-get update
sudo apt-get install -y ca-certificates curl jq
mkdir actions-runner
cd actions-runner
curl -fsSL https://api.github.com/repos/actions/runner/releases/latest -o release.json
RUNNER_VERSION=$(jq -er '.tag_name | ltrimstr("v")' release.json)
RUNNER_TARBALL="actions-runner-linux-x64-${RUNNER_VERSION}.tar.gz"
RUNNER_URL=$(jq -er --arg name "$RUNNER_TARBALL" \
'.assets[] | select(.name == $name) | .browser_download_url' release.json)
RUNNER_SHA=$(jq -er --arg name "$RUNNER_TARBALL" \
'.assets[] | select(.name == $name) | .digest | select(startswith("sha256:")) | ltrimstr("sha256:")' release.json)
curl -fsSL "$RUNNER_URL" -o "$RUNNER_TARBALL"
printf '%s %s\n' "$RUNNER_SHA" "$RUNNER_TARBALL" | sha256sum -c - && \
tar xzf "$RUNNER_TARBALL" && \
sudo ./bin/installdependencies.sh && \
./config.sh --help期待される結果はactions-runner-linux-x64-2.338.2.tar.gz: OKです。展開はチェックサムの検証に成功した場合にのみ実行され、失敗した場合やGitHubからダイジェストが提供されない場合は中止してください。リリースは段階的に展開されるため、必要に応じてリポジトリのセットアップページに表示されるバージョンとチェックサムを使ってください。GitHubのランナーリリース。
Debian 12では、installdependencies.shがICUの各バージョンを試す間にE: Unable to locate package libicu80などの行を出力し、その後libicu72を見つけました。これらのフォールバックの試行は今回のテストでは想定どおりでしたが、スクリプトが正常に完了することを確認してください。
登録して待ち受けを開始する
セットアップページから登録トークンをコピーします。GitHubによると、このトークンの有効期限は1時間です。これはランナーの登録トークンであり、個人アクセストークンではありません。以下のYOUR_OWNER/YOUR_REPOをリポジトリのパスに置き換え、組織のスコープではhttps://github.com/YOUR_ORGを使ってください。
read -rsp 'Registration token: ' RUNNER_TOKEN
printf '\n'
./config.sh --unattended \
--url https://github.com/YOUR_OWNER/YOUR_REPO \
--token "$RUNNER_TOKEN" \
--name linux-build-01 \
--labels linux-build
unset RUNNER_TOKEN
./run.sh期待される結果は√ Connected to GitHub、√ Runner successfully added、√ Settings Saved.で、./run.shの後にListening for Jobsが表示されます。Settings → Actions → Runnersで、接続済みで実行準備ができているときにIdleと表示されることを確認してください。最初のジョブが終わるまでは、ターミナルを起動したままにしてください。登録、ランナーの状態。
ジョブを送る
このファイルを、リポジトリのデフォルトブランチに.github/workflows/runner-check.ymlとしてコミットしてください。
name: Check self-hosted runner
on:
workflow_dispatch:
permissions:
contents: read
jobs:
check:
runs-on: [self-hosted, linux, x64, linux-build]
steps:
- name: Show the execution environment
run: |
echo "Runner accepted the job"
uname -s -m
whoamiActions → Check self-hosted runner → Run workflowを開きます。今回のテストで期待される結果はRunner accepted the job / Linux x86_64 / builderです。ログインユーザー名は異なる場合があります。このスモークテストにはチェックアウトもツールチェーンも不要なので、実際のビルドではそれらを追加してください。キューで待機したままの場合は、ジョブが待機する理由をご覧ください。
GitHubはruns-onリスト内のすべてのラベルを照合します。ランナーには登録時にself-hosted、linux、x64が付与され、linux-buildはこの例のカスタムラベルです。ラベルはランナーの特性を示しますが、ソフトウェアをインストールしたり、リポジトリへのアクセスを許可したりするものではありません。GitHubのワークフローのルーティング。
サービスとして実行し続ける
テストが終わったらCtrl-Cを押し、フォアグラウンドの./run.shリスナーが終了したことを確認してから、サービスを起動してください。そうしないと、以前のリスナーがジョブを受け取る一方で、ジャーナルにA session for this runner already exists.やConflictが表示されることがあります。今回のテストでもこの状況が発生しました。同じroot以外のログインユーザーで、ランナーのディレクトリから次を実行します。
sudo ./svc.sh install
sudo ./svc.sh start
sudo ./svc.sh status期待される結果は、svc.sh statusによるActive: active (running)の表示です。GitHubは登録後にsvc.shを作成し、systemd環境では、これらのコマンドによってログアウトや再起動後もランナーが動作し続けます。GitHubのサービス設定。
ランナーを削除する
Settings → Actions → Runnersでランナーを選び、Removeをクリックして削除トークンを取得します。ランナーのディレクトリからサービスを停止してアンインストールし、その後、登録を削除します。
sudo ./svc.sh stop
sudo ./svc.sh uninstall
read -rsp 'Removal token: ' REMOVAL_TOKEN
printf '\n'
./config.sh remove --token "$REMOVAL_TOKEN"
unset REMOVAL_TOKEN期待される結果は√ Runner removed successfully、√ Removed .credentials、√ Removed .runnerです。GitHubのランナー削除手順にはUIでの操作が記載されており、自動化する場合はリポジトリの削除トークンをリクエストできます。
ランナーグループとラベルはどう違いますか?
GitHub Actionsのランナーグループは、一連のランナーをどのリポジトリが使えるかを制御します。ラベルは、その許可された範囲からランナーを選ぶために使います。組織ランナーでは、Settings → Actions → Runner groupsを開いてグループを選び、Repository accessを必要なリポジトリに限定してください。GitHubのランナーグループによる制御。
組織ランナーでは、trusted-buildsというグループを作成してから、--url https://github.com/YOUR_ORG --runnergroup trusted-buildsで登録します。グループは事前に存在している必要があり、このフラグは上記のリポジトリスコープのセットアップには適用されません。ジョブでは、グループとラベルの両方を指定できます。
runs-on:
group: trusted-builds
labels: linux-build信頼度の低いリポジトリが使うランナーでは、リリースジョブを実行しないでください。グループは誰が処理を割り当てられるかを制限しますが、プロセスを分離したり、共有ディスクを安全にしたりするものではありません。GitHubのルーティングのドキュメントでは、グループへのアクセス権とラベルの一致の両方が必要とされています。
エフェメラルランナーとジャストインタイムランナーはどう動作しますか?
エフェメラルランナーは1つのジョブを受け取った後にGitHubによって登録解除され、この動作は--ephemeralで有効にします。VMの破棄やディスクの消去は、引き続き自分のインフラで行う必要があります。GitHubはオートスケーリングにエフェメラルランナーを推奨し、プロダクションで使う前にログを外部に保存するよう求めています。GitHubのオートスケーリングリファレンス。
同じlinux-buildラベルを持つ以前のランナーを残している場合は、sudo ./svc.sh stopでサービスを停止するか、新しいランナーとワークフローの両方で別のラベルを使ってください。そうしないと、GitHubがテストジョブを以前のランナーに送る可能性があります。新しいVMと未設定のランナーディレクトリで、新しい登録トークンを使います。
read -rsp 'Registration token: ' RUNNER_TOKEN
printf '\n'
./config.sh --unattended \
--url https://github.com/YOUR_OWNER/YOUR_REPO \
--token "$RUNNER_TOKEN" \
--name "ephemeral-$(hostname)" \
--labels linux-build \
--ephemeral
unset RUNNER_TOKEN
./run.sh失敗した場合も含め、リスナーが終了したらマシンを破棄してください。キャンセルや、ジョブを一度も受け取らないマシンにも対処してください。以前の状態が残った同じVMを再登録しても、クリーンな環境にはなりません。
APIでジャストインタイム構成を生成する
JITランナーは起動時に構成を受け取り、実行できるジョブは最大1つです。プロビジョナーは、有効期間の長いGitHub API認証情報をワーカーに置かずに、その構成を取得できます。ただしGitHubは、基盤となるハードウェアを再利用する場合にもクリーンな環境が必要だと注意しています。GitHubのJITセキュリティガイド。
この組織レベルの例では、対象の組織でSelf-hosted runners: write権限を持つ、承認済みのAPIトークンを使います。組織の管理者はテストにfine-grainedトークンを使えますが、自動化にはGitHub Appインストールトークンを使ってください。GitHubのランナーグループAPIから数値のグループIDを取得し、まずそのグループのリポジトリへのアクセスを制限してください。
Bashで、組織とグループのプレースホルダーを置き換えます。これは信頼できるテストでのみ、新しいマシンのランナーディレクトリから実行し(先にダウンロードのブロックを再実行してください)、プロダクションではAPIリクエストをプロビジョナーで実行して、返された構成だけをワーカーへ渡してください。
ORG='YOUR_ORG'
RUNNER_GROUP_ID='REPLACE_WITH_NUMERIC_GROUP_ID'
read -rsp 'GitHub API token: ' GH_API_TOKEN
printf '\n'
JIT_CONFIG=$(
jq -n --arg name "jit-$(date +%s)" --argjson group "$RUNNER_GROUP_ID" \
'{name: $name, runner_group_id: $group,
labels: ["self-hosted", "linux", "x64", "linux-build"],
work_folder: "_work"}' |
curl -fsSL -X POST \
-H 'Accept: application/vnd.github+json' \
-H "Authorization: Bearer $GH_API_TOKEN" \
-H 'X-GitHub-Api-Version: 2026-03-10' \
--data-binary @- \
"https://api.github.com/orgs/$ORG/actions/runners/generate-jitconfig" |
jq -er '.encoded_jit_config'
)
unset GH_API_TOKEN
[ -n "$JIT_CONFIG" ] && ./run.sh --jitconfig "$JIT_CONFIG"
unset JIT_CONFIGGitHubは、この組織向けJITリクエストと、単一リポジトリのテスト向けのリポジトリレベルのJITエンドポイントを文書化しており、今回のテストでは後者をrunner_group_id: 1で使用しました。--jitconfigフラグは、./run.sh --helpに記載されていなくても機能します。エンコードされた構成はシークレットとして扱い、ルーティングは引き続きスコープ、グループ、ラベルに依存することに注意してください。
JITジョブ後の期待される結果はJob check completed with result: Succeeded、√ Removed .credentials、√ Removed .runner、続いてRunner listener exit with 0 return code, stop the service, no retry needed.とExiting runner...です。
DockerでGitHubのセルフホストランナーを実行するには?
GitHubが管理するghcr.io/actions/actions-runnerイメージは、コンテナ内でエージェントを実行します。この例では2026年11月4日時点の最新ランナーリリースであるタグ2.338.2を使っており、Linux x64のマニフェストは確認しましたが、このイメージでDockerジョブは実行していません。
まずDockerのUbuntu向け手順またはDebian向け手順に従い、Docker Engineをインストールしてください。このコマンドはsudoを使いますが、代替となるDockerのdockerグループの設定はroot相当のアクセス権を付与します。
JITリクエストを使い、GitHubのgenerate-jitconfig APIから1ジョブ用の新しい構成を取得しますが、ローカルでのランナー起動とunset JIT_CONFIGの行は実行しないでください。返された構成がJIT_CONFIGに入った状態で、次を実行します。
sudo docker run --rm --init --platform linux/amd64 \
--entrypoint /home/runner/run.sh \
ghcr.io/actions/actions-runner:2.338.2 \
--jitconfig "$JIT_CONFIG"
unset JIT_CONFIGスモークテスト用ワークフローを、コンテナのラベルを指定して送ってください。コンテナはイメージ内のrunnerユーザーとして実行され、永続的なワークスペースは接続せず、終了時に削除されます。GitHubのイメージのソースに含まれるツールが記載されているので、ビルドの依存関係は派生イメージに追加してください。
エージェントをDocker内で実行することと、ワークフローのcontainer:設定でジョブのステップをDocker内で実行することは異なります。GitHubでは、Dockerコンテナアクションとサービスコンテナに、Linuxと動作するDocker環境が必要です。上記のコマンドは、入れ子のコンテナジョブ用のDockerデーモンを設定しません。GitHubのコンテナジョブ。
ホストのDockerソケットをマウントすると、ジョブのコードからそのデーモンを制御でき、ホストのファイルシステムが露出する可能性があります。Docker-in-Dockerは特権コンテナを必要とすることが多く、専用のディスク、ネットワーク、クリーンアップの計画が必要です。どちらの方法でも、通常の共有Dockerホストが悪意のあるプルリクエストに対して安全になるわけではありません。信頼できない処理には使い捨てVMによる分離境界を使い、Dockerのデーモンのセキュリティガイドを確認してください。
Actions Runner ControllerでKubernetes上のランナーをオートスケールするには?
Actions Runner Controller (ARC)は、セルフホストのGitHub Actionsランナー向けのオープンソースKubernetesコントローラーで、GitHubとコミュニティのコントリビューターが保守しています。キューに入ったジョブ用にランナーPodを作成し、minRunnersとmaxRunnersの設定範囲内でランナー群をスケールし、設定すればゼロまで縮小できます。チームがすでにKubernetesを運用している場合に適しており、GitHubのARCクイックスタートにはクラスターとHelm 3が必要です。ARCのアーキテクチャ。
コントローラーを専用の名前空間にインストールします。
helm install arc \
--namespace arc-systems \
--create-namespace \
oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set-controller
kubectl create namespace arc-runnersこの組織スコープの例では、組織のSelf-hosted runners: read and writeとリポジトリのMetadata: read-onlyの権限を持つGitHub Appを作成し、インストールします。その秘密鍵をローカルにgithub-app.pemとして保存します。リポジトリスコープでの登録には、Administration: read and writeも必要です。GitHubのARC認証手順に従ってください。
App IDとインストールIDを置き換え、ランナーの名前空間にシークレットを作成します。
kubectl create secret generic arc-github-app \
--namespace arc-runners \
--from-literal=github_app_id=YOUR_APP_ID \
--from-literal=github_app_installation_id=YOUR_INSTALLATION_ID \
--from-file=github_app_private_key=./github-app.pem次をrunner-values.yamlとして保存します。この例ではアイドル状態のランナーをゼロ、ランナーの最大数を4に設定していますが、これは予算に応じた設定値であり、ARC製品の上限ではありません。
githubConfigUrl: https://github.com/YOUR_ORG
githubConfigSecret: arc-github-app
runnerScaleSetName: arc-linux
minRunners: 0
maxRunners: 4ランナースケールセットをインストールし、コントローラーを確認します。
helm install arc-linux \
--namespace arc-runners \
--values runner-values.yaml \
oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set
helm list -A
kubectl get pods -n arc-systems先ほどのスモークテスト用ワークフローで、ラベルのリストを次に置き換えます。
runs-on: arc-linuxワークフローを起動し、ランナーの名前空間を監視します。
kubectl get pods -n arc-runners -wGitHubが示す期待される結果は、コントローラーが動作し、ジョブ用のランナーPodが作成されることです。ランナーPodをゼロにスケールしても、クラスターの固定費はなくなりません。これらのチャート名と設定値はGitHubのデプロイドキュメントとチャートの設定値で確認しましたが、この記事のためにクラスターをデプロイしたわけではありません。
プロダクションで使う前に、検証済みのチャートとイメージのバージョンを固定し、コントローラーとランナーのログを収集し、ビルドに合ったPodのリソースリクエストを設定してください。GitHub Appのシークレットへのアクセスを制限してください。コンテナジョブには、ARCのドキュメントにあるDocker-in-DockerまたはKubernetesコンテナモードを選び、その権限を確認してください。上記の最小構成の設定値では、どちらのモードも設定していません。
AWSでセルフホストランナーをオートスケールするには?
terraform-aws-github-runnerは、Kubernetesを使わず、自分のAWSアカウントのEC2上でセルフホストランナーをオートスケールするオープンソースのTerraformモジュールです。Webhookベースの構成で、GitHub Appを通じてジョブがキューに入ったイベントを受け取り、LambdaとSQSで需要を管理します。エフェメラルランナーとSpotインスタンスに対応しています。プロジェクトのアーキテクチャ。
自分の構成に合ったプロジェクトの例を使い、モジュールのバージョンを固定してください。VPC、サブネット、GitHub App、ランナーイメージを用意し、適用前にIAM権限とTerraformのプランを確認してください。Spotジョブの中断、プロビジョニングの失敗、取り残されたインスタンスへの対応を計画してください。請求額にはEC2、ディスク、ログ、ネットワークサービス、コントローラーのAWSリソースを含めてください。
ポリシー上、ランナーを自分のAWSアカウント内に置く必要がある場合は、この構成を選んでください。イメージへのパッチ適用や障害対応は引き続き自分のチームで行います。この記事のために、このTerraform構成をデプロイしたわけではありません。
パブリックリポジトリでセルフホストランナーを安全に使えますか?
そのままでは安全に使えません。フォークからのプルリクエストによって攻撃者が制御するコードをマシン上で実行できるため、GitHubはセルフホストランナーをプライベートリポジトリにのみ推奨しています。プライベートリポジトリでも注意が必要で、フォークとプルリクエストの作成を許可された人が、ランナー環境でコードを実行できる可能性があります。GitHubのセキュリティガイド。
公開されたプロジェクトへの外部からの貢献には、GitHubホステッドランナーから始めるほうが安全です。このチュートリアルの永続VMをパブリックリポジトリに接続しないでください。信頼できないコードをどうしてもセルフホストで実行する必要がある場合は、認証情報とネットワークアクセスを制限した、分離された使い捨て環境をジョブごとに用意してください。エフェメラル登録だけでは、その分離境界にはなりません。
- SSH鍵、クラウド管理者の認証情報、プロダクションのデータをランナーのディスクに置かないでください。可能な限り、有効期間が短く、スコープを絞った認証情報を使ってください。
- 信頼度の異なるリポジトリは、ランナーグループと別々の実行環境で分けてください。カスタムラベルはアクセス制御ではありません。
- 特権を持つ
pull_request_targetワークフローで、信頼できないプルリクエストをチェックアウトして実行しないでください。イベントの権限と、フォーク由来の実行に対する承認ポリシーを確認してください。 - 内部サービスとクラウドのメタデータエンドポイントへのアクセスを制限してください。ジョブに必要なGitHubのエンドポイントと依存関係のレジストリを許可しますが、アウトバウンド接続だけでもデータの窃取は可能です。
- キャッシュは共有状態として扱ってください。後で特権ビルドが実行するデータを、信頼できないジョブに書き込ませないでください。
これらの対策は、GitHubの安全な使用に関するガイドに沿っています。通信リファレンスには、ランナーの更新、アクション、ログ、アーティファクト、キャッシュに必要なドメインが記載されています。
ランナーとそのイメージを最新に保つ
GitHubのランナーリファレンスでは、自動更新を無効にしたランナーを、パッチリリースも含めて新しいリリースから30日以内に更新するよう求めています。GitHubは古くなったランナーへのジョブの割り当てを停止し、必須の重大なセキュリティ更新では、それより早くジョブがブロックされる場合があります。GitHubの更新ポリシー。
通常、ランナーは自動更新されます。--disableupdateは、チームが期限内にランナーイメージを再ビルドする場合にのみ使ってください。エージェントの更新では、Ubuntu、Docker、ビルドツールにパッチは適用されません。実行中のジョブを中断せずに保守できるよう、マシンを置き換えるか、新しいジョブの受け入れを止めて実行中のジョブが終わるのを待ってください。
ランナーがオフライン、またはジョブが待機中なのはなぜですか?
ラベルと許可されたスコープまたはグループに一致する、オンラインでアイドル状態のランナーがないと、ジョブは待機します。オフラインのランナーは、待ち受けを停止しているか、GitHubに接続できていません。GitHubのルーティングリファレンスによると、キューで24時間を超えて待機したジョブは失敗します。
| 症状 | 最初に確認すること | 対処 |
|---|---|---|
| ランナーがOffline | マシンの状態、リスナーまたはサービス、アウトバウンドHTTPS、プロキシ、証明書 | サービスを起動し、ログとGitHubへの接続を確認 |
| ジョブに「Waiting for a runner」と表示される | runs-onのすべてのラベル、ランナーグループへのアクセス、ランナーのスコープ、一致するランナーが実行中かどうか | セレクターまたはグループポリシーを修正し、オートスケーラーとクラウドの容量を確認 |
サービスがConflictを報告する | 同じ登録のフォアグラウンドリスナーがまだ動作している | サービスを起動する前に、./run.shが終了したことを確認 |
| 登録に失敗する | トークンの有効期限、対象URL、組織のポリシー | 正しいスコープの新しい登録トークンを取得 |
| Permission denied | サービスの実行ユーザー、ワークスペースの所有権、Dockerへのアクセス | 本来の実行ユーザーの権限を修正し、ランナー全体をrootで実行することは避ける |
| No space left | ビルド成果物、Dockerレイヤー、キャッシュ、保持されたログ | ディスク使用量を確認し、ランナーの新規ジョブ受け入れを停止して実行中のジョブが終わってから、不要なデータを削除 |
| イメージが古くなってからジョブが届かなくなった | ランナーのバージョンと更新ログ | 現行のランナーで再ビルドし、古いインスタンスを置き換える |
GitHubのトラブルシューティングリファレンスは、ランナーの状態、ログ、接続、Dockerの権限を扱っています。
systemdのマシンでは、たとえば直近100行のジャーナルを確認してから、診断ファイルとディスク使用量を確認します。
sudo ./svc.sh status
sudo journalctl -u "$(cat .service)" -n 100 --no-pager
ls -lt _diag/
df -h_diagでは、Runner_ファイルにリスナーの情報、Worker_ファイルに個々のジョブの情報が記録されています。エフェメラルランナーを破棄する前に、これらを保存してください。ジョブが開始されなかった場合は最新のRunner_ログを読み、開始後に失敗した場合は、そのジョブのWorker_ログとジョブの出力を読んでください。
セルフホストランナーのマシンにはいくらかかりますか?
マシン自体と、イメージのパッチ適用、ディスクのクリーンアップ、監視、失敗したジョブへの対応といった保守の予算を確保してください。
2026年11月4日時点で、GitHubの課金ドキュメントでは、提案された課金の延期後もセルフホストのコンピュートは無料とされており、料金と付属利用枠についてはGitHub Actionsの全料金一覧をご覧ください。
例: 常時稼働するLinux VMを1台使う
2026年11月4日時点で、DigitalOceanのBasic Regular Droplet料金表には、共有 vCPU 2 基、RAM 4 GiB、SSD 80 GiB、転送量4,000 GiBで月額$24と記載されていました。課金ドキュメントによると、バンドル型のDropletsは電源を切っていても課金され続けるため、課金を止めるにはDropletを破棄する必要があります。
VMはBasic Dropletsが利用できるNYC3で1か月を通じて稼働し、プライベートリポジトリのビルドを1つずつ処理し、クレジットの適用やバンドルを超える使用量はないものとします。この予算例には、税金、バックアップ、スナップショット、追加のストレージやトラフィック、GitHubの料金、運用担当者の作業時間は含まれておらず、性能に関する主張もしていません。
この前提では、ジョブがときどき実行される場合も、常に処理している場合も、VMの料金は$24のままです。リリースで頼るようになる前に、保守担当者を決めてください。
最近のジョブ履歴を使い、アイドル容量や再試行も含めた月額請求全体を比較し、有料の使用量を比較する前にGitHubホステッドランナーの利用枠を適用してください。
マネージドランナーのほうが適しているのはどんな場合ですか?
LizardのGitHub Actionsランナーは、ジョブごとに新しいFirecracker VMでJIT構成からGitHubのactions/runnerを実行し、その後ランナーの登録を削除します。Lizardがキャッシュディスクを保持するのはプライベートリポジトリのみで、フォーク由来のジョブでこのディスクが使われることはありません。プルリクエストやほかのブランチからキャッシュを読み取ることはできますが、保存するのはデフォルトブランチでのプッシュ、スケジュール実行、手動実行のみです。
| Lizardランナー | vCPU | 製品ページに表示されるRAM | ワークフローのラベル | 1時間あたりの使用料金 |
|---|---|---|---|---|
| Small | 2 | 4 GB | lizard-small-ubuntu-2404 | $0.0162 |
| Medium | 4 | 8 GB | lizard-medium-ubuntu-2404 | $0.0324 |
| Large | 8 | 16 GB | lizard-large-ubuntu-2404 | $0.0648 |
Lizard Proは月額$19(税込)で、$19分の使用量が含まれ、これが月額最低料金となり、超過分はpay as you goです。ランナーのVM時間は、セットアップとアイドル時間も含め、秒単位で課金されます。
Lizardランナーの対応環境はUbuntu 24.04上のLinux x64のみで、利用できるのはGitHub組織に限られ、個人アカウントには対応していません。組織の管理者がLizard GitHub Appをインストールします。7日間のトライアルにはカード登録が必要で、$5分の使用量が含まれ、利用できるのはSmallランナーのみ、同時に最大4 vCPUまでで、トライアルの利用枠を使い切ると、Proを開始しない限りワークロードは一時停止します。
トライアルのジョブにはSmallのラベルを使ってください。
runs-on: lizard-small-ubuntu-2404Windows、macOS、ARMのジョブはGitHubで引き続き実行し、GPUジョブには適したプロバイダーを選んでください。ビルド時間の短さを重視するならプロバイダーをベンチマークし、必要なら自分のクラウドで実行する構成を使い、パブリックプロジェクトで要件を満たせる場合は無料のGitHubホステッドランナーを使い続けてください。マネージドランナーとほかのCIプラットフォームの比較をご覧ください。
私たちのフロントエンドのビルドではLizardのほうが安く、時間がかかったので、ビルドの実測結果とLizardランナーのセットアップを確認し、信頼できるLinuxジョブを1つ試して、実行時間、請求総額、保守の手間を比較してください。
よくある質問
GitHub Actionsのセルフホストランナーで環境変数を設定するには? たとえばactions-runner/.envにBUILD_MODE=testを記述し、sudo ./svc.sh stopとsudo ./svc.sh startでサービスを再起動します。NAME=valueをそのまま1行ずつ記述し、export、シェル展開、値を囲む引用符は使わないでください。GitHubのプロキシの手順には.envの使用方法が記載されており、ランナーのパーサーが起動時に読み込み、env.shはPATHを別途.pathに保存します。ジョブはこれらの値を読み取れるため、ジョブの設定にはワークフローのenv:を、認証情報にはGitHubのシークレットを使ってください。.envはバージョン管理に含めないでください。
GitHubのセルフホストランナーは無料ですか? 課金ドキュメントによると、2026年11月4日時点でGitHubはセルフホストのコンピュートに課金していません。マシンとその保守の費用は引き続き必要です。
セルフホストランナーにインバウンドポートの開放は必要ですか? いいえ。GitHubの通信要件ではポート443でのアウトバウンドHTTPS接続が必要で、ランナーにインバウンドのWebhookポートは不要です。
ランナーの登録トークンの有効期限はどのくらいですか? GitHubのランナーのセットアップ手順によると、1時間です。有効期限切れで登録に失敗した場合は、新しいトークンを生成してください。
AI で構築。Lizard で公開。
本番公開にプラットフォームチームは必要ありません。クラウド全体が、1 つの CLI コマンドですぐ使えます。
- サービス
- —
- アドオン
- —
- デプロイ
- —
- Sandbox の起動
- —