How it connects
What's running
Split across two hosts by trust level — public-facing on the edge, everything else stays tailnet-only.
homeserver
compute + storage, tailnet-only
The primary relational database — backs Forgejo and anything else that wants real transactions.
Document store for schema-flexible workloads that don't fit neatly into tables.
Full-text search and analytics engine, sitting under anything that needs fast querying at scale.
S3-compatible object storage for files and blobs, self-hosted instead of renting a bucket.
Self-hosted Git service — repos, issues, and pull requests, GitHub-shaped but under my own roof.
Executes Forgejo Actions jobs in an isolated Docker-in-Docker sandbox.
Web UI for managing every container and stack on the box without living in the terminal.
A small monitoring hub I built — collects heartbeats from Watchpost agents across hosts.
Browser-based file manager for poking around the filesystem from anywhere on the tailnet.
Chat interface for locally-run LLMs — the front door to whatever model is on call that day.
A grab-bag of small dev utilities — encoders, generators, converters — in one page.
A personal-use format/conversion utility, tucked away for one-off jobs.
cathedral
edge VPS, public-facing
The front door — reverse proxy and automatic TLS for every public service on this box.
This site. Next.js, rebuilt and redeployed by the pipeline below every time it changes.
A self-hosted Matrix homeserver — private chat, no third party in the middle.
A custom Matrix bot wired to a hosted LLM, with tool-calling for weather, math, and web search.
VS Code in the browser — a full dev environment reachable from any machine, no local setup.
The edge half of Sentinel — reports this host's health back to the homeserver over the tailnet.
How it ships
Every push to the deployment branch rebuilds and redeploys this site with zero manual steps.
Push
A commit lands on the deployment branch.
Actions
GitHub Actions checks out the repo and opens an SSH connection to cathedral.
Build
bun install, bun run build, then a zero-downtime docker compose recreate.
Verify
The workflow polls until the container reports healthy, then prunes old images.