プロジェクト · 2026 · 作者

abualruz-homelab:サイトとそれを動かすインフラ

Caddy と Docker でホームラボミラーから配信する Astro 6 + Svelte 5 製パーソナルサイト。エージェントプレイブックとともにフェーズごとに積み上げた、自作インフラと自作ワークフローの実験記録。

Screenshot of the abualruz-homelab GitHub repo page showing the site + infra monorepo

これはメタプロジェクトだ。君が今読んでいるこのサイト、それをミラーするホームラボインフラ、そして両方を構築したエージェントプレイブック。ある意味で文字どおりの進行中の実験でもある—AIコーディングエージェントを主要な労働力として使いながらプロダクション品質のパーソナルサイトをリリースできるか、しかも恥ずかしくないコードベースで、という問いへの答えを探している。

今のところ、答えはイエスだ—ただし重要な注釈つきで。

なぜ作ったか

理由は二つ。一つ目は退屈な話だ:パーソナルサイトが欲しかった。何年も「そのうち作ろう」と思っていて、「そのうち」はサイドプロジェクトの墓場になりがちなことはよく知っている。二つ目の理由の方が面白い:本物のプロジェクトが必要だった。おもちゃでも、チュートリアルでも、「デプロイボタン付きのHello World」でもない、Fulcrumで構築してきたエージェント支援開発ワークフローを本気でストレステストできる何かが。

パーソナルサイトはそのために完璧だ。要件は本物だ。デザインの決断には意味がある。書くべきコンテンツがある、守るべきパフォーマンスバジェットがある、恥ずかしい方法でやらかして後で直すCSPヘッダーがある。ただし、ミスのブラストラジウスは全部自分だけに返ってくるから、クライアント案件よりも速く動いて派手に失敗できる。

フェーズごとに進捗ログとレッスンドキュメントをリリースする。これはドキュメントの演技じゃない—それらは次のエージェントランへの入力になる。Chief-of-Staff はフェーズ N+1 の作業を依頼する前にレッスンドキュメントを読む。書き留める規律が、次のフェーズを速くする規律だ。

どう動いているか

サイトは Astro 6 でインタラクティブアイランドに Svelte 5 を使っている。Astro はすべきことをやっている:静的ページはほぼゼロ JavaScript、必要な部分だけ選択的ハイドレーション。Svelte 5 のルーンモデルは本当に良い—パーソナルサイトが必要とするような小さく集中したインタラクティビティには、React フックより反応性プリミティブがクリーンだ。

コンテンツは MDX ファイルで、ビルド時に Zod で検証される構造化コレクションスキーマに格納される。トピックはenum(src/data/topics.ts で一度だけ定義し、スキーマとハブページの両方から使う)なので、フロントマターのタイプミスはサイレントな404の代わりに大きな音でビルドを落とす。コンテンツサイトのビルド時スキーマ検証、本当に好きになった。フィードバックループが速くて、エラーが具体的だ。

ホームラボミラーは自宅ネットワーク上の1台のマシンで動き、Caddy リバースプロキシの裏にある。Docker Compose がサービスを管理し、Caddy が TLS ターミネーションと静的ファイル配信を担う。コンテンツセキュリティポリシーは静的アセットと一緒に配信される _headers ファイルに書いている—Caddy がそのまま通過させるのは責務分担として正しい。

デプロイは GitHub Actions ワークフロー。Astro サイトをビルドして出力をサーバーにプッシュして Docker サービスを再起動する。派手じゃない。派手にする必要もない。賢い感じがするデプロイパイプラインは、大抵夜の11時に直したいものがあるタイミングで壊れるやつだ。

面白いところ

フェーズベースのリリースモデルは最初から計画していたわけじゃない。最初のエージェントランから生まれた。そのランが生んだフェーズ0は、自分がゼロから設計するものよりずっとまとまっていた—コンテンツスキーマ、動くビルド、デプロイパイプラインを持つ最小限のバイアブルサイト—そして次に何が必要かを列挙したフォローアップドキュメントも出てきた。その構造が荷重を担っていることが後で分かった。

「すべてのフェーズにレッスンドキュメントがある」という特性の面白いところは、コンテキストを完全に忘れる前に学んだことを言語化させる点だ。当たり前に聞こえるが、実際はほとんどのプロジェクトのレトロスペクティブは作業完了の3週間後に行われ、具体的な記憶が薄れて一般論しか出てこない。フェーズリリース当日にレッスンドキュメントを書くと、はるかに具体的な観察が得られる。「CSP の unsafe-inline ストップギャップは、Astro のメタ CSP アプローチが十分に安定するまでに解決する必要がある」は有用なメモだ。「CSP は難しい」は有用じゃない。

Svelte 5 + Astro の組み合わせは、何をインタラクティブにする必要があって何が不要かを真剣に考えさせた。モダンウェブ開発のデフォルトの前提はすべてをインタラクティブにすることだが、Astro はそれを逆転させる。その制約の中で働いた結果、SPA フレームワークに手を伸ばしていたら作れなかったよりも速いサイトができた。

変えたいこと

ホームラボミラーはフェイルオーバーなしの単一マシンだ。これは意図的な選択だ—不要な複雑さは噛みつく複雑さだ—でも、ハードウェアメンテナンスのたびにサイトが落ちる。自分が思いたいよりも頻繁に起きる。Caddy をフロントに置いたアクティブ・パッシブフェイルオーバーで2台目のマシンを追加するのは将来のフェーズリストに入っている。

CSP の話はまだ進行中だ。現在の _headers ファイルは Astro のネイティブなメタタグ CSP アプローチが成熟するまでの間 unsafe-inline をストップギャップとして使っている。既知の負債項目として追跡中で、アップストリームの状況が依存できるくらい安定したときにリリースする。

将来のフェーズで最も興味があるのは:サイト自体をエージェントワークフローのアウトプットサーフェスとして使うことだ。今のところ、進捗ログとレッスンドキュメントは自分が読む Markdown ファイルとして存在している。欲しいのは構造化されたエージェントメモリーレイヤー—Fulcrum はもちろんそれだ—がそれらのドキュメントを L0 ソースとして取り込んで、COS が次のフェーズを計画するときに厳選されたレッスンを自動的に表示してくれることだ。インフラはすでにある。ちゃんと配線するだけでいい。

それが本当のメタプロジェクトだ:ツールを作り、そのツールでプロジェクトを作り、プロジェクトのレッスンをツールに戻す。ループが閉じ始めている。