DockerでGitHub Actions Runnerをセルフホスト:高速・安全・コストを100%削減

Docker tutorial - IT technology blog
Docker tutorial - IT technology blog

5分で最初のランナーをデプロイする

すぐに使える「自前」のCI/CDマシンが必要ですか?いくつかのDockerコマンドを実行するだけで、個人のラップトップや月額5ドルのVPSをGitHub Actionsの強力なアシスタントに変えることができます。マシンにはすでにDockerがインストールされていることを前提とします。

ステップ1:GitHubからトークンを取得する

まず、ランナーに「通行証」を発行しましょう。

  1. GitHubのリポジトリを開きます。
  2. Settings > Actions > Runners に移動します。
  3. New self-hosted runner をクリックし、オペレーティングシステムに Linux を選択します。
  4. 設定コマンドの最後にある TOKEN をコピーします。面倒な .tar.gz ファイルのダウンロードコマンドを実行する必要はありません。Dockerを使用します。

ステップ2:Dockerコンテナを起動する

手動でインストールする代わりに、最適化されたコミュニティ製のイメージを使用します。ターミナルを開き、以下のコマンドを貼り付けてください。

docker run -d --restart always --name github-runner \
  -e REPO_URL="https://github.com/user/your-repo" \
  -e RUNNER_NAME="docker-runner-01" \
  -e RUNNER_TOKEN="あなたのトークン" \
  -v /var/run/docker.sock:/var/run/docker.sock \
  myoung34/github-runner:latest

ブラウザのSettingsタブに戻ってください。緑色の丸で Idle と表示されれば、成功です!

なぜセルフホストランナーに移行すべきなのか?

デフォルトでは、GitHubは無料アカウントに対して、仮想マシン上で月間約2,000分のビルド時間を提供しています。一見多く見えますが、継続的にテストを実行していると、あっという間に使い切ってしまいます。私がセルフホストランナーの構築を決めた3つの理由は以下の通りです。

  • 制限の突破: 2,000分のクォータを気にする必要がなくなります。追加費用なしで24時間365日ビルド可能です。
  • 大幅な高速化: GitHubの仮想マシンは通常2 vCPUと7GB RAMしかありません。私のJavaプロジェクトでテストしたところ、NVMeドライブを搭載した専用サーバーで実行すると、ビルド時間が12分から4分に短縮されました。
  • 内部ネットワークへのアクセス: インターネットにポートを開放することなく、LANやVPC内にあるデータベースやサーバーに直接デプロイできます。

なぜベアメタルではなくDockerなのか?

ランナーをOSに直接インストール(ベアメタル)するのは、サーバーを「ゴミ溜め」にする一番の近道です。数十回のビルド後、不要なライブラリや一時ファイルがディスク容量を使い果たしてしまいます。

Dockerを使用することには、3つの決定的な利点があります。

1. 常にクリーンな環境(Clean Environment)

コンテナを再起動するたびに、真っさらな環境が手に入ります。Node.jsやPythonのバージョン競合による「自分のマシンでは動くのにサーバーでは動かない」という状況が完全に解消されます。

2. 即座に拡張可能

プロジェクトが繁忙期に入り、1日に数十件のプルリクエストが発生する場合でも、コンテナの数を増やすだけで対応できます。システムは最初から設定し直すことなく、自動的に負荷を分散します。

3. Docker-in-Docker (DinD) の魔法

<a href="https://itfromzero.com/ja/docker-ja/docker-socket%e3%81%ae%e3%82%bb%e3%82%ad%e3%83%a5%e3%83%aa%e3%83%86%e3%82%a3%ef%bc%9a-var-run-docker-sock%e3%82%92%e3%83%8f%e3%83%83%e3%82%ab%e3%83%bc%e3%81%ae%e3%83%90%e3%83%83%e3%82%af%e3%83%89.html">/var/run/docker.sock</a> をマッピングすることで、コンテナ内のランナーがホストマシンのDockerを制御できるようになります。これにより、ホスト上で直接操作しているかのように、他のDockerイメージのビルド、タグ付け、プッシュをスムーズに行えます。

Docker Composeによるプロフェッショナルな管理

毎回 docker run コマンドを入力するのは非効率です。管理やバックアップを容易にするために、設定を docker-compose.yml ファイルにまとめましょう。

version: '3.8'
services:
  runner:
    image: myoung34/github-runner:latest
    restart: always
    environment:
      - REPO_URL=https://github.com/your-org/your-repo
      - RUNNER_TOKEN=ABC123XYZ
      - RUNNER_NAME=prod-runner
      - RUNNER_LABELS=linux,docker,high-perf
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ./runner-data:/data # 次回のビルドを高速化するためのデータキャッシュ

docker-compose up -d を実行するだけで、すべてが安定して自動運用されます。

実運用における「現場での教訓」

チームのためにランナーシステムを1年以上運用してきた中で、3つの重要な教訓を得ました。

1. ディスクをゴミで埋め尽くさない

Dockerイメージをビルドするたびに、古いレイヤーが急速に蓄積されます。ある週、チェックを忘れたところ、100GB of ディスクがわずか3日で一杯になってしまいました。毎日午前3時に docker system prune -f を実行するcronjobを設定し、自動的に掃除するようにしましょう。

2. パブリックリポジトリにおけるセキュリティの警告

特記事項: パブリックプロジェクトには絶対にセルフホストランナーを使用しないでください。悪意のあるユーザーが(rm -rf / のような)不正なコードを含むプルリクエストを作成した場合、あなたのランナーがそれをサーバー上で直接実行してしまいます。プライベートリポジトリのみで使用してください。

3. スマートなラベル付け

各ジョブに適切なランナーを割り当てるために、ワークフローファイル .github/workflows/main.yml でラベルを使用します。

jobs:
  deploy:
    runs-on: [self-hosted, high-perf]
    steps:
      - uses: actions/checkout@v3
      - name: アプリのビルド
        run: docker build -t my-app .

ランナーの自前運用は最初は手間がかかるように見えますが、それによって得られる自由度とパフォーマンスは、その労力に見合う価値が十分にあります。このガイドが、あなたのCI/CDプロセスの効率化に役立つことを願っています。

Share: