Hugo へ移行したこのサイトを、GitHub Pages ではなく Raspberry Pi 5 上でビルドするようにした。
GitHub Pages 用の workflow は使わないので削除し、代わりに GitHub Actions の self-hosted runner を Raspberry Pi 5 に登録して、main ブランチへ push したタイミングで Rpi5 上の hugo コマンドを実行する構成にした。
やりたいこと
今回の目的は次の通り。
- GitHub Pages への deploy workflow をやめる
- Raspberry Pi 5 上で Hugo をビルドする
- GitHub から Raspberry Pi へ SSH ログインしなくても自動実行できるようにする
- Rpi5 を systemd サービスとして待機させ、push のたびにビルドさせる
self-hosted runner とは
GitHub Actions の self-hosted runner は、自分で用意したマシン上で Actions の job を実行する仕組み。
今回の場合は Raspberry Pi 5 が runner になる。
重要なのは、GitHub から Raspberry Pi へ SSH ログインするわけではない、という点。
Raspberry Pi 側で runner を起動しておくと、runner が GitHub に接続しに行き、GitHub Actions の job が来るのを待つ。
通信の向きは大まかに次のようになる。
Raspberry Pi 5 ---> GitHub
そのため、自宅ルーターで SSH ポートを公開したり、GitHub から Raspberry Pi にログインできるようにしたりする必要はない。
GitHub Pages workflow を削除する
もともとは .github/workflows/gh-pages.yml で GitHub Pages へ deploy していた。
このサイトでは GitHub Pages を使わないので、この workflow は削除した。
代わりに .github/workflows/rpi5-hugo-build.yml を追加した。
name: Build Hugo on Raspberry Pi 5
on:
push:
branches:
- main
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
runs-on: [self-hosted, Linux, ARM64, rpi5]
env:
HUGO_DESTINATION: ${{ vars.HUGO_DESTINATION || 'public' }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 0
- name: Check Hugo
run: hugo version
- name: Build
run: hugo --minify --cleanDestinationDir --destination "$HUGO_DESTINATION"
main に push されたとき、または GitHub Actions 画面から手動実行したときに動く。
on:
push:
branches:
- main
workflow_dispatch:
実行先は次のラベルを持つ runner。
runs-on: [self-hosted, Linux, ARM64, rpi5]
self-hosted、Linux、ARM64 は自動で付くラベルで、rpi5 は自分で追加したラベル。
Raspberry Pi 5 に runner を登録する
GitHub の対象リポジトリで次の画面を開く。
Settings
-> Actions
-> Runners
-> New self-hosted runner
画面では次のように選ぶ。
Runner image: Linux
Architecture: ARM64
すると、Raspberry Pi で実行するコマンドが表示される。
Rpi5 に SSH して、表示されたコマンドを実行する。
mkdir actions-runner
cd actions-runner
# GitHub の画面に表示された curl / tar コマンドを実行する
./config.sh --url https://github.com/<owner>/<repo> --token <表示されたtoken>
./config.sh の token は期限があるので、GitHub の runner 追加画面を開いてから作業する。
runner group と label を間違えない
登録中に次のように聞かれる。
Enter the name of the runner group to add this runner to: [press Enter for Default]
ここで rpi5 と入力すると、次のようなエラーになる。
Could not find any self-hosted runner group named "rpi5".
rpi5 は runner group ではなく label として使う。
そのため runner group は空のまま Enter でよい。
runner group: Default のまま
runner name : rpi5 など好きな名前
runner label: rpi5
追加ラベルを聞かれたら、そこで rpi5 を入力する。
Enter any additional labels (ex. label-1,label-2): [press Enter to skip]
rpi5
手動起動で確認する
登録できたら、一度手動で runner を起動する。
./run.sh
今回の環境では、次のように表示された。
√ Connected to GitHub
Current runner version: '2.335.1'
2026-07-09 14:01:47Z: Listening for Jobs
Connected to GitHub と Listening for Jobs が表示されれば、GitHub との接続はできている。
GitHub Actions 画面から workflow を手動実行すると、Raspberry Pi 側で job が走った。
2026-07-09 14:05:58Z: Running job: build
2026-07-09 14:06:23Z: Job build completed with result: Succeeded
これで Rpi5 上で Hugo build 用の job が成功した。
systemd サービスとして起動する
手動起動の ./run.sh は、端末を閉じると止まってしまう。
常時待機させるため、systemd サービスとして登録する。
まず手動起動している runner を Ctrl+C で止める。
^CExiting...
Runner listener exit with 0 return code, stop the service, no retry needed.
Exiting runner...
次にサービスをインストールして起動する。
sudo ./svc.sh install
sudo ./svc.sh start
sudo ./svc.sh status
今回の環境では、次のサービスが作成された。
/etc/systemd/system/actions.runner.usurageha-nosubject-hugo.rpi5.service
status では次のように active (running) になった。
● actions.runner.usurageha-nosubject-hugo.rpi5.service - GitHub Actions Runner (usurageha-nosubject-hugo.rpi5)
Loaded: loaded (/etc/systemd/system/actions.runner.usurageha-nosubject-hugo.rpi5.service; enabled; preset: enabled)
Active: active (running) since Thu 2026-07-09 23:07:31 JST
これで、Raspberry Pi 5 が起動していてネットワークにつながっていれば、GitHub Actions の job を受け取れる。
Hugo の出力先
workflow では HUGO_DESTINATION を使っている。
env:
HUGO_DESTINATION: ${{ vars.HUGO_DESTINATION || 'public' }}
Repository variables に HUGO_DESTINATION を設定しておくと、そのパスへ Hugo の出力を置ける。
未設定なら public に出力する。
たとえば公開用ディレクトリへ直接出力するなら、GitHub のリポジトリ設定で variable を追加する。
Settings
-> Secrets and variables
-> Actions
-> Variables
例:
HUGO_DESTINATION=/home/usura/nosubject-docker/hugo-public
ただし、workflow では --cleanDestinationDir を使っている。
hugo --minify --cleanDestinationDir --destination "$HUGO_DESTINATION"
出力先ディレクトリの中身を消してから生成するので、HUGO_DESTINATION には Hugo の公開先専用ディレクトリだけを指定する。
ホームディレクトリや作業ディレクトリ全体のような広すぎるパスは指定しない。
まとめ
GitHub Pages を使わず、Raspberry Pi 5 上で Hugo をビルドする流れは次のようになった。
- GitHub Pages 用の workflow を削除する
- Rpi5 用の GitHub Actions workflow を追加する
- Rpi5 に self-hosted runner を登録する
- runner に
rpi5ラベルを付ける ./run.shで接続確認する- GitHub Actions から手動実行して job 成功を確認する
svc.shで systemd サービス化する
これで、main に push すると Raspberry Pi 5 上で Hugo が自動ビルドされるようになった。