← projects
// project

Nix Relay Server

Reusable NixOS flake for redundant DNS relay hosts running Pi-hole and Traefik, with GitOps-driven automatic upgrades, Renovate dependency updates, and CI-built system closures.

repo ↗
homelab · nix · IaC · dns

Summary

A NixOS flake that defines a fleet of DNS relay hosts from a single repository. Each host runs Pi-hole behind Traefik, with configuration synchronized from a leader node. Cloning a new relay comes down to a hardware config, a small settings.nix, and one entry in flake.nix.

Architecture

  • Hosts: nix01, iris, and hermes, each with its own hosts/<hostname>/ directory
  • Shared profile: profiles/relay-base.nix is the common relay template; hosts only override what differs
  • Services: Pi-hole for DNS filtering, Traefik for ingress and TLS
  • Sync: Nebula Sync on a single leader pushes Pi-hole config to the replicas

Core Principles

  • Declarative hosts: The whole system state lives in the flake; nix flake check validates it
  • Plain Compose stacks: Stacks in stacks/ stay ordinary Docker Compose projects. Nix maps each one to a systemd unit that runs docker compose up --wait, so a rebuild recreates only containers whose image or configuration changed
  • State outside the repo: Mutable data and secrets live under /var/lib/homelab/. An interactive bootstrap.sh creates them with mode 0600, and missing env files fail visibly instead of being silently defaulted
  • No silent failures: Reconciliation errors surface through systemctl status and journalctl

GitOps & Deployment

  • Merge to deploy: Each host runs system.autoUpgrade against github:bartilg/nix-relay-server#<hostname>, so merging to main rolls out on the next scheduled run
  • Staggered upgrades: Per-host autoUpgradeDates keep the DNS relays from restarting at the same time
  • Dependency updates: Renovate tracks flake inputs and Compose images and runs periodic flake.lock maintenance
  • CI: GitHub Actions builds the full NixOS system closures on a self-hosted ARC runner scale set, and the build check is required before merging to main