Skip to content

Architecture Overview

The homelab is now managed as a native NixOS 25.11 system with a reusable module tree. The homelab-nixos repository is the source of truth for operating system configuration, services, user programs, local proxying, backups, and Cloudflare infrastructure.

graph TD
F[flake.nix] --> H[hosts/nixos/configuration.nix]
F --> HM[home-manager/home.nix]
F --> LIB[lib/ helpers]
H --> CORE[modules/nixos/core.nix]
H --> SYS[modules/nixos/system/*]
H --> SVC[modules/nixos/services/*]
H --> MCP[modules/nixos/mcp/*]
H --> INFRA[modules/nixos/infra/cloudflare.nix]
HM --> HMM[modules/home-manager/*]
SVC --> PROXIES[config.homelab.proxies]
PROXIES --> NGINX[Nginx local proxy]
PROXIES --> CF[OpenTofu Cloudflare DNS, Access, Tunnel]
SVC --> BACKUP[config.homelab.backupPaths]
BACKUP --> BACKREST[Backrest and Restic]
PathPurpose
flake.nixDefines inputs, exported modules, overlays, formatter, packages, and the nixos host.
CONFIG.nixNon-secret global metadata: main user, member emails, hostname, domain, host prefix, and state version.
MASTER_SECRETS.nix1Password reference catalog. This file stores op://... paths only, not secret values.
hosts/nixos/Host-specific switchboard and hardware configuration.
modules/nixos/core.nixShared homelab.* options for secrets, users, proxies, backups, versions, and paths.
modules/nixos/services/Native service modules. Each service owns its enable option, backup paths, proxy entry, and systemd configuration.
modules/nixos/system/Core OS modules for boot, network, users, power, localization, keyboard, and desktop settings.
modules/nixos/infra/OpenTofu-based Cloudflare provisioning.
modules/nixos/mcp/Homelab MCP servers and restricted systemd wrappers for agent operations.
modules/home-manager/User-level application modules managed by Home Manager.
lib/Shared helper functions, including runtime secret injection helpers.

hosts/nixos/configuration.nix enables the current host. It imports the reusable NixOS module set from outputs.nixosModules.default, then toggles services through homelab.services.<name>.enable, system modules through homelab.system.<name>.enable, and MCP through homelab.mcp.homelab-ssh.enable.

Global values come from CONFIG.nix and are assigned to config.homelab: domain, hostPrefix, ip, users, versions, and secrets. This keeps module code reusable and avoids hardcoding identity or domain data in service modules.

Each service module follows the same ownership model:

ConcernDeclared In
Enable optionoptions.homelab.services.<name>.enable
Runtime servicesystemd.services.*, NixOS native service options, or Podman units
Local proxyhomelab.proxies.<name> inside the service module
Backupshomelab.backupPaths and homelab.backupExcludes inside the service module
Dashboardmodules/nixos/services/portal.nix
External DNS and AccessGenerated from config.homelab.proxies by OpenTofu

The central proxy module consumes the aggregate config.homelab.proxies map. Local services are exposed through Nginx virtual hosts such as service-home.javiersc.com and local aliases such as service.nixos.local.

The host currently enables Cloudflared, Cockpit, documentation, FlareSolverr, Home Assistant, Jackett, Jellyfin, LiteLLM, Matter Server, shared media storage, Mosquitto, Ollama, OpenThread Border Router, OpenClaw, PicoClaw, Piper, Homepage, Prowlarr, Nginx proxy, Radarr, Backrest/Restic, Sonarr, Tailscale, Transmission, Whisper, and the Homelab SSH MCP server.

Zigbee2MQTT is present as a module but currently disabled in hosts/nixos/configuration.nix.

The firewall is local-first. Service modules must not use openFirewall = true; instead, they register local service ports in homelab.proxies. modules/nixos/system/network.nix derives allowed local TCP ports from the proxy map and restricts direct access to private network ranges.

Nginx listens on ports 80 and 443. Cloudflare Tunnel routes public hostnames to local services through http://127.0.0.1:<port> by default, or through an explicit cloudflareService target for non-HTTP protocols (for example, SSH via ssh://localhost:22). All Cloudflare-protected services use the standard email-based Access policy. For private/admin access (e.g. Home Assistant iOS app), use Tailscale (e.g. http://100.82.100.68:8123).

Backups are aggregated declaratively through config.homelab.backupPaths and config.homelab.backupExcludes. Backrest writes the generated plan and runs Restic against the Backblaze B2 repository b2:javiersc-backup:restic.

The OpenTofu working directory at /var/lib/cloudflare-infrastructure is intentionally not part of backups. Cloudflare resources are reconstructed from Nix, this repository, 1Password references, and the Cloudflare account.