Reviewed-on: #18
nixos-servers
NixOS Flake-based configuration repository for a homelab infrastructure. All hosts run NixOS 25.11 and are managed declaratively through this single repository.
Hosts
| Host | Role |
|---|---|
ns1, ns2 |
Primary/secondary authoritative DNS |
ca |
Internal Certificate Authority |
ha1 |
Home Assistant + Zigbee2MQTT + Mosquitto |
http-proxy |
Reverse proxy |
monitoring01 |
Prometheus, Grafana, Loki, Tempo, Pyroscope |
jelly01 |
Jellyfin media server |
nix-cache01 |
Nix binary cache |
pgdb1 |
PostgreSQL |
nats1 |
NATS messaging |
auth01 |
Authentication (LLDAP + Authelia) |
vault01 |
OpenBao (Vault) secrets management |
template1, template2 |
VM templates for cloning new hosts |
Directory Structure
flake.nix # Flake entry point, defines all host configurations
hosts/<hostname>/ # Per-host configuration
system/ # Shared modules applied to ALL hosts
services/ # Reusable service modules, selectively imported per host
modules/ # Custom NixOS module definitions
lib/ # Nix library functions (DNS zone generation, etc.)
secrets/ # SOPS-encrypted secrets (age encryption)
common/ # Shared configurations (e.g., VM guest agent)
terraform/ # OpenTofu configs for Proxmox VM provisioning
terraform/vault/ # OpenTofu configs for OpenBao (secrets, PKI, AppRoles)
playbooks/ # Ansible playbooks for template building and fleet ops
scripts/ # Helper scripts (create-host, vault-fetch)
Key Features
Automatic DNS zone generation - A records are derived from each host's static IP configuration. CNAME aliases are defined via homelab.dns.cnames. No manual zone file editing required.
SOPS secrets management - Each host has a unique age key. Shared secrets live in secrets/secrets.yaml, per-host secrets in secrets/<hostname>/.
Daily auto-upgrades - All hosts pull from the master branch and automatically rebuild and reboot on a randomized schedule.
Shared base configuration - Every host automatically gets SSH, monitoring (node-exporter + Promtail), internal ACME certificates, and Nix binary cache access via the system/ modules.
Proxmox VM provisioning - Build VM templates with Ansible and deploy VMs with OpenTofu from terraform/.
OpenBao (Vault) secrets - Centralized secrets management with AppRole authentication, PKI infrastructure, and automated bootstrap. Managed as code in terraform/vault/.
Usage
# Enter dev shell (provides ansible, opentofu, openbao, create-host)
nix develop
# Build a host configuration locally
nix build .#nixosConfigurations.<hostname>.config.system.build.toplevel
# List all configurations
nix flake show
Deployments are done by merging to master and triggering the auto-upgrade on the target host.
Provisioning New Hosts
The repository includes an automated pipeline for creating and deploying new hosts on Proxmox.
1. Generate host configuration
The create-host tool (available in the dev shell) generates all required files for a new host:
create-host \
--hostname myhost \
--ip 10.69.13.50/24 \
--cpu 4 \
--memory 4096 \
--disk 50G
This creates:
hosts/<hostname>/- NixOS configuration (networking, imports, hardware)- Entry in
flake.nix - VM definition in
terraform/vms.tf - Vault AppRole policy and wrapped bootstrap token
Omit --ip for DHCP. Use --dry-run to preview changes. Use --force to regenerate an existing host's config.
2. Build and deploy the VM template
The Proxmox VM template is built from hosts/template2 and deployed with Ansible:
nix develop -c ansible-playbook -i playbooks/inventory.ini playbooks/build-and-deploy-template.yml
This only needs to be re-run when the base template changes.
3. Deploy the VM
cd terraform && tofu apply
4. Automatic bootstrap
On first boot, the VM automatically:
- Receives its hostname and Vault credentials via cloud-init
- Unwraps the Vault token and stores AppRole credentials
- Runs
nixos-rebuild bootagainst the flake on the master branch - Reboots into the host-specific configuration
- Services fetch their secrets from Vault at startup
No manual intervention is required after tofu apply.
Network
- Domain:
home.2rjus.net - Infrastructure subnet:
10.69.13.0/24 - DNS: ns1/ns2 authoritative with primary-secondary AXFR
- Internal CA for TLS certificates (migrating from step-ca to OpenBao PKI)
- Centralized monitoring at monitoring01