本文へスキップ
ysk-hack-log
戻る

GitHub Actionsでラズパイへ自動デプロイ|pushで自動publish&再起動【連載⑨】

「GitHub Actionsでラズパイへ自動デプロイ|pushで自動publish&再起動【連載⑨】」の記事アイキャッチ

前回(第8回) で常駐化できましたが、更新は毎回手動でpublish&再起動でした。今回は GitHub Actions で、pushしたら自動でデプロイされるようにします。

Table of contents

Open Table of contents

難所:Piは自宅NATの内側にいる

GitHub Actions のランナーはクラウド、Piは自宅ルーターの内側(公開IPなし)。クラウドから直接Piへ入るのは面倒です。そこで、Pi自身にランナーを置く「セルフホストランナー」方式が最も手軽です。ランナーは外向き通信でGitHubを見に行くので、ポート開放もグローバルIPも不要です。

セルフホストランナーとは

GitHub Actions のジョブを実際に動かす「作業員」が ランナー です。通常はGitHubが用意するクラウド上のランナーが使われますが、自分のマシン(今回はRaspberry Pi)をランナーにするのが セルフホストランナー です。

Piにランナーの常駐プログラムを入れておくと、それが GitHubへ外向きに「仕事はある?」と問い合わせ続け(ポーリング)、pushでジョブが来たら Pi自身がその場で実行します。

flowchart LR
    Runner["Piのランナー(常駐)"]
    GH["GitHub(クラウド)"]
    App["Blazorアプリ publish→再起動"]

    Runner -->|① 外向きに問い合わせ| GH
    GH -->|② ジョブを渡す| Runner
    Runner -->|③ Piの中で実行| App

STEP 1:Piにセルフホストランナーを入れる

登録手順とコマンドは、GitHubが自動生成してくれます。

  1. リポジトリの Settings → Actions → Runners → New self-hosted runner を開く
  2. Linux / ARM64 を選ぶ
  3. 画面に出るコマンドをPi上で上から順に実行する(<URL> や <TOKEN> は画面の値をそのまま使う)

手順は、大きく3ステップです。
(1)と(2)はコマンド例であり、GitHubの画面上に表示されたコマンドを正としてください。

(1) Download:Pi上にランナー本体を取得

mkdir actions-runner && cd actions-runner
curl -o runner.tar.gz -L <画面に表示されるダウンロードURL>
tar xzf runner.tar.gz

(2) Configure:このPiをリポジトリのランナーとして登録

./config.sh --url https://github.com/<user>/<repo> --token <画面のTOKEN>

config.sh は (1)で展開したフォルダーに最初から入っているセットアップ用スクリプトです(自分で作るものではありません)。これでPiとリポジトリが紐付きます。

(3) svc.sh:常駐サービスとして自動起動させる

sudo ./svc.sh install
sudo ./svc.sh start

svc.sh も同梱のサービス管理スクリプト。これで、SSHを切っても・Piを再起動してもランナーが動き続け、pushを待ち受けます。

これで、pushをPi上のランナーが受けて処理できます。

STEP 2:サービス再起動を許可する(sudoers)

ワークフローの最後で sudo systemctl restart tempmonitor を実行しますが、sudo は通常パスワード入力を求めます。自動実行ではパスワードを打てないため、そこで止まってしまいます。

そこで使うのが sudoers です。sudoersは「誰が・どのコマンドを・パスワード無しで sudo 実行してよいか」を定義するLinuxの設定ファイル。ここで、ランナーのユーザー(pi)に、対象サービスの再起動コマンドだけをパスワード無しで許可します。

編集は visudo(文法チェック付きで安全に編集できる専用コマンド)で行います。

sudo visudo -f /etc/sudoers.d/tempmonitor

開いたら次の1行を書いて保存します。

pi ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart tempmonitor

STEP 3:ワークフローを書く

リポジトリに .github/workflows/deploy.yml を追加します。

name: deploy
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: self-hosted # ← Pi上のランナーで実行
    steps:
      - uses: actions/checkout@v4

      - name: Publish
        run: ~/.dotnet/dotnet publish -c Release -o ~/tempmonitor

      - name: Restart service
        run: sudo systemctl restart tempmonitor

main にpushすると、Piがチェックアウト→publish→サービス再起動まで自動で行います。第8回のsystemdサービスがそのまま更新されます。

動作確認

コードを少し直して git push すると、GitHubの Actions タブでジョブが走り、完了後に http://<PiのIP>:5000 が更新されていれば成功です。

⚠️ セキュリティ(重要)

別方式:クラウドでビルドしてSSHで配る

Piでビルドさせたくない場合は、GitHubのランナーでビルドし、成果物をPiへ送る方式もあります。

Piの負荷を下げられる一方、SSH到達性(Tailscale等)の準備が要ります。まずはセルフホストランナー方式が手軽です。

つまずきポイント

まとめ

次回(第10回・最終回)は、安全な外部公開。Cloudflare Tunnelでポート開放なしにHTTPS公開し、運用の仕上げをします。


前の記事:連載⑧ BlazorアプリをsystemdでRaspberry Piに常駐させる


この記事をシェア:

前の記事
BlazorアプリをsystemdでRaspberry Piに常駐させる|自動起動と自動再起動【連載⑧】
次の記事
ラズパイのBlazorアプリを安全に外部公開する|Cloudflare TunnelでHTTPS【連載⑩・完結】