Skip to content

Repository files navigation

NixOS configurations

Flake-based NixOS configurations for a fleet of servers, LXC containers, and workstations, with CI-gated, signature-verified GitOps deployment. Servers track the stable channel (26.05); workstations track unstable. All hosts build as .#hostname.

The primary host is srv-n1. Its configuration and the security layers behind it are documented at https://codeberg.org/sensei/nixos/wiki/srv-n1

This configuration is specific to one environment. Hostnames, usernames, disk layouts, mounts, and secrets will not transfer directly. Review every file before reusing any part of it.

Table of contents

Repo structure

  • /.forgejo: CI workflows. Host builds, deploy gating, Renovate, and a daily Cloudflare IP range refresh.
  • /config: application configuration files (ghostty, niri, waybar, etc.), deployed to ~/.config through Home Manager.
  • /home: Home Manager configurations. common.nix is the workstation baseline, server.nix the server baseline, plus per-environment and per-shell files.
  • /machines: per-host configuration, grouped into desktop, laptop, lxc, and server. Each host directory holds its default.nix, hardware-configuration.nix, disko layout, and any host-specific services. Server hosts define their OCI containers under containers/. Retired hosts are preserved on the legacy branch.
  • /modules: shared NixOS modules, exposed as options under the workstation.* and server.* namespaces.
  • /pkgs: package derivations not available in nixpkgs.
  • /secrets: sops-encrypted secrets. /.sops.yaml at the repo root defines which host keys can decrypt each secret.
  • /terra: Terraform + nixos-anywhere provisioning, one file per machine.
  • /workers: Cloudflare Workers. srv-n2-monitor polls srv-n2 on a five-minute cron.

Hosts

flake.nix defines two host builders. mkWorkstation builds against nixpkgs-unstable with the latest kernel; mkServer builds against nixpkgs-stable with an LTS kernel and imports the server baseline (SSH, service defaults, continuous deployment, binary cache, DNS, scheduled reboots). Both wire in Home Manager, disko, and sops-nix.

Current outputs:

Host Type Role
console workstation living-room KDE build with controller support
srv-n1 server primary server; runs most services as rootless Quadlets
srv-n2 server public-facing edge; Caddy, CrowdSec, Cloudflare-restricted ingress
git server Forgejo host
mongoose server qBittorrent host
pangolin server Pangolin tunnel/ingress node
jellyfin LXC media server
runner LXC Forgejo Actions runner and Harmonia binary cache
second-brain LXC second-brain service, consumed as a flake input

erebos (desktop) and prometheus (laptop) are defined but currently commented out, as is a five-node k3s cluster. Anything commented out is not being actively developed or maintained.

Modules

Modules are enable-gated options rather than unconditional imports. Workstation functionality lives under workstation.* (baseline, packages, desktop environments, virtualization, etc.); server functionality lives under server.* (baseline, cd, cache, dns, kernelReboot). A host enables what it needs:

workstation.baseline.enable = true;
workstation.niri.enable = true;

Notes:

  • Garbage collection removes generations older than 7 days on workstations and 5 days on servers. Store optimization runs weekly on both.
  • The user is created with an initialPassword, and SSH is key-only. Set a real password on first boot.
  • All builds default to zsh. A bash Home Manager file exists; swap the shell import in flake.nix.
  • Desktop environments use their stock display managers (GDM, SDDM, LightDM). Window managers use tuigreet with autologin. Niri (with Noctalia Shell) is the most actively maintained environment; GNOME, KDE, and XFCE are stable; Hyprland lags upstream.

Deployment pipeline

Servers are usually not rebuilt by hand.

  1. Forgejo Actions builds every flake output on push and pull request (nix-build.yaml).
  2. Renovate opens PRs for container image and flake input updates. Non-major container updates and lock file maintenance automerge once CI passes. New containers are pinned as tag@digest.
  3. A daily gate job (deploy-gate.yaml) rebuilds all comin-enabled hosts from main and force-pushes the result to deploy-candidate.
  4. A follow-up job (deploy-release.yaml) promotes deploy-candidate to deploy.
  5. comin on each server polls the deploy branch, verifies the tip commit is signed by a trusted key (hardware security key or the Forgejo instance signing key, which signs all PR merges), and applies it. Unsigned tips are refused, and deploy only ever moves fast-forward.

A scheduled workflow also refreshes the Cloudflare IP allowlist consumed by srv-n2.

Build commands

From the repo root:

sudo nixos-rebuild boot --flake .#console

The same form applies to any other entry in the flake. Server hosts can be built this way for testing, but routine changes reach them through the deployment pipeline above.

Showcase

Installation

For installation instructions, see https://codeberg.org/sensei/nixos/wiki/Installation-instructions

Sponsor NixOS

Consider sponsoring NixOS to support the people who make this possible: https://github.com/sponsors/NixOS

GitHub mirror

https://github.com/epic9491/nixos

Contributors

Languages