NixOs server configuration
  • Nix 83.8%
  • Shell 14.1%
  • Go Template 2.1%
Find a file
2026-10-09 14:31:27 +02:00
modules feat: require forgejo.service 2026-10-09 14:31:27 +02:00
scripts feat: add hire-me-site module to serve felix.meuer.xyz/hire-me/* 2026-07-31 19:56:41 +02:00
secrets feat: add hire-me-site module to serve felix.meuer.xyz/hire-me/* 2026-07-31 19:56:41 +02:00
.gitignore feat: require forgejo.service 2026-10-09 14:31:27 +02:00
configuration.nix feat: upgrade packages 2026-09-09 20:01:22 +02:00
disk-config.nix fix: automatically clean older kernel versions 2026-09-08 14:57:29 +02:00
flake.lock feat: upgrade packages 2026-09-09 20:01:22 +02:00
flake.nix feat: add hire-me-site module to serve felix.meuer.xyz/hire-me/* 2026-07-31 19:56:41 +02:00
README.md feat: added README 2026-07-30 22:33:27 +02:00

nix-server

NixOS flake configuration for a single Contabo VPS (meuer.xyz) hosting a handful of self-hosted services behind an nginx reverse proxy, deployed with nixos-rebuild --target-host and secrets managed via agenix.

Structure

.
├── flake.nix           # entrypoint: nixosConfigurations.contabo-server
├── configuration.nix   # host-wide base config (bootloader, SSH, ACME defaults, agenix identity)
├── disk-config.nix     # disko partitioning/LVM layout
├── modules/            # one file per service, imported from flake.nix
├── scripts/            # deploy + operational helper scripts
└── secrets/            # agenix-encrypted secrets (*.age) and secrets.nix key registry

Each service lives in its own modules/*.nix file and is wired into the system via the modules list in flake.nix. Services that need a public hostname declare their own services.nginx.virtualHosts.<domain> block with enableACME = true; forceSSL = true;, so TLS certs are issued automatically per-domain by the ACME module configured in configuration.nix.

Modules

  • nginx.nix — enables the shared nginx instance used as the reverse proxy for every other service, plus the Diffie-Hellman params it uses for TLS.
  • postgres.nix — shared PostgreSQL instance. Services connect over the local Unix socket using peer authentication (the connecting system user must match the Postgres role name), so no DB passwords are needed. Runs services.postgresqlBackup.
  • vaultwarden.nix — Bitwarden-compatible password manager at vault.meuer.xyz. Signups disabled; SMTP + admin token supplied via the vaultwarden-env.age secret.
  • hedgedoc.nix — collaborative Markdown editor at pad.meuer.xyz.
  • jitsi.nix — self-hosted video conferencing at jitsi.meuer.xyz.
  • minecraft.nix — declarative Minecraft server on port 43000.
  • forgejo.nix — self-hosted git forge (the software Codeberg.org runs on) at git.meuer.xyz. Uses Postgres via peer auth, LFS enabled, public registration disabled (admin accounts are created via scripts/forgejo-create-admin.sh), git-over-SSH on port 2222 (its own built-in SSH server, separate from the host's OpenSSH on port 22). Reuses the smtp-password secret declared in auto-update.nix for outgoing mail.
  • backup.nix — nightly-triggered oneshot service that GPG-encrypts a pg_dump of the Vaultwarden database (symmetric, passphrase from backup-passphrase.age) and prunes backups older than 14 days.
  • auto-update.nix — system.autoUpgrade at 03:00 daily, gated on a successful Vaultwarden backup first. After a successful upgrade+switch, a health-check service verifies core services came back up and emails felix@meuer.xyz (via smtp-password.age) if any failed to restart.

Secrets

Secrets are encrypted with agenix and committed as secrets/*.age. secrets/secrets.nix lists which public keys (the server's own SSH host key, plus a local personal key for editing) each secret is encrypted for:

  • vaultwarden-env.age — Vaultwarden SMTP_PASSWORD / ADMIN_TOKEN env file.
  • smtp-password.age — shared SMTP password, referenced by auto-update.nix and forgejo.nix.
  • backup-passphrase.age — GPG passphrase for encrypted Vaultwarden backups.

Edit a secret with agenix -e <name>.age (run from secrets/, requires your local SSH key to be one of the listed public keys). The server decrypts secrets at activation time using its own SSH host key (/etc/ssh/ssh_host_ed25519_key), configured via age.identityPaths in configuration.nix.

Scripts

  • deploy.sh — rsyncs the repo to /etc/nixos-server-config/ on the server and runs nixos-rebuild switch --target-host against it.
  • backup-vaultwarden.sh — one-off, on-demand GPG-encrypted Vaultwarden backup, downloaded to the local machine.
  • forgejo-create-admin.sh — creates a Forgejo admin user via the Forgejo CLI on the server (registration is disabled, so this is the only way to provision accounts).
  • post-upgrade-alert-email.tmpl — email template used by the post-upgrade-healthcheck service in auto-update.nix.

Deploying

./scripts/deploy.sh

This builds and switches the contabo-server flake output on the remote host over SSH. Requires SSH access to root@meuer.xyz.