コンテナベースの多機能ホームサーバー
個人プロジェクト
概要
Raspberry Pi 5(8GB RAM)+NVMe SSD 2TB上にUbuntu Server 24.04 LTS arm64を載せ,Docker Composeとシェルスクリプトで10コンテナ規模のホームサーバーをInfrastructure as Codeとして構築.スマートホームハブ,Time Machineバックアップ,Web変更検知,死活監視,社外VPN接続までを単一筐体で同居させ,設定は全てGit管理することで再構築コストを最小化した.
アーキテクチャ
Docker Compose profiles(`phase1`〜`phase4`および`full`)で依存関係順に段階起動する構成を採用.検証中は特定フェーズのみを立ち上げ,本番運用時は`full`で一括起動という運用パスを設計.各フェーズに冪等なセットアップスクリプトを1対1で対応させ,再現性を担保した.
Bridge / Host の2種ネットワークを用途別に明示的に使い分け.SMB,mDNS,Bluetoothなど L2的要件を持つコンテナ(Samba,Homebridge,Home Assistant)はHostネットワークに配置し,それ以外のHTTP系はBridgeに隔離.Homepageダッシュボードの`siteMonitor`は,Bridgeサービスはコンテナ名で,HostサービスはDocker bridgeのゲートウェイIPで解決する二層の命名規則を実装して統一的に監視している.
Nginx Proxy Managerには REST APIを Bearerトークンで叩き,プロキシホストを宣言的に構成.手作業で設定した状態をAPIから読み取って`configs/`へ書き出すことで,WebUIでの変更も最終的にIaC側へ吸い上げられる流れにした.AvahiのCNAMEパブリッシャー(`/etc/avahi/cname.d/services.conf`)で`<service>.local → ubuntu-pi.local`を動的発行し,家庭内DNSを汚さず全サービスに`.local`ドメインを付与.
- phase1 基盤: Nginx Proxy Manager / Docker Socket Proxy(Homepageを読み取り専用でソケット露出)/ Homepage / MkDocs Material
- phase2 ファイル: Samba(Time Machine,`vfs_fruit`完全対応)
- phase3 スマートホーム: Homebridge(HomeKit + Tesla連携)/ Home Assistant(`privileged` + host net + D-Bus)
- phase4 監視: Playwright Chrome(JS描画)/ Changedetection.io / Uptime Kuma
- ホスト直接導入: Tailscale(Exit Node)/ AdGuard Home(systemd-resolvedスタブリスナー無効化で共存)/ Rclone(cron日次バックアップ)
運用・可観測性
`phase0-prereq.sh`から`phase4-utility.sh`までの全シェルスクリプトを冪等に設計.再実行しても差分のみ適用されるよう,`systemctl enable --now`や`docker compose up -d`の前に状態チェックを組み込み,配線ミスからの復旧を高速化した.
`verify-all.sh`で13項目のヘルスチェック(ポート疎通・コンテナステータス・mDNS解決・SMB接続・Home Assistant API疎通等)を集約.デプロイ直後に一括検証し,どのレイヤーで問題が起きているかを即座に切り分けられる運用体制を構築.
Rcloneが毎日3:00に`homeassistant`と`timemachine`をGoogle Driveへ5MB/s制限で同期.上流帯域を圧迫せず,かつローカルとクラウドの二重化によるディザスタリカバリを実現.データは`~/data/`(`.gitignore`)に集約し設定(`configs/`)と物理的に分離することで,誤バックアップを防いだ.
ハードウェア最適化
`/boot/firmware/config.txt`に`dtparam=pcie1_gen=3`を追記してPCIe Gen3を有効化.NVMe SSDのスループットを約450MB/s → 900MB/sへ倍増させ,Time Machineのバックアップ時間を実効的に半減.さらにEEPROMを最新化して NVMeブートの安定性を確保した.
AdGuard Homeが UDP/53を占有する必要があるため,`systemd-resolved`のスタブリスナーを`/etc/systemd/resolved.conf`から無効化し`/etc/resolv.conf`をAdGuardへ向けることで,OS標準DNSと宅内DNSフィルタの競合を解消.