0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

自宅Proxmox上のUbuntu ServerをGitHub ActionsのSelf-hosted Runnerにする【Dockerビルド・E2Eテストまで】

0
Posted at

自宅Proxmox上のUbuntu ServerをGitHub ActionsのSelf-hosted Runnerにする【Dockerビルド・E2Eテストまで】

はじめに

自宅のProxmox VEで動かしているUbuntu Serverを、GitHub Actionsの**Self-hosted Runner(セルフホステッドランナー)**にしてみます。

この記事では、Runnerの登録・常駐化から、GitHub Actionsでの動作確認、Dockerイメージのビルド、PlaywrightによるE2Eテストまでを紹介します。

AIAgentの登場により、コードをみないで開発することが増えました。それによりE2Eテストをする重要性はましており、GithubActionsでは課金が高額になる。そういった場合に余っているPC端末が使えるかもしれません。

対象: 自分で管理しているプライベートリポジトリで、信頼できるコードのみを実行する開発・検証用途。実行されるWorkflowはUbuntuサーバー上でコマンドを動かせるため、セキュリティには注意してください。

※ この記事は2026年10月28日時点の公式ドキュメントに基づきます。Runnerのバージョンや画面表示は更新されるため、ダウンロード・登録コマンドはGitHubが表示する最新版を使用してください。

Self-hosted Runnerとは?

GitHub Actionsのジョブを、GitHubが用意したVM(GitHub-hosted Runner)ではなく、自分で管理するマシンで実行する仕組みです。

GitHub Repository
  └─ Push / 手動実行
       └─ GitHub Actions
            └─ HTTPS(Ubuntu → GitHub、外向き443)
                 └─ 自宅 Proxmox VE
                      └─ Ubuntu Server VM
                           └─ Self-hosted Runner
                                ├─ Docker Build
                                ├─ Unit Test
                                └─ Playwright E2E Test

Runner側からGitHubに接続するため、通常、Runnerのためにルーターのポート開放は不要です。ただしUbuntuからGitHub関連サービスへ、外向きTCP 443番で通信できる必要があります。

自宅Runnerを使うメリット

  • 既存の計算資源を活用できる: Proxmoxで常時稼働しているVMをCIに使える。
  • 環境をカスタマイズできる: CPU・メモリ・ストレージやDocker、テストツールを自由に用意できる。
  • ローカルキャッシュを活用できる: 永続型RunnerならDockerイメージ・ビルドキャッシュを保持でき、条件次第で高速化できる。
  • 宅内の検証環境と連携できる: 必要な範囲だけネットワーク接続を許可すれば、検証用DBやサービスとのテストも可能。
  • GitHub ActionsのSelf-hosted Runner実行時間自体は無料: ただし電気代、ストレージ、保守などは自己負担。

デメリット・注意点

GitHub-hosted Runnerと違い、OS更新・ディスク容量・ジョブの隔離・Runnerの稼働管理は自分の責任です。またRunnerがオフラインの場合はジョブが待機します。必ずしもGitHub-hostedより高速・安価になるわけではありません。

想定環境

項目 内容
仮想化基盤 Proxmox VE
ゲストOS Ubuntu Server 24.04 LTS(22.04 LTSでも概ね同様)
CPU / メモリ 例:2〜4 vCPU / 4〜8GB(推奨の目安であり必須条件ではない)
GitHub 管理権限のあるプライベートリポジトリ
Runner Linux x64、リポジトリ単位で登録
Ubuntuへのアクセス sudo可能な管理ユーザーでSSH接続できる

今回は既存のUbuntu VMを使用します。重要な本番サービスやNAS・Proxmox管理系へアクセスできるVMなら、Runner専用VMを別に作ることを推奨します。

1. Ubuntuの事前準備

まずUbuntuにSSH接続し、OSとアーキテクチャを確認します。

cat /etc/os-release
uname -m

uname -m が x86_64 の場合、GitHubでは Linux / x64 を選びます。aarch64 の場合は ARM64 を選んでください。

必要な基本ツールを導入します。

sudo apt update
sudo apt install -y curl ca-certificates git tar gzip

Runnerをrootで動かさないため、専用ユーザーを作成します。

sudo adduser --disabled-password --gecos "" gha-runner
sudo -iu gha-runner
mkdir -p ~/actions-runner
cd ~/actions-runner

以降、Runnerのダウンロード・登録までは gha-runner ユーザーで作業します。

2. GitHubからRunnerを登録する

対象のGitHubリポジトリを開き、次の順番で進みます。

  1. Settings を開く
  2. 左メニューの Actions → Runners を選択
  3. New self-hosted runner を押す
  4. Linux / x64 を選ぶ

画面に「Download」「Configure」などのコマンドが表示されます。

Runnerアプリをダウンロードする

Ubuntuの ~/actions-runner ディレクトリで、GitHub画面に表示されるダウンロード・SHA-256検証・展開のコマンドをそのまま実行します。

# ここでGitHubの「Download」に表示されるコマンドを実行
# 1. curl でRunnerアーカイブをダウンロード
# 2. sha256sum で検証
# 3. tar で展開

Runnerのリリース番号・ダウンロードURL・SHA-256値は変わるため、この記事では固定しません。

GitHubにRunnerを登録する

続いて、GitHub画面の「Configure」に表示される ./config.sh コマンドを実行します。

# 以下は書式の例。OWNER / REPO / TOKEN は自分の値に置き換える
./config.sh \
  --url https://github.com/OWNER/REPO \
  --token YOUR_REGISTRATION_TOKEN \
  --name home-ubuntu-runner \
  --labels homelab
  • --name:GitHubに表示するRunner名
  • --labels homelab:WorkflowからこのRunnerを指定するためのカスタムラベル
  • --token:登録用の期限付きトークン(1時間で失効)。GitHubが表示するものを使う

登録トークンはQiitaの記事・スクリーンショット・実行ログに掲載しないでください。 コマンド履歴への記録も避けたい場合は、./config.sh の対話入力を利用してください。

接続を確認する

一度フォアグラウンドで起動します。

./run.sh

Connected to GitHub や Listening for Jobs が表示されれば接続成功です。GitHubの Settings → Actions → Runners にもRunnerが表示されます。

常駐化するため、Ctrl+C で停止してから exit で管理ユーザーに戻ります。

# Ctrl+C で ./run.sh を停止してから実行
exit

3. systemdで自動起動する

以下はsudo権限のある元の管理ユーザーで実行します。

cd /home/gha-runner/actions-runner
sudo ./svc.sh install gha-runner
sudo ./svc.sh start
sudo ./svc.sh status

これでUbuntu起動時にRunnerサービスも起動するようになります。

トラブル時にログを確認するには、インストールディレクトリにある .service ファイルでサービス名を調べます。

cat /home/gha-runner/actions-runner/.service
sudo journalctl -u "$(cat /home/gha-runner/actions-runner/.service)" -n 100 --no-pager

4. GitHub Actionsから動作確認する

リポジトリに .github/workflows/home-runner-test.yml を作成します。

name: Home Runner Test

on:
  workflow_dispatch:

permissions:
  contents: read

jobs:
  test:
    runs-on: [self-hosted, linux, x64, homelab]
    timeout-minutes: 10

    steps:
      - name: Show Ubuntu server information
        run: |
          echo "Hello from my Proxmox VM!"
          hostname
          uname -a
          free -h
          df -h .

GitHubの Actions → Home Runner Test → Run workflow から手動実行します。実行ログに自宅Ubuntuのホスト名やメモリ情報が表示されれば成功です。

runs-on の各ラベルはすべて一致する必要があります。ジョブが Queued のままなら、Runnerが Idle か、指定したラベルが正しいかを確認してください。

5. Dockerビルドを動かす

Dockerビルドを行うには、Ubuntu側にDocker EngineとBuildx、Docker Composeプラグインが必要です。既にDockerを利用しているVMでは、既存環境を壊さないよう、まずインストール状況を確認してください。

docker --version
docker compose version
sudo systemctl status docker --no-pager

未導入の場合は、Docker公式のUbuntu向けインストール手順に従い、公式APTリポジトリから docker-ce、docker-ce-cli、containerd.io、docker-buildx-plugin、docker-compose-plugin を導入します。

RunnerユーザーにDockerの操作権限を与える例は次のとおりです。

sudo usermod -aG docker gha-runner
cd /home/gha-runner/actions-runner
sudo ./svc.sh stop
sudo ./svc.sh start
sudo -u gha-runner -H docker version

セキュリティ上の重要事項: Docker公式によると、docker グループへの所属は実質的にroot相当の権限を与えます。既存の重要なサービスとDockerデーモンを共有する構成は避け、Runner専用VMで利用することを強く推奨します。

リポジトリのルートに Dockerfile があるなら、次のWorkflowでビルドできます。

.github/workflows/docker-build.yml

name: Docker Build

on:
  workflow_dispatch:

permissions:
  contents: read

jobs:
  build:
    runs-on: [self-hosted, linux, x64, homelab]
    timeout-minutes: 30

    steps:
      - uses: actions/checkout@v7

      - name: Build image
        run: docker build -t "my-app:ci-${GITHUB_RUN_ID}" .

      - name: Remove test image
        if: always()
        run: docker image rm "my-app:ci-${GITHUB_RUN_ID}" || true

actions/checkout でリポジトリを取得し、自宅Ubuntu上のDockerでビルドします。キャッシュが残ることはありますが、毎回必ず高速になるわけではありません。

6. PlaywrightでE2Eテストを動かす(応用)

次は、Docker Composeで検証用Webアプリを起動し、Playwright公式DockerイメージからE2Eテストを実行する例です。UbuntuホストにブラウザやNode.jsを直接インストールしなくても構成できます。

前提: リポジトリにアプリ用Dockerfile、package.json、package-lock.json、Playwrightのテストがあり、アプリはコンテナ内の 0.0.0.0:3000 で待ち受けるものとします。実際のアプリに合わせてポートやヘルスチェックURLを変更してください。

CI専用のComposeファイル

compose.ci.yml

services:
  app:
    build: .
    ports:
      - "127.0.0.1:3000:3000"

ホスト側を 127.0.0.1 に限定しているため、アプリをLAN全体に公開せずにテストできます。既存の本番用Composeファイルをそのまま使用しないようにしましょう。

Playwrightのテスト例(tests/home.spec.ts):

import { test, expect } from '@playwright/test';

test('トップページが表示される', async ({ page }) => {
  const response = await page.goto('http://127.0.0.1:3000/');
  expect(response?.ok()).toBeTruthy();
});

ここでは例としてPlaywright v1.64.1 の公式Dockerイメージを使用します。プロジェクトの@playwright/testのバージョンとDockerイメージのバージョンを必ず合わせてください。

.github/workflows/e2e.yml

name: Playwright E2E

on:
  workflow_dispatch:

permissions:
  contents: read

jobs:
  e2e:
    runs-on: [self-hosted, linux, x64, homelab]
    timeout-minutes: 45
    env:
      COMPOSE_PROJECT_NAME: ci-${{ github.run_id }}-${{ github.run_attempt }}

    steps:
      - uses: actions/checkout@v7

      - name: Start test application
        run: docker compose -f compose.ci.yml up -d --build

      - name: Wait for application
        run: |
          curl --fail --silent --show-error \
            --retry 30 --retry-connrefused --retry-delay 2 \
            http://127.0.0.1:3000/

      - name: Run Playwright E2E in Docker
        run: |
          docker run --rm --init --shm-size=1g \
            --network host \
            -e CI=1 \
            -v "$GITHUB_WORKSPACE:/src:ro" \
            -w /work \
            mcr.microsoft.com/playwright:v1.64.1-noble \
            bash -lc 'cp -a /src/. /work/ && npm ci && npx playwright test'

      - name: Cleanup
        if: always()
        run: docker compose -f compose.ci.yml down -v --remove-orphans
  • docker compose up -d --build:アプリのビルドと起動
  • curl --retry:アプリがHTTP応答できるまで確認
  • docker run ... --network host:Linuxホスト上の 127.0.0.1:3000 にPlaywrightからアクセス
  • -v "$GITHUB_WORKSPACE:/src:ro":ソースを読み取り専用で渡し、コンテナ内でコピーしてテストすることで、ホスト側にroot所有ファイルを残しにくくする
  • if: always():テスト失敗時もComposeを停止・削除

この例は信頼できるテストコード・アプリのみを対象にします。また同じUbuntu上で他のサービスが3000番ポートを使っている場合は衝突するため、ポートを変更してください。

7. よくあるトラブル

現象 確認すること
GitHubでRunnerがOffline VMの起動状態、sudo ./svc.sh status、外向きHTTPS 443、Runnerログ
Queuedから進まない runs-onのラベル、RunnerがIdleか、対象リポジトリへの登録状況
config.shで登録できない 登録トークンの有効期限、リポジトリURL、管理権限
docker.sock: permission denied gha-runnerのDocker権限、サービス再起動
Playwrightでブラウザが起動しない プロジェクトと公式DockerイメージのPlaywrightバージョン一致、メモリ不足
E2Eの接続エラー アプリの待受アドレス、ポート、起動完了、compose.ci.yml
ディスク不足 Dockerイメージ、ビルドキャッシュ、_workの蓄積

Dockerの使用量は docker system df、Runnerのログは /home/gha-runner/actions-runner/_diag/ で確認できます。既存Ubuntuが他のコンテナも動かしている場合、安易な docker system prune -a --volumes は避けてください。

8. セキュリティと運用で守りたいこと

  1. 信頼できるプライベートリポジトリだけにRunnerを登録する。 パブリックリポジトリのFork PRで任意コードが実行される構成は避ける。
  2. Runner専用ユーザー・可能ならRunner専用VMを使う。 Dockerを使うRunnerは強い権限を持つので、NASやProxmox管理ネットワークから分離する。
  3. GITHUB_TOKENは最小権限にする。 Workflowに permissions: contents: read を設定し、不要なSecretやSSH鍵をRunner上に置かない。
  4. ジョブ後のデータ残存に注意する。 永続型Runnerでは作業ディレクトリやキャッシュが残る。信頼境界が異なるジョブを混在させない。
  5. 更新と稼働状況を管理する。 Runnerアプリは通常自動更新されるが、Ubuntu・Docker・その他のツールは別途更新する。自宅停電や回線断でジョブが止まることも想定する。

複数人で共有する場合や外部コードを処理する場合は、ジョブごとに破棄するEphemeral Runner や専用VMの自動作成も検討した方が安全です。

9. Runnerを削除したい場合

一時停止だけなら、Ubuntu側で次を実行します。

cd /home/gha-runner/actions-runner
sudo ./svc.sh stop

完全に削除する場合は、GitHubの Settings → Actions → Runners → 対象Runner → Remove を開き、表示される削除手順に従ってください。必要なトークンはその画面から取得します。

まとめ

自宅Proxmox上のUbuntu ServerをSelf-hosted Runnerにすると、普段使っているVMをGitHub Actionsの実行基盤として活用できます。DockerビルドやPlaywrightのE2Eテストも実行でき、既存の計算資源・キャッシュを使えるのが魅力です。

一方、自宅サーバー上でWorkflowのコマンドが本当に実行されることが最大のリスクでもあります。まずは自分だけが管理するプライベートリポジトリで小さく試し、Dockerを使う場合や共有する場合はVM分離を検討するとよいでしょう。

参考資料(公式)

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?