こんばんは。
ずっと暑いですね。外に出ると溶けそうになります。
さて、最近はCI/CDといえばGitHub Actionsが結構有力な選択肢ですが、そういえば自分で構築したことがなかったなと思って試してみます。
前半はポチポチ触っていますが、後半に最終的なDockerfileの設定もあるので、場合によっては読み飛ばしてください。
self-hosted runnersってなんぞや
GitHub Actionsではpushやpull requestといったイベントをトリガーに任意のワークフローを実行することができます。
GitHubが用意してくれている環境を「github-hosted runners」、自分で用意する環境を「self-hosted runner」といいます。
github-hosted runnersはAzureの仮想マシンで動いているらしいですね。
パブリックリポジトリなら無制限、プライベートリポジトリだと無料枠があるようです。(Freeだと2000分/月)
GitHub Actions の課金について - GitHub Docs
self-hosted runnerはHTTPSのロングポーリングを使ってランナー側からGitHub側にアクセスしているので、ポート開放やIPアドレスの割当等が不要なあたりがとても便利です。
作るならDockerがいい
というわけで自宅のLinuxサーバにDockerを使ってself-hosted runnerを建ててみます。
手順を確認
まずは対象としたいリポジトリのSettings>Actions>Runnersから「New self-hosted runner」ボタンを押します。
自身の環境を選択します。今回の私の場合はRunner imageがLinuxでArchitectureがx64です。
LinuxでArchitecutureがよくわからない場合は「uname -a」コマンドとかを叩いてみるとよいかと思います。間違えると後で面倒なので先に確認しましょう。(ハマった人)
コンテナの準備
最初からDockerfileを書きたい気持ちもあるのですが、なんだかつまづきそうな気がするのでひとまずプレーンにコンテナを建ててコマンドを叩いていくことにします。
Dockerfile
FROM ubuntu:24.04
docker-compose.yml
version: '3.8' services: self_hosted_runner: build: . container_name: self_hosted_runner tty: true stdin_open: true
上記の2ファイルを適当なフォルダに作ったら以下のコマンドを叩いて、コンテナの起動&コンテナの中に入ります。
docker compose up -d docker exec -it self_hosted_runner /bin/bash
手順に沿って作業
基本的には画面に記載のコマンドのとおり実行していくのですが、なんだかんだあれが足りないとかこれが違うとか言われます。
インストールが必要になるのはsudoとcurlなので、先にapt-getを更新したうえでインストールしておきます。
apt-get update
apt-get install -y sudo curl
次にGitHubのページに従ってダウンロードまで済ませます。ハッシュのチェックはお好みらしいので一旦省略。(インストールするもの増えるので)
mkdir actions-runner && cd actions-runner curl -o actions-runner-linux-x64-2.317.0.tar.gz -L https://github.com/actions/runner/releases/download/v2.317.0/actions-runner-linux-x64-2.317.0.tar.gz tar xzf ./actions-runner-linux-x64-2.317.0.tar.gz
あとは設定のシェルを実行すればOKと思いきや、
./config.sh --url https://github.com/{user}/{repository} --token {token}
rootユーザじゃダメだよ的なことを言われます。
Must not run with sudo
仕方がないのでユーザを作ります。このユーザをsudoグループに入れて最初からこのユーザを使うのもありですが、今回はつけないでおきます。
useradd -m runner -s /bin/bash su runner
で、改めて実行すると
./config.sh --url https://github.com/{user}/{repository} --token {token}
依存関係が不足しているから、インストール用のシェルを叩いてと言われます。
が、何故かこれを実行しても問題が解決しません。(rootで実行とrunnerユーザにsudo権限つけて実行の両方試したけどダメでした…何故…)
Libicu's dependencies is missing for Dotnet Core 6.0
Execute sudo ./bin/installdependencies.sh to install any missing Dotnet Core 6.0 dependencies.
仕方がないので足りないと言われているLibicuを自分でインストールします。
exit # rootに戻る apt-get install -y libicu-dev su runner
今度こそ実行できるようになります。
./config.sh --url https://github.com/{user}/{repository} --token {token}
なんかこんな感じにいろいろなことを聞かれます。(Enterポチポチで良きに計らってくれます)
-------------------------------------------------------------------------------- | ____ _ _ _ _ _ _ _ _ | | / ___(_) |_| | | |_ _| |__ / \ ___| |_(_) ___ _ __ ___ | | | | _| | __| |_| | | | | '_ \ / _ \ / __| __| |/ _ \| '_ \/ __| | | | |_| | | |_| _ | |_| | |_) | / ___ \ (__| |_| | (_) | | | \__ \ | | \____|_|\__|_| |_|\__,_|_.__/ /_/ \_\___|\__|_|\___/|_| |_|___/ | | | | Self-hosted runner registration | | | -------------------------------------------------------------------------------- # Authentication √ Connected to GitHub # Runner Registration Enter the name of the runner group to add this runner to: [press Enter for Default] Enter the name of runner: [press Enter for f6e1c843bd72] This runner will have the following labels: 'self-hosted', 'Linux', 'X64' Enter any additional labels (ex. label-1,label-2): [press Enter to skip] √ Runner successfully added √ Runner connection is good # Runner settings Enter name of work folder: [press Enter for _work] √ Settings Saved.
これで設定が完了したので、あとは起動のシェルを叩けば待受状態になります。
./run.sh
√ Connected to GitHub
Runnerが作られて状態がIdleになっています。
Dockerfileにまとめよう
せっかくDockerを使っているのでまとめてみます。
RUNをどこまで繋げるものなのかよくわからない…繋げられる場合は全部繋げてしまっていいのだろうか。
Dockerfile
FROM ubuntu:24.04 RUN apt-get update \ && apt-get install -y sudo curl libicu-dev RUN useradd -m runner -s /bin/bash RUN mkdir actions-runner && cd actions-runner \ && curl -o actions-runner-linux-x64-2.317.0.tar.gz -L https://github.com/actions/runner/releases/download/v2.317.0/actions-runner-linux-x64-2.317.0.tar.gz \ && tar xzf ./actions-runner-linux-x64-2.317.0.tar.gz USER runner WORKDIR /actions-runner RUN ./config.sh \ --url https://github.com/{user}/{repository} \ --token {token} \ --unattended \ --name sample-runner CMD ["./run.sh"]
docker-compose.yml
version: '3.8' services: self_hosted_runner: build: . container_name: self_hosted_runner
これで「docker compose up -d」一発でランナーの立ち上げまでできるようになりました。
中身ほとんどないのでdocker composeじゃなくてもいいかもしれないです。
試しにWorkflowを動かしてみる
とりあえず動作確認がしたいので、すごくシンプルなワークフローを作ります。
今回は「workflow_dispatch」を指定しているので、手動でトリガーする形です。
./github/workflows/sample.yml
name: Sample on: workflow_dispatch jobs: echo: runs-on: self-hosted steps: - name: Hello world run: echo "hello, world" && whoami && date
こんな感じ。
Actionsタブにワークフローが表示されるようになります。
Run workflowで実行すると、無事に実行されたようです。
ランナー側にはこんな感じでコンソール出力されていました。
2024-07-21 14:30:52Z: Running job: echo 2024-07-21 14:31:03Z: Job echo completed with result: Succeeded
わりとすんなり感はあったけれど
環境構築はなんだかんだでハマりますね…。
でも、設定のシェルが叩けるようになったあとは「もうつながったの?」という感じのすんなりさでした。
今回はちょっとした処理を試しただけですが、実際に利用するのであればDinDを使ってコンテナを綺麗に保ったり、DooDを使って別のリソースにアクセスしたりみたいな工夫が必要になってきそうですね。
(DooDについては以前の記事があるので良ければ参考に)
正直現状だと家でCI/CDちゃんとしたいような使い方をしていないので何ともですが、外からアクセスできることを生かした面白いことができたりしないもんかなと思っています。
外出先からVPNを有効にするとかできたら便利そうかなくらい…?何かないかな。
それでは。