AI時代になってからというもの、色々なものをGit管理したいというモチベーションが上がっている。Claude Codeのようなツールからリポジトリを扱う場面が増えてきたし、Obsidian VaultのようなものもGitで管理しておくと何かと都合がいい。
一方で、なんでもかんでもGitHubに置くのはちょっとな、という気持ちが少なくとも自分にはある。GitHub自体に不満があるわけではないが、プライベートなデータや実験的なリポジトリまで全部GitHubというのは気が進まない。
特に気になっていたのがOpenClawのような自律的なAIエージェントとの兼ね合いだ。OpenClawはLinux上で主には自分のユーザー権限で動く。GitHubへのアクセスはGit SSHか、HTTPS経由ならPATを使うことになる(gh CLIの場合は~/.config/gh/hosts.ymlにあるPATを使うようだ)。つまり自律的なAIエージェントがGitHubの全リポジトリにアクセスできてしまう。個人的にはこれは望ましくなかった。
Fine-grained PATでリポジトリ単位の権限制御はできるが、リポジトリが増えるたびにトークンの設定を見直すのも面倒だ。
GitHubとは隔離度合いの高いセルフホストGitサーバーが欲しい。HTTPS経由でpush/pullできればOpenClawからも扱いやすい。ということでForgejoを自分のVPSに導入した。
なぜForgejo
Giteaのフォークで、コミュニティ主導の開発が続いている。機能的にはGiteaとほぼ同じで、GitHub風のWeb UIを持ちつつ、シングルバイナリで動く軽量さが魅力。
自分のVPSにはすでにNginxとMySQLが動いていたので、追加の構築コストはほぼなかった。
セットアップ
既存のUbuntu 24.04のVPSにバイナリを配置して、systemdでサービス化した。DBはMySQLを使い、NginxでリバースプロキシしてSSL終端している。ワイルドカード証明書があったので、サブドメインを切ってアクセスできるようにした。
https://git.example.com → Nginx → http://127.0.0.1:3000
セキュリティ面では、Web UIはNginxのallow/denyで、ForgejoのビルトインSSHサーバーはufwで、それぞれ自宅や職場などよくアクセスする場所のIPとTailnetからのみアクセスを許可している。新規ユーザー登録も無効化しているので、完全に個人用。
SSH経路の分離
もともとOpenClawからはHTTPS経由でpush/pullできるのがメリットだと思っていたので、SSHのことはあまり考えずにForgejoを導入した。ところが導入後にForgejoにビルトインのSSHサーバーがあることを知り、「ならVPS管理用のSSHとポート分けるだけでいいじゃん」となった。
[server]
START_SSH_SERVER = true
SSH_PORT = 54922
SSH_LISTEN_PORT = 54922
これでssh://git@git.example.com:54922/user/repo.gitのような形でアクセスできる。Forgejoがsshの鍵管理もやってくれるので、サーバー側のauthorized_keysを触る必要がない。ポート分ければいいだけというのは導入した後に気づいたが、ビルトインsshdのおかげで管理が楽になった。
使ってみて
思った以上にWeb UIで色々見れるのが便利だった。差分ビュー、ブランチ管理、リポジトリの設定などGitHubに慣れている身としては違和感なく使える。APIトークンの発行もWeb UIからできるので、CIやツールとの連携もしやすい。
運用コストも今のところ軽い。Forgejoのアップデートはバイナリを差し替えてsystemctl restartするだけ。バックアップはデータディレクトリとDBを取ればいい。
ForgejoにはGitHub Actionsと互換性のあるForgejo Actionsもあるが、まだ試せていない。そのうちやりたい。
なんでもGitHubではなく、用途に応じてセルフホストのGitサーバーを持っておくという選択肢、なかなか良い。インフラレベルでのアクセス制御という観点で、AIに対してのひとつのハーネスエンジニアリングと呼べるかも。