Personal NixOS system configurations managed with flakes and sops-nix for encrypted secrets.
This file is auto-generated. Edit
scripts/generate-readme.shto change its contents.
nixos-configs/
├── flake.nix # Flake entry point with host definitions
├── common.nix # Shared configuration for all hosts
├── machines/
│ ├── nova/ # Media server / reverse proxy / Matrix
│ ├── gilbert/ # Media ripping / Minecraft / NFS
│ └── void/ # NAS (ZFS RAID)
├── modules/
│ ├── uptime-kuma.nix # Custom uptime-kuma sync module
│ └── cloudflare-dns.nix # Auto-sync Caddy vhosts to Cloudflare DNS
├── scripts/
│ ├── generate-readme.sh # Regenerates this file
│ ├── install-hooks.sh # Installs git hooks
│ ├── update.sh # Pull + nixos-rebuild on current host
│ ├── install.sh # Bootstrap any machine via nixos-anywhere
│ └── sops.sh # Secrets management helper
├── .githooks/
│ └── pre-commit # Auto-regenerates README on commit
└── secrets/
└── secrets.yaml # Encrypted secrets (gitignored)
| Host | IP | Purpose | Key Services |
|---|---|---|---|
gilbert |
192.168.0.11 |
Media ripping (ARM), Minecraft server, NFS storage | Minecraft (ATM10),arm |
nova |
192.168.0.10 |
Media server, reverse proxy, Matrix homeserver | Matrix-Synapse,Caddy,Cloudflare DNS sync,jellyfin,pihole,uptime-kuma,gotify,igotify,romm-db,romm,immich-server,immich-machine-learning,immich-redis,immich-postgres,rustfs |
void |
192.168.0.12 |
NAS with ZFS RAID storage | ZFS + SMART monitoring |
IP: 192.168.0.11 Purpose: Media ripping (ARM), Minecraft server, NFS storage
| File | Role |
|---|---|
backups.nix |
|
containers.nix |
Docker container definitions |
default.nix |
Imports all machine modules |
hardware-configuration.nix |
Generated hardware config (do not edit) |
hardware.nix |
GPU drivers and hardware acceleration |
minecraft.nix |
Minecraft server (ATM10 / NeoForge) |
networking.nix |
Static IP, firewall, Tailscale |
services.nix |
SOPS secret declarations |
storage.nix |
Disk mounts and NFS |
arm-config/ |
ARM app config (arm.yaml) + Dockerfile |
IP: 192.168.0.10 Purpose: Media server, reverse proxy, Matrix homeserver
| File | Role |
|---|---|
backups.nix |
|
caddy.nix |
Reverse proxy virtual hosts |
containers.nix |
Docker container definitions |
default.nix |
Imports all machine modules |
hardware-configuration.nix |
Generated hardware config (do not edit) |
hardware.nix |
GPU drivers and hardware acceleration |
matrix.nix |
Matrix-Synapse homeserver + PostgreSQL |
networking.nix |
Static IP, firewall, Tailscale |
services.nix |
SOPS secret declarations |
storage.nix |
Disk mounts and NFS |
IP: 192.168.0.12 Purpose: NAS with ZFS RAID storage
| File | Role |
|---|---|
default.nix |
Imports all machine modules |
hardware-configuration.nix |
Generated hardware config (do not edit) |
networking.nix |
Static IP, firewall, Tailscale |
samba.nix |
|
services.nix |
SOPS secret declarations |
smartd.nix |
SMART disk monitoring + notifications |
storage.nix |
Disk mounts and NFS |
Applied to every host:
- Nix: flakes + nix-command enabled, auto-optimise-store
- Timezone: Europe/London, locale en_GB.UTF-8
- Packages: nano, tree, git, btop, wget, curl
- SSH: password auth disabled, root login restricted; keys imported from GitHub
- Tailscale: enabled on all hosts with routing features
- Auto-upgrade: polls
github:imlunahey/nixos-configsevery 15 minutes, reboots if needed - Gotify notification: sent when a host successfully upgrades to a new generation
| Input | Source |
|---|---|
inputs |
github:NixOS/nixpkgs/nixos-unstable |
| Script | Purpose |
|---|---|
scripts/generate-readme.sh |
Regenerate this README from repo structure |
scripts/install-hooks.sh |
Configure git to use .githooks/ |
scripts/update.sh |
git pull then nixos-rebuild switch on the current host |
scripts/install.sh <machine> <ip> |
Bootstrap any machine from a NixOS live ISO via nixos-anywhere |
scripts/sops.sh <cmd> |
list / get / set / delete / edit secrets |
| Module | Purpose |
|---|---|
modules/uptime-kuma.nix |
Syncs Caddy virtual hosts as HTTP monitors into Uptime Kuma on boot |
modules/cloudflare-dns.nix |
Upserts Caddy virtual hosts as Cloudflare DNS A records on boot |
The cloudflare-dns module reads services.caddy.virtualHosts at build time and generates a boot-time service that creates or updates the corresponding DNS A records via the Cloudflare API. Adding a new Caddy virtual host is enough — no manual DNS management required.
Managed records (nova):
matrix.flaked.orgjellyfin.flaked.orgpihole.flaked.orgstatus.flaked.orgs3.flaked.orggotify.flaked.orgigotify.flaked.orgromm.flaked.orgimmich.flaked.orgs3-console.flaked.org
Secrets are encrypted with SOPS + age.
Each machine decrypts secrets via its host SSH key (/etc/ssh/ssh_host_ed25519_key). Age keys are defined in .sops.yaml.
# List secrets
./scripts/sops.sh list
# Get a secret
./scripts/sops.sh get tailscale_key
# Add or update a secret
./scripts/sops.sh set my_secret my_value
# Open in editor
./scripts/sops.sh edit- Add the key:
./scripts/sops.sh set my_new_secret value - Declare it in the relevant
machines/<host>/services.nix:sops.secrets.my_new_secret = {};
- Reference it in config:
config.sops.secrets.my_new_secret.path
./scripts/install-hooks.shThis configures git to use .githooks/, which regenerates the README before every commit.
- Create
machines/<name>/with at minimum:default.nix,hardware-configuration.nix,networking.nix,services.nix - Add age key to
.sops.yamland re-encrypt:./scripts/sops.sh edit - Add to
flake.nixoutputs - Deploy:
./scripts/install.sh <name> <ip>
nix flake update
git add flake.lock
git commit -m "chore: update flake.lock"MIT