Raspberry Pi OS で構築する CI/CD(Forgejo Runner) - Linux 使いになりたい人向け
はじめに
この記事は Forgejo Runner という CI/CD(Continuous Integration / Continuous Delivery)用のソフトウェアについて説明しています。
Forgejo Runner は Git リポジトリ管理システム Forgejo と簡単に連携させることができるので、手軽に CI/CD 環境を構築したいと考えている場合に使ってみることを検討してみると良いでしょう。ただし、現時点ではアルファバージョンのものなので、個人で不具合も含めて楽しみながら使うものだと思ってください。
ここでは Raspberry Pi 5 の Raspberry Pi OS にインストールして動かしてみます。一般的には CI/CD のシステムでは実行時にそれなりの負荷が発生するので、負荷分散の観点から Git リポジトリ管理システムとは別マシンとして動かします。
ここでは個人用に使うものを想定しているのと、そんなにたくさんのマシンを用意するのも大変なので、Git リポジトリ管理システムと CI/CD のシステムは同じマシンで稼働させることにします。
つまり、Forgejo Runner をインストールするマシンには、事前に HTTPS/SSH 対応の Forgejo のインストールと設定がしてあるとします。
ちなみに、今回、動作確認をした Raspberry Pi 5 の仕様は次の通りです。
項目 | 内容 |
---|---|
OS | Raspberry Pi OS 2023-12-05 版 |
メモリ | 8 GB |
microSD | 16 GB |
ホスト名 | pi5 |
FQDN | pi5.local |
なお、FQDN の pi5.local
については、通常は mDNS により自動で使えるようになるものですが、Forgejo Runner は mDNS による名前解決に対応していません。そのため、これについてはインストールするマシン(ここでは pi5)の /etc/hosts
ファイルに登録しておく必要があります。その点に注意してください。
127.0.0.1 pi5.local
インストールするソフトウェア
基本は Forgejo Runner のインストールと設定となりますが、CI/CD では Docker Engine を使うことも多くあります。そのため、Docker Engine もインストールします。
ソフトウェア名 | 説明 |
---|---|
Forgejo Runner | CI/CD 用ソフトウェア |
Docker Engine | コンテナーソフトウェア |
CI/CD とは
ここで、CI/CD(Continuous Integration / Continuous Delivery)について簡単に説明しておきます。
CI/CD は、継続的インテグレーション(Continuous Integration) と 継続的デリバリー(Continuous Delivery)の略称です。ソフトウェア開発において、コード変更からリリースまでのプロセスを自動化し、迅速かつ確実に高品質なソフトウェアを提供するための手法や機能を指します。CI/CD を導入することで、ソフトウェア開発の効率化、ソフトウェア品質の向上などのメリットを得られます。
CI は、開発者がコード変更を頻繁に Git リモートリポジトリに統合し、自動テストを実行することや、それを実現する機能を指します。この機能を利用することによる主なメリットは次の通りです。
- コードの品質向上: コード変更を頻繁に統合・テストすることで、問題の早期発見・修正が可能
- 開発効率の向上: 手動による統合・テスト作業を減らすことで、単純作業による開発リソースの浪費を減少
- 開発環境の統一: 共通のリポジトリとテスト環境を使用することで、開発者間の環境差異による問題を排除
CD は、CI でテストされたコードを自動的に本番環境にデプロイすることや、それを実現する機能を指します。この機能を利用することによる主なメリットは次の通りです。
- リリース時間の短縮: 手動によるデプロイ作業を減らすことで、新しい機能を迅速にユーザーへ提供
- リリースの信頼性向上: 自動化されたデプロイプロセスにより、手動によるデプロイ作業によるミスやエラーの排除
- リスクの低減: 段階的なデプロイやロールバック機能などにより、リリースに伴うリスクを低減
有名な CI/CD ツールには、以下のようなものがあります。なお、それぞれが提供する機能やサービスについて、厳密には一致していませんが、機能的に CI/CD に関するものということで、ざっくりとまとめて表としたものです。
CI/CD ツール | 説明 |
---|---|
Jenkins | Java で実装されたオープンソースの CI/CD ツール |
GitHub Actions | GitHub 上で利用できる CI/CD ツール |
GitLab CI/CD | GitLab 上で利用できる CI/CD ツール |
CircleCI | クラウド型の CI/CD ツール |
Gloud Build | Google Cloud Platform の CI/CD ツール |
Azure DevOps | Microsoft Azure の CI/CD ツール |
CI/CD が世の中に普及するきっかけを与えたのは Jenkins で、これは CI/CD のための自動処理を実行する環境を提供するソフトウェアです。Jenkins と、Git リポジトリ管理システムが連携して、CI/CD の機能を実現することができます。
CI/CD が普及した結果、Jenkins が提供する機能は Git リポジトリ管理システムでも標準的に提供する機能となりつつあり、GitHub Actions や GitLab CI/CD といった機能が追加されるようになっています。
なお、Forgejo は GitHub を参考にして開発されているため、CI/CD のための機能は GitHub Actions と同様に Forgejo Actions という名前で提供されています。CI/CD のための Git リモートリポジトリの設定を、この Actions で指定します。
この Actions で利用する「自動処理を実行する環境」を提供するソフトウェアがランナーと呼ばれるものになります。ランナーとしては、Forgejo 公式のものは Forgejo Runner なります。Forgejo actions runners の、他のランナーについてのドキュメント で紹介されているように、他にも Gitea 用の gitea/act_runner などを使うこともできます。
Docker Engine
Docker Engine とは、コンテナーソフトウェアで、コンテナーの実行や管理をすることができます。OSS(オープンソースソフトウェア)として開発されていて、Apache License, Version 2.0 のライセンスで利用可能です。Docker Engine の人気によりコンテナーソフトウェアが普及したので、初めてコンテナーソフトウェアを使うなら、Docker Engine が良いです。
ちなみに、Docker Engine は Docker Desktop に含まれているので、Docker Dekstop を使う場合は自動で Docker Engine も使うことになります。
なお、コンテナーソフトウェアについては、OCI(Open Container Initiative)で仕様策定がされています。また、Docker Engine 以外にも Podman、Linux Containers といったコンテナーソフトウェアもあります。Docker Engine を使ってコンテナーについての基本を理解したら、これらについても調べてみると良いでしょう。コンテナーソフトウェアについて更に理解が深まるはずです。
ここでは Docker Engine のインストールと、動作確認の方法について説明します。
Docker Engine のインストール
それでは Docker Engine をインストールしましょう。Raspberry Pi OS は Debian ベースなので、arm64 対応の Docker を https://docs.docker.com/engine/install/debian/#install-using-the-repository の説明に従ってインストールします。
次のような install_docker.sh
スクリプトを用意してインストールしました。
#!/bin/sh
apt-get update
apt-get install -y ca-certificates curl gnupg
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg \
| gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
tee /etc/apt/sources.list.d/docker.list > /dev/null
apt-get update
apt-get install -y docker-ce docker-ce-cli \
containerd.io docker-buildx-plugin docker-compose-plugin
インストールスクリプトは sudo
コマンドを使って sh
コマンドで実行します。
sudo sh ./install_docker.sh
これで、Docker Engine がインストールできます。
次に pi ユーザーが docker
コマンドを実行できるようにするために、usermod
コマンドで docker グループへ pi ユーザーを追加します。
sudo usermod -aG docker pi
この変更を反映するために、一度ログアウトします。それから、pi ユーザーで再ログインしてから動作の確認をします。
Docker Engine の動作確認
最初に root での動作確認のため、sudo
コマンドを使って hello-world コンテナーを実行してみます。
sudo docker run hello-world
実行できたら、pi ユーザーで sudo
をつけずに docker
コマンドを使ってみます。このとき、設定がうまくできていないとエラーになります。
例えば、root による hello-world
コンテナーの確認を docker ps
コマンドで確認してから、それを docker rm
コマンドで削除します。実際に実行すると次のようになります。
pi@pi5:~ $ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2af0b6ab7f96 hello-world "/hello" 19 minutes ago Exited (0) 18 minutes ago zealous_keller
pi@pi5:~ $ docker rm zealous_keller
zealous_keller
Forgejo Runner インストールの事前準備
Forgejo Runner のインストールと設定をする前に、実際に CI/CD をするときに必要となるものを事前に準備しておきます。
- git の設定
- Docker イメージの用意
- デプロイキーの用意と設定
- Forgejo ソケットファイルの導入
git の設定
Git リポジトリを使用するので、git config
コマンドを使って pi ユーザーのメールアドレスとユーザー名のデフォルト設定をしておきます。ここで指定するメールアドレスとユーザー名は Git リポジトリで使うものなので、Raspberry Pi OS のものとは別のものです。
ここでは、Raspberry Pi OS のものと同じものを指定することにして、それぞれ pi@pi5.local と pi とします。
git config --global user.email pi@pi5.local
git config --global user.name pi
Docker イメージの用意
Forgejo Runner を稼働させる前に、使用する Docker イメージはあらかじめ用意しておくと、実際に利用するときの待ち時間が少なくて済みます。ここでは node:18-bookworm
と ubuntu:22.04
を使うことにして、docker pull
コマンドでローカルマシンで使えるようにしておきます。
docker pull node:18-bookworm
docker pull ubuntu:22.04
デプロイキーの用意と設定
Forgejo Runner を使って処理を実行するにあたって、Forgejo が管理する Git リポジトリからコードを取得する必要があります。そのために CI/CD ツールが SSH クローンを使えるように設定が必要です。
SSH クローンを手動で行うときの作業を思い出すとわかるはずなのですが、デプロイ用に使うリポジトリへアクセスするための SSH のキーペアと pi5.local マシンのホスト用公開鍵の値が必要だということになります。
これらの値は、Forgejo の次の機能を使ってリポジトリ用の情報として保存し、利用することになります。
- デプロイキー
- Actions のシークレット
- Actions の変数
なお、今回の説明では、これらの値を使って Forgejo Actions を使うところまではしませんが、これらを設定しておくと、次回のリポジトリーからコードを取得する Forgejo Actions がすぐに使えるようになります。
デプロイキーの用意
まず、デプロイ用のキーを ssh-keygen
コマンドで作成します。pi5.local の Git リポジトリ proj001
用に作るので -C
オプションでコメントに pi5 proj001 deploy
を指定します。また、ファイル名に proj001-deploy
を指定して、デプロイ用のキーペアだということがわかるようにします。
ssh-keygen -t ed25519 -f proj001-deploy -C "pi5 proj001 deploy"
これで、proj001-deploy
と proj001-deploy.pub
ファイルが生成されます。それぞれの値を確認して Forgejo へ登録します。
デプロイキーの設定
最初にデプロイキーを Forgejo へ登録します。デプロイキーには、デプロイ用の公開鍵を指定します。秘密鍵ではないので注意してください。ということで、proj001-deploy.pub
の内容を cat
コマンドで確認します。
pi@pi5:~ $ cat proj001-deploy.pub
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGC15l4riDBENzdAMeUSg6tC5iWIcbqLk78QLmSr05BH pi5 proj001 deploy
次に https://pi5.local:3000/pi/proj001/settings/keys を開いて、「デプロイキーを追加」をクリックします。表示された画面で、デプロイキーの内容に proj001-deploy.pub
の内容を追加します。また、タイトルにキーが区別できるように「pi5 proj001 deploy」と入力し、CI/CD の処理により Git リポジトリを更新できるように「書き込みアクセスも有効にする」のチェックも入れます。
Forgejo デプロイキーの追加画面
それから「デプロイキーを追加」をクリックすると、Forgejo の proj001 にデプロイキーが追加されます。
Forgejo 登録されたデプロイキーの一覧画面
シークレットの設定
次に、デプロイ用の秘密鍵について、 Forgejo のシークレット変数へ登録します。cat
コマンドで proj001-deploy
の内容を確認します。
pi@pi5:~ $ cat proj001-deploy
-----BEGIN OPENSSH PRIVATE KEY-----
(略)
-----END OPENSSH PRIVATE KEY-----
それから https://pi5.local:3000/pi/proj001/settings/actions/secrets を開いて、シークレット変数 DEPLOY_SSH_KEY を追加します。「シークレットを追加」をクリックして、シークレット変数を追加する画面を表示して、名称に「DEPLOY_SSH_KEY」、値にデプロイ用の秘密鍵を入力します。
Forgejo シークレットの追加画面
「了解」をクリックすると、シークレット変数 DEPLOY_SSH_KEY が Forgejo の proj001 に追加されます。
Forgejo シークレットの一覧画面
変数の設定
次に、pi5.local マシンのホスト用公開鍵について、 Forgejo の変数へ登録します。
pi5.local マシンのホスト用公開鍵は ssh-kyescan
コマンドで確認できます。デプロイ用に使うキーペアを作成するときのタイプに合わせたホスト用公開鍵の値が必要なので -t
オプションを使って指定します。
ssh-keyscan -t <キーのタイプ> <ホスト名>
今回はキーペアを ed25519
のタイプで作成していて、ホストは pi5.local
でアクセスするので、次のようなコマンドになります。
ssh-keyscan -t ed25519 pi5.local
実際にコマンドを実行するときは、次のようにします。2>&1
でエラー出力を標準出力へリダイレクトして統合し、パイプライン(|
)と grep
コマンドで ssh-ed25519
を含む行だけ抽出すると必要な情報が出力できます。
pi@pi5:~/proj001 $ ssh-keyscan -t ed25519 pi5.local 2>&1 |grep ssh-ed25519
pi5.local ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIP4Rm4y9/X1sZNCPG7nbrZsmeOZmhEYb9KDs1v2FCmhL
それから https://pi5.local:3000/pi/proj001/settings/actions/variables を開いてホストの公開鍵を変数 DEPLOY_KNOWN_HOST を追加します。「変数の追加」をクリックすると変数を登録する画面になります。名称へ「DEPLOY_KNOWN_HOST」、値へホスト用公開鍵の値を入力します。
Forgejo 変数の追加画面
「了解」をクリックすると、Forgejo の proj001 の変数に追加されます。
Forgejo 変数の一覧画面
Forgejo ソケットファイルの導入
Forgejo Runner を利用するにあたって、Forgejo の性能を高めるためにソケットファイルを導入しておきます。Forgejo では Git Hook の機能というものを使って、Git リポジトリに変更があった場合に、自分自身が提供する API を呼び出して実行するように実装がされています。
この呼び出しについて、初期設定だと HTTP/HTTPS によるネットワーク通信で実行されるのですが、ソケットファイルを導入することで内部プロセス通信による処理にすることができます。ネットワーク通信よりも、ソケットファイル経由での内部プロセス通信の方が高速で安定するはずなので、こちらが使われるように設定します(と、断定的に書きましたが、きちんとは調べていません。そのはずです)。
Forgejo ソケットファイルを導入するには /etc/systemd/system/forgejo.main.socket
ファイルを用意します。forgejo サービスの一部として設定するので、このファイルを用意する前に、forgejo サービスを止めておきます。
sudo systemctl stop forgejo
それから、次の内容でファイルを作成します。
[Unit]
Description=Forgejo Web Socket
PartOf=forgejo.service
[Socket]
Service=forgejo.service
ListenStream=/run/forgejo/forgejo.sock
NoDelay=true
[Install]
WantedBy=sockets.target
次に forgejo サービスの設定 /etc/systemd/system/forgejo
を変更します。設定のカスタマイズをするので、systemctl edit
コマンドを使って変更の指定をします。サービス名(.service
は省略可能)を指定すると、指定したサービスのカスタマイズができます。
systemctl edit <サービス名>
実際の作業では管理者権限が必要なので、sudo
コマンドと組み合わせて実行します。EDITOR
環境変数を指定しない場合は次のようになります。
sudo systemctl edit forgejo
systemctl edit
コマンドで forgejo サービスのカスタマイズのためのエディターを起動したら、次のように追加設定する内容を指定します。ちなみに、この場合、編集対象のファイルは /etc/systemd/system/forgejo.service.d/override.conf
となります。
[Unit]
After=forgejo.main.socket
Requires=forgejo.main.socket
[Service]
RuntimeDirectory=forgejo
Forgejo ソケットファイル用の設定については、もともとの forgejo.service
のコメントにあったものをそのまま使っています。つまり、そう指定すると動くということなので従っています。
一応、簡単に説明しておくと、[Unit]
のセクションで指定しているのは、forgejo.main.socket
で指定してあるソケット(ここでは /run/forgejo/forgejo.sock
)がサービスには必要で、その設定ファイルを読み込んでから、このサービスを起動するというものです。
また、[Service]
のセクションで RuntimeDirectory=forgejo
を指定することで /run/forgejo
ディレクトリーにソケットファイル forgejo.sock
を用意して使えるようになります。使用するソケットファイルのパスは /etc/systemd/system/forgejo.main.socket
ファイルで指定した ListenStream=/run/forgejo/forgejo.sock
によって決まります。
ファイル編集が終わったら保存してエディターを終了します。念の為、ファイルの内容を cat
コマンドで確認しておきます。
pi@pi5:~ $ cat /etc/systemd/system/forgejo.service.d/override.conf
[Unit]
After=forgejo.main.socket
Requires=forgejo.main.socket
[Service]
RuntimeDirectory=forgejo
追加指定した設定が有効になっていることは systemctl show
コマンドで確認できます。そのまま使うと設定が全部表示されるので、パイプラインと grep
コマンドで設定を絞り込んで表示して確認します。ここでは After と RuntimeDirectory を grep
コマンドのキーワードに指定して確認します。
pi@pi5:~ $ sudo systemctl show forgejo|grep After
RemainAfterExit=no
After=network.target systemd-journald.socket system.slice -.mount forgejo.main.socket basic.target syslog.target sysinit.target
pi@pi5:~ $ sudo systemctl show forgejo|grep RuntimeDirectory
RuntimeDirectoryPreserve=no
RuntimeDirectoryMode=0755
RuntimeDirectory=forgejo
After の設定について、forgejo.main.socket
が含まれていて、RuntimeDirectory=forgejo
の設定も追加されていれば大丈夫です。
準備ができたら forgejo.main.socket サービスを有効化します。
sudo systemctl enable forgejo.main.socket
これで、/etc/systemd/system/sockets.target.wants/
に forgejo.main.socket
のシンボリックリンクが作成されます。念の為に ls -l
コマンドで確認しておきます。
pi@pi5:~ $ ls -l /etc/systemd/system/sockets.target.wants/ | grep forgejo
lrwxrwxrwx 1 root root 39 2月 29 08:38 forgejo.main.socket -> /etc/systemd/system/forgejo.main.socket
systemctl status
コマンドで状態も確認しておくと良いでしょう。
pi@pi5:~ $ sudo systemctl status forgejo.main.socket
● forgejo.main.socket - Forgejo Web Socket
Loaded: loaded (/etc/systemd/system/forgejo.main.socket; enabled; preset: >
Active: active (running) since Sat 2024-03-02 19:30:16 JST; 1min 31s ago
Triggers: ● forgejo.service
Listen: /run/forgejo/forgejo.sock (Stream)
CGroup: /system.slice/forgejo.main.socket
3月 02 19:30:16 pi5 systemd[1]: Listening on forgejo.main.socket - Forgejo Web>
ソケット導入の用意ができたので、forgejo サービスを起動します。
sudo systemctl start forgejo
それから、systemctl status
で forgejo サービスの状態を確認し、Active: active (running)
と TriggeredBy: ● forgejo.main.socket
の表示がされていれば OK です。
pi@pi5:~ $ sudo systemctl status forgejo
● forgejo.service - Forgejo (Beyond coding. We forge.)
Loaded: loaded (/etc/systemd/system/forgejo.service; enabled; preset: enab>
Drop-In: /etc/systemd/system/forgejo.service.d
└─override.conf
Active: active (running) since Sat 2024-03-02 19:30:16 JST; 5min ago
TriggeredBy: ● forgejo.main.socket
Main PID: 3863 (forgejo)
Tasks: 10 (limit: 9255)
CPU: 3.661s
CGroup: /system.slice/forgejo.service
└─3863 /usr/local/bin/forgejo web --config /etc/forgejo/app.ini
もし、Triggers:
の表示がおかしいようなら、systemctl daemon-reload
コマンドで設定を反映してから、forgejo サービスについて systemctl stop
、systemctl start
を使って再起動して再確認をしてみてください。
sudo systemctl daemon-reload
Forgejo Runner の用意
Forgejo Runner は Forgejo インスタンスへ接続して、CI/CD のための処理を実行するデーモンプロセス用のソフトウェアです。MIT ライセンスで開発されている OSS です。
Forgejo Runner を実行するホスト OS の環境をそのまま使って CI/CD 用の処理を実行することができます。また、Forgejo Runner を実行するホスト OS で Docker コンテナーを実行することができるなら、Docker コンテナーを使って CI/CD 用の処理を実行することもできます。ただし、2024-03-02 時点では bash が動作する Docker コンテナーでないと使えないようです。
Forgejo Runner のインストール
Forgejo Runner のインストールをするには、https://code.forgejo.org/forgejo/runner/releases からバイナリをダウンロードしてホストとなる OS へインストールする方法と、https://code.forgejo.org/forgejo/-/packages/container/runner/versions で公開されている Open Container Initiative(OCI)の仕様に準拠したコンテナーイメージを使う方法があります。
ここでは arm64 版のバイナリをダウンロードしてホスト OS へインストールします。次のような install_forgejo.sh
スクリプトを用意します。EB114F5E6C0DC2BCDD183550A4B61A2DC5923710
の値については、https://forgejo.org/docs/next/admin/actions/#installation-of-the-binary で提示されているスクリプトのものなので、もしそこの値が変わっているようなら、それに置き換えてください。
DL_URL=https://code.forgejo.org/forgejo/runner/releases/download
ARCH=arm64
#ARCH=amd64
VERSION=3.3.0
curl -o forgejo-runner ${DL_URL}/v${VERSION}/forgejo-runner-${VERSION}-linux-${ARCH}
chmod +x forgejo-runner
curl -o forgejo-runner.asc ${DL_URL}/v${VERSION}/forgejo-runner-${VERSION}-linux-${ARCH}.asc
gpg --keyserver keys.openpgp.org --recv EB114F5E6C0DC2BCDD183550A4B61A2DC5923710
gpg --verify forgejo-runner.asc forgejo-runner
sudo mv forgejo-runner /usr/local/bin/
このスクリプトを実行すると、最後に sudo
コマンドを実行するために pi ユーザーのパスワード入力が要求されます。パスワードを入力して実行すると /usr/local/bin/forgejo-runner
コマンドが使えるようになります。なお、途中でファイルの確認もあるので、初めてインストールするときは、1行ずつ順番に実行していくと良いでしょう。
スクリプトを実行する場合は次のようにコマンド入力します。
sh install_forgejo.sh
ちなみに、gpg
コマンドでファイルをチェックしている部分のコマンド実行結果は次のようになります。
pi@pi5:~ $ gpg --keyserver keys.openpgp.org --recv EB114F5E6C0DC2BCDD183550A4B61A2DC5923710
gpg: 鍵A4B61A2DC5923710:"Forgejo <(略)>"変更なし
gpg: 処理数の合計: 1
gpg: 変更なし: 1
pi@pi5:~ $ gpg --verify forgejo-runner.asc forgejo-runner
gpg: 2023年12月05日 02時47分01秒 JSTに施された署名
gpg: EDDSA鍵EB114F5E6C0DC2BCDD183550A4B61A2DC5923710を使用
gpg: "Forgejo <(略)>"からの正しい署名 [不明の]
gpg: 別名"Forgejo Releases <(略)>" [不明の]
gpg: *警告*: この鍵は信用できる署名で証明されていません!
gpg: この署名が所有者のものかどうかの検証手段がありません。
主鍵フィンガープリント: EB11 4F5E 6C0D C2BC DD18 3550 A4B6 1A2D C592 3710
ここでは この鍵は信用できる署名で証明されていません!
という警告が表示されていますが、公式の https://forgejo.org/docs/next/admin/actions/#installation-of-the-binary で指定されている値の EB114F5E6C0DC2BCDD183550A4B61A2DC5923710
から取得した GPG キーなので、これについては信頼しても大丈夫です。これを信頼する前提だと、"Forgejo <(略)>"からの正しい署名
と表示されていれば大丈夫だということになります。
Forgejo Actions の有効化
Forgejo Runner の用意ができたら、Forgejo Actions を有効化します。そのためには、pi5.local の /etc/forgejo/app.ini
ファイルに [actions]
セクションの追加が必要です。指定する内容は次のようになります。
[actions]
ENABLED = true
ZOMBIE_TASK_TIMEOUT = 10m
ENDLESS_TASK_TIMEOUT = 15m
ABANDONED_JOB_TIMEOUT = 30m
SKIP_WORKFLOW_STRINGS = [skip ci],[ci skip],[no ci],[skip actions],[actions skip]
この設定では、個人で使う前提で、確認もしやすくするために、タイムアウトの設定値を短めにしてあります。デフォルトの値は https://codeberg.org/forgejo/forgejo/src/branch/forgejo/custom/conf/app.example.ini にある例を参照してください。
この設定ファイルへの追加変更にあたっては、エディタを使っても良いですし、次のようにコマンドを実行しても良いです。
cat << EOS | sudo tee -a /etc/forgejo/app.ini
[actions]
ENABLED = true
ZOMBIE_TASK_TIMEOUT = 10m
ENDLESS_TASK_TIMEOUT = 15m
ABANDONED_JOB_TIMEOUT = 30m
SKIP_WORKFLOW_STRINGS = [skip ci],[ci skip],[no ci],[skip actions],[actions skip]
EOS
設定変更をしたら、forgejo サービスを systemctl
コマンドで再起動します。
sudo systemctl restart forgejo
再起動したら systemctl status
コマンドで forgejo サービスが有効になっていることを確認します。
Forgejo Runner の登録と動作確認
Forgejo で Actions の機能を有効化したら、Forgejo Runner を登録します。ここではトークン(token)を使う方法で登録します。
なお、まだ pi5.local
について /etc/hosts
へ 127.0.0.1 pi5.local
のエントリーをしていない場合は、次のコマンドを実行して hosts
ファイルを更新してから、Forgejo Runner の登録をするようにしてください。
echo -e "127.0.0.1\tpi5.local" | sudo tee -a /etc/hosts
次の順番に説明します。
- Forgejo Runner の設定ファイル
- トークンの発行
- Forgejo Runner の登録
- Forgejo Runner の動作確認
Forgejo Runner の設定ファイル
最初に forgejo-runner
コマンド用の設定ファイルとして config.yml
を作成します。初期設定ファイルを生成する forgejo-runner generate-config
コマンドがあるので、これを使います。生成された設定ファイルを、構築したい環境に合わせて編集します。
まず、HTTPS では自己署名のサーバー証明書を使っているため、接続時の検証が有効になっていると警告やエラーになってしまいます。そのため、接続時の検証については無効化する必要があります。そのため、runner
に insecure: true
の指定します。
runner:
#(略)
insecure: true
#(略)
次に、並行して実行する処理の数については、runner
で capacity: 1
と指定されています。実際に使ってみたところ 1 にしておくと、次の処理が実行されるまで待つ時間が長くなるようだったので、これを 3 へ増やします。
また、タイムアウトなどの時間については、runner
で、それぞれ timeout: 3h
、fetch_timeout: 5s/
、fetch_interval: 2s
が指定されています。ここでは動作確認もしたいので、待ち時間は短めの 15 分にしつつ、個人で使うことを考えると CI/CD 用の処理があるかどうかを確認するフェッチのタイムアウトは 30 秒、間隔は 60 秒とすることにしました。
動作確認時にうまく動かない場合、ログを確認するときに間隔が短すぎるとフェッチのログばかりになって確認しにくくなります。
次にラベルについて決めます。Forgejo Actions では使用する Runner を自動で選ぶためにラベルというものが使われます。その値を labels:
へ指定する必要があります。詳細については Forgejo Actions administrator guide labels-and-runs-on を参照してください。
ここでは、ホスト OS の環境を使って CI/CD 用の処理を実行するための self-hosted
、ホスト OS で動作する Docker Engine を使って CI/CD 用の処理を実行する docker
と node-18
のラベルを用意することにします。
ラベルの指定は、<ラベル名>:<実行環境>
というフォーマットでします。
実行環境の部分について、host
とするとホスト OS の環境をそのまま使います。正式には host://-self-hosted
のようなのですが、手元では host
で動いたのでそのままにします。
実行環境に Docker を使う場合は docker://<Docker イメージ>
という指定をします。実行環境を省略すると node:16-bullseye
のイメージが使われるようですが、Node.js 16 はすでにサポートが終了しているので、ここでは docker://ubuntu:22.04
を使うようにします。
Node.js 環境で実行したいときもあるはずなので、node-18
のラベルに対して docker://node:18-bookworm
と指定して、Node.js 18 の Docker コンテナーを使えるようにしておきます。
配列で指定するときは下記のようになります。
labels: ["self-hosted:host","docker:docker://ubuntu:22.04","node-18:docker://node:18-bookworm"]
次のように要素で指定することもできます。
labels:
- self-hosted:host
- docker:docker://ubuntu:22.04
- node-18:docker://node:18-bookworm
以上の設定を反映するためには、次のようにコマンド実行をすると良いでしょう。
/usr/local/bin/forgejo-runner generate-config > config.yml
sed -i "s/insecure: false/insecure: true/" config.yml
sed -i "s/capacity: 1/capacity: 3/" config.yml
sed -i "s/timeout: 3h/timeout: 15m/" config.yml
sed -i "s/fetch_timeout: 5s/fetch_timeout: 30s/" config.yml
sed -i "s/fetch_interval: 2s/fetch_interval: 60s/" config.yml
sed -i -e "s\
|labels: \[\]\
|labels: \
\[\
\"self-hosted:host\",\
\"docker:docker://ubuntu:22.04\",\
\"node-18:docker://node:18-bookworm\"\
\]\
|" config.yml
変更したものはいずれも runner:
にあるものなので、そこだけ抜粋すると次のような内容になります。なお、コメント行は省略しています。
runner:
file: .runner
capacity: 3
envs:
A_TEST_ENV_NAME_1: a_test_env_value_1
A_TEST_ENV_NAME_2: a_test_env_value_2
env_file: .env
timeout: 15m
insecure: true
fetch_timeout: 30s
fetch_interval: 60s
labels: ["self-hosted:host","docker:docker://ubuntu:22.04","node-18:docker://node:18-bookworm"]
これで、Forgejo Runner の設定ファイルである config.yml
ファイルの準備はおしまいです。
トークンの発行
次に、Forgejo Runner 登録用のトークンを発行します。Forgejo へ Web ブラウザでアクセスして画面を操作して発行することもできますが、コマンド実行の方が楽なので、そうします。
コマンドを実行する場合は、pi5.local の git ユーザーで forgejo actions generate-runner-token
コマンドを実行します。ただし、今回の環境では forgejo
コマンドを実行するときに使用する設定ファイルの指定なども必要なので、このままでは正しく実行できません。
forgejo actions generate-runner-token
ということで、今回は次のコマンドを git ユーザーで実行すれば良いということになります。ですが、まだ実行しないでください。
/usr/local/bin/forgejo \
--config=/etc/forgejo/app.ini \
actions generate-runner-token
現在の作業は pi ユーザーで行っているので、git ユーザーでコマンド実行するには sudo
コマンドと組み合わせる必要があります。また、ここで発行したトークンは、この後の Forgejo Runner を登録するときにも必要なので、シェル変数へ保存しておくのが楽です。
なお、シェル変数へコマンドの出力結果を保存するには <シェル変数名>=$(<コマンド>)
とします。以上のことから、シェル変数 token
へトークンを保存して、echo
コマンドで値を表示するようにしましょう。
そのコマンドは次のようになります。
token=$(sudo --user git sh -c "\
/usr/local/bin/forgejo \
--config=/etc/forgejo/app.ini \
actions generate-runner-token
")
echo ${token}
これを実行すると、次のようなトークン用の文字列が出力されます。
VhuZON1xoqfLTvJVbGDL88lSvAcz2oaLCevH5DC4
このトークンを使って、Forgejo Runner を登録します。
Forgejo Runner の登録
トークンの用意ができたら、forgejo-runner register
コマンドを使って、pi5.local で実行する Forgejo Runner を https://pi5.local:3000 で稼働する Forgejo へ登録します。
ここで、forgejo-runner register
コマンド実行時に指定するオプションがいくつかあります。
使用する設定ファイルは --config
で config.yml
を指定します。
対話的に指定することはないので --no-interactive
を指定して非対話モードとします。
登録先は --instance
に URL で https://pi5.local:3000 を指定します。
トークンは --token
で指定します。事前にシェル変数 token に入れてあるなら ${token}
を指定します。シェル変数を使わない場合は forgejo actions generate-runner-token
コマンドの実行後に出力された文字列をそのまま指定します。
最後に、登録する Forgejo Runner は区別がつくように --name
で名前を指定できます。ここでは pi5-runner
とします。
以上より、実行するコマンドは次のようになります。
/usr/local/bin/forgejo-runner register \
--config config.yml \
--no-interactive \
--instance https://pi5.local:3000 \
--token ${token} \
--name pi5-runner
実際に実行したときの結果は次のようになります。Runner を pi ユーザーで実行しているため警告が出ていますが、いまのところ root 権限が必要なコマンドを実行する予定はないので無視して大丈夫です。
pi@pi5:~ $ /usr/local/bin/forgejo-runner register \
--config config.yml \
--no-interactive \
--instance https://pi5.local:3000 \
--token ${token} \
--name pi5-runner
INFO Registering runner, arch=arm64, os=linux, version=v3.3.0.
WARN Runner in user-mode.
DEBU Successfully pinged the Forgejo instance server
INFO Runner registered successfully.
登録が成功すると、コマンドを実行したディレクトリーに .runner
ファイルが作成されます。その内容は cat
コマンドで確認しておきましょう。次のようなになるはずです。
pi@pi5:~ $ cat .runner
{
"WARNING": "This file is automatically generated by act-runner. Do not edit it manually unless you know what you are doing. Removing this file will cause act runner to re-register as a new runner.",
"id": 1,
"uuid": "af5313ae-583f-41a3-b56a-6a686aab6eeb",
"name": "pi5-runner",
"token": "3d06b21baaa3e77d70b49693b06b82cf8f257b67",
"address": "https://pi5.local:3000",
"labels": [
"self-hosted:host",
"docker:docker://ubuntu:22.04",
"node-18:docker://node:18-bookworm"
]
}
また、https://pi5.local:3000/admin/actions/runners を開いて、pi5-runner が Forgejo に登録されていることを確認しましょう。このとき、id が .runner
のものと一致していることも確認します。
Forgejo Actions ランナーの一覧画面
Forgejo Runner の動作確認
Forgejo Runner の登録ができたら、動作確認をしてみましょう。実行するには forgejo-runner daemon
コマンドを実行します。このとき、実行時のディレクトリーに .runner
ファイルが必要です。また、--config
オプションで使用する設定ファイルの指定も必要です。
/usr/local/bin/forgejo-runner --config config.yml daemon
これで、https://pi5.local:3000/admin/actions/runners のランナーの一覧にある pi5-runner が「アイドル」となればOKです。
Forgejo Runner の利用
Forgejo Runner を利用するには、リポジトリで Actions を有効にし、ワークフロー用のファイルを作成してリポジトリへ追加する必要があります。
Forgejo リポジトリの Actions 有効化
まず Forgejo リポジトリの Actions の設定を有効化します。ここでは proj001 リポジトリの設定をするので、https://pi5.local:3000/pi/proj001/settings を開きます。そこに、「Actions を有効にする」があるのでチェックします。
Forgejo proj001 リポジトリの設定で Actions を有効化
それから「設定を更新する」をクリックすると、リポジトリの画面に Actions のタブが追加されます。
Forgejo proj001 リポジトリの Actions のタブ
このリポジトリの Actions の画面では、この後に説明するワークフロー用のファイルを追加して Forgejo Runner が実行されると、結果が表示されます。結果については次の例でわかるように、失敗したときには赤色、成功したときには緑色で表示されて、すぐにわかるようになっています。
Forgejo proj001 リポジトリの Actions の画面
ワークフロー用のファイルの用意
それでは、ワークフロー用のファイルを用意して、Forgejo Actions を動かしてみましょう。なお、ここでは Actions が動作することの確認を主な目的として、ワークフロー用のファイルについての説明は簡単に済ませます。
Forgejo Runner を動作させるときの処理については、ワークフロー用のファイルをリポジトリに追加してコントロールします。ここでは、proj001
ディレクトリーに Forgejo の proj001 を SSH クローンしてあるとします。
次のように、proj001
ディレクトリの下に .forgejo/workflows
ディレクトリーを用意します。
cd proj001
mkdir -p .forgejo/workflows
次に、.forgejo/workflows/demo.yaml
ファイルへ、Forgejo Runner のホスト OS で echo
コマンドを実行するジョブの設定をします。コマンドを実行するタイミングは、リポジトリに何らかのコミットが push
されたタイミングとします。ジョブの名前は test
とします。
これを指定する demo.yaml
ファイルの内容は次のようになります。
on: [push]
jobs:
test:
runs-on: self-hosted
steps:
- run: echo All Good
on:
でコマンドを実行するタイミング、jobs:
でジョブ、runs-on:
で実行環境のラベル、steps:
で実行するコマンドを指定しています。エディタで作成しても良いですし、次のようにコマンドで作成しても良いです。
cat << EOS > .forgejo/workflows/demo.yaml
on: [push]
jobs:
test:
runs-on: self-hosted
steps:
- run: echo All Good
EOS
demo.yaml
ファイルを作成したら、git add
と git commit
コマンドを使ってdemo.yaml
ファイルをリポジトリへ追加して、それを git push
コマンドで Forgejo の Git リポジトリへ反映します。
pi@pi5:~/proj001 $ git add .forgejo
pi@pi5:~/proj001 $ git commit -m "add demo.yaml"
[main f649e78] add demo.yaml
1 file changed, 6 insertions(+)
create mode 100644 .forgejo/workflows/demo.yaml
pi@pi5:~/proj001 $ git push
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 4 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 384 bytes | 384.00 KiB/s, done.
Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
remote: . Processing 1 references
remote: Processed 1 references in total
To ssh://git@pi5.local/pi/proj001.git
8fd20b9..f649e78 main -> main
git push
コマンドを実行してからしばらくすると、forgejo-runner
コマンドが実行されます。結果は Forgejo の proj001 の Actions の画面で確認することができます。各ジョブには結果の詳細を表示するためのリンクがあります。リンクをクリックすると、次のような画面が表示されて、ジョブの詳細結果を確認することが出来ます。
Forgejo proj001 リポジトリのジョブの詳細画面
動作確認ができたら、forgejo-runner
を実行しているターミナルで、Ctrl+C を入力して停止します。
参考となる URL
最後に設定や利用方法について参考になる URL を紹介しておきます。
Discussion