← Return to field notes
systems / homelab build log

A homelab is a small datacenter with a recovery contract

Proxmox, Caddy, NetBird, and Docker Compose on one box is enough to run a real infrastructure fabric. The discipline is treating the single node like a datacenter: backups, IaC, and tested recovery.

explainer verified created 2026-07-28 updated 2026-07-28 8 min 4 sections 1 figures
subscribe via RSS report a correction sec intro ~8 min left read 0%
opening contract explainer · verified
problem
A homelab built by ad-hoc SSH commands and manual container creation becomes un-rebuildable within months. A disk failure or a Proxmox upgrade becomes a multi-day reconstruction instead of a restore.
scope
A homelab fabric design: Proxmox as the hypervisor, Docker Compose for services, Caddy as the edge proxy, NetBird for overlay networking, and everything defined in version-controlled configuration that can rebuild the host from a fresh install.
environment
A single Proxmox VE host (VM102) running LXC containers and VMs, with Docker Compose stacks for services, Caddy for reverse proxy with Authentik SSO, and NetBird for WireGuard overlay access.

Assumptions

  • The host is a single physical machine; high availability is not the goal, but tested recovery is.
  • All persistent data lives on ZFS or on bind-mounted volumes that are backed up.
  • The operator can rebuild the host from a Proxmox ISO plus a configuration repository.

Limitations

  • A single node has no HA; the recovery contract is "restore from backup," not "failover."
  • This is a personal infrastructure record, not an enterprise design; scale assumptions differ.
  • Network details (IPs, VLANs, NetBird peer IDs) are omitted for security.
Table of contents 4 sections
  1. 1 Configuration is the source of truth, not the running host
  2. 2 Caddy and Authentik are the edge and identity layer
  3. 3 NetBird makes the LAN reachable from anywhere
  4. 4 Backups are a tested contract, not a cron job

Configuration is the source of truth, not the running host

The running host is a build artifact. The source of truth is the configuration repository: Compose files, Caddyfile, LXC templates, and provisioning scripts. A service that exists only on the host and not in the repository is a service that cannot be rebuilt after a failure.

This means every new service starts as a Compose file in the repository. The deployment is "git pull && docker compose up -d." A service that required manual steps to configure is a debt that must be repaid by encoding those steps as a script or a Compose entry before it counts as "done."

Caddy and Authentik are the edge and identity layer

Caddy terminates TLS for every public service and reverse-proxies to internal containers. Authentik provides SSO: a request to a protected service hits Caddy, Caddy forwards to Authentik for authentication, and Authentik returns a forward-auth decision. This means no service has its own auth logic; identity is centralized at the edge.

The practical pattern is a Caddyfile where each site block includes a forward_auth directive pointing to Authentik. A new service is exposed by adding a site block and an Authentik application; it does not implement login. This is the same separation as an API gateway: the service trusts the edge to have authenticated the request.

Caddy + Authentik forward-auth plaintext
cockpit.moment.msakg.com {    reverse_proxy 10.10.0.111:8765    forward_auth authentik:9000 {        uri /outpost.goauthentik.io/auth/traefik        copy_headers X-Authentik-Username \                      X-Authentik-Email        trusted_proxies 10.10.0.0/24    }}

NetBird makes the LAN reachable from anywhere

NetBird creates a WireGuard mesh overlay. A laptop on a remote network can reach the homelab services by IP without a VPN client config or port forwarding. The overlay is the access layer; Caddy and Authentik are the application layer. This separates "can I reach the network" from "can I access the service," which are different security decisions.

The trade-off is that the overlay peer must be trusted. A compromised laptop on the overlay can reach every internal service. The mitigation is that Authentik still gates application access, so overlay access is necessary but not sufficient. The two layers compose: network reach plus identity, neither alone.

Backups are a tested contract, not a cron job

A Proxmox vzdump cron job creates backups, but a backup that has never been restored is a hypothesis, not a contract. The discipline is to test restore: take a backup, restore it to a test VM, boot it, and verify the service works. If the restore fails, the backup is worthless and the failure is found in a test, not during an outage.

Persistent data for Docker Compose services lives on bind-mounted ZFS datasets. These are snapshotted by ZFS and replicated to a secondary location. The Compose file in the repository plus the ZFS snapshot is the full recovery set: the repository rebuilds the container configuration, the snapshot restores the data.

evidence ledger 2 claims
  1. implemented
    Running homelab fabric

    Proxmox VE hosts LXC containers and VMs; Docker Compose stacks run Nextcloud, SigNoz, a static site, and internal services; Caddy terminates TLS with Authentik SSO; NetBird provides overlay access from remote networks.

  2. field-observed
    Tested recovery

    The host has been rebuilt from a fresh Proxmox install plus the configuration repository within a working session, validating the recovery contract.

linked artifacts 2 attached
  • reference
    Proxmox VE documentation

    Reference for ZFS, backups, LXC, VM management, and storage configuration.

    open ↗
  • reference
    Caddy documentation

    Reference for reverse proxy, automatic HTTPS, and module configuration.

    open ↗