- Nix 83.6%
- HTML 10.7%
- Shell 5.7%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
Flake lock file updates:
• Updated input 'nixpkgs':
'git+https://elbforge.org/NuschtOS/nuschtpkgs/?ref=backports-26.05&rev=24df2647a97f8369d2ac49b16e5c4ab72f7439fe&shallow=1' (2026-08-30)
→ 'git+https://elbforge.org/NuschtOS/nuschtpkgs/?ref=backports-26.05&rev=054114434b4fd533db021b24682339f494f03f28&shallow=1' (2026-09-06)
• Updated input 'sops-nix':
'github:mic92/sops-nix/a8627b21b9107c5711c96b84f32a9a4b3d45295f?narHash=sha256-gkig4nPi1CWc4Z50GBsjE4ygSE7hMpl/TwID2an2Cck%3D' (2026-08-13)
→ 'github:mic92/sops-nix/fbf759290e0cb0a98dfc813a4eb7d53ad1dacb57?narHash=sha256-gkSH8VUtCo6hnysNmb9DbTuDepH2t5pv%2BQWjP75xKAk%3D' (2026-09-02)
|
||
| docs | ||
| hosts | ||
| images | ||
| keys | ||
| lib | ||
| modules | ||
| pkgs | ||
| resources | ||
| .gitignore | ||
| build.sh | ||
| flake.lock | ||
| flake.nix | ||
| README.md | ||
| update-prod.sh | ||
Elbforge Infra
NixOS configuration for Elbforge, a hosted developer
platform built around Forgejo (git forge) with
Authentik for single sign-on. Everything is defined as a
Nix flake and deployed to OpenStack VMs hosted at the dd8a ALASCA deployment
maintained by Cloud&Heat.
Hosts
| Host | Role | What it runs |
|---|---|---|
elf-rpx01 |
Reverse proxy | HAProxy, ACME/TLS termination, HTTP + TCP (git-over-SSH) ingress |
elf-forge01 |
Git forge | Forgejo, with its data on a ZFS pool. |
elf-idp01 |
Identity provider | Authentik (SSO), configured declaratively through blueprints |
elf-adm01 |
Admin services | Authoritative DNS (Knot), mail (nixos-mailserver) |
elf-db01 |
Database | PostgreSQL for Authentik and Forgejo, with its data on a ZFS pool |
Stages
Every host is built in two variants:
prod: the real deployment onelbforge.org. Network addressing comes from OpenStack (modules/elbforge-prod/ipam.json).local: a throwaway QEMU VM onelbforge.test, for testing changes without touching production.
Repository layout
.
├── flake.nix # entrypoint: inputs, packages, nixosConfigurations
├── flake.lock # locked dependencies
├── hosts/
│ └── <name>/ # per-host config: default.nix + prod.nix + local.nix
├── modules/
│ ├── common/ # generic NixOS tuning (ssh, nix, kernel, tools, ...)
│ ├── elbforge/ # base config applied to every Elbforge host
│ ├── elbforge-prod/ # prod-stage overlay (domain, ipam from OpenStack)
│ ├── elbforge-local/ # local-stage overlay (domain, derived addressing)
│ └── elbforge-<role>/ # opt-in service roles (rpx, forge, auth, db, ns, mta, ...)
├── pkgs/ # custom packages (authentik, forgejo, VM/image builders)
├── lib/ # Nix helpers (nixosSystem, mkIp, mkMac, mkHash)
├── keys/ # SSH public keys
├── resources/ # step-ca certs, dhcp scripts
├── images/ # local VM disk images
└── docs/ # in-depth docs
How a host is assembled
hosts/<name>/default.nix sets the hostname and enables the roles it needs via
elbforge.<role>.enable = true. The role modules under modules/elbforge-*
implement each role and are gated behind those flags, so a host only pulls in what it
turns on. Stage-specific bits live in hosts/<name>/prod.nix / local.nix and the
matching modules/elbforge-{prod,local} overlay.
Common tasks
Build
# build all prod hosts
./build.sh
# build a single prod host (forge01 | idp01 | adm01 | rpx01)
./build.sh forge01
Deploy to production
Before you can deploy to production hosts, you should configure adm01 as your
SSH jump host for elf-*.prod.elbforge.org. Otherwise, you won't be able to access
them via SSH or deploy to them using update-prod.sh:
Host elf-*.prod.elbforge.org
ProxyJump elf-adm01.prod.elbforge.org
Builds locally and switches the remote host over SSH:
./update-prod.sh forge01
Run a host locally as a VM
nix run .#elf-idp01-local
The VM sets up a br-elbforge bridge and boots with a decrypted host key. Disk
images live in ./images/<name>.qcow2. Shut it down with shutdown from inside.
See docs/local-vm.md.
You can also use the vm-helper to run multiple VMs at once:
nix run .#vm-helper
Build an OpenStack image
nix build .#openstack-image-x86_64
See docs/openstack/image.md for the openstack image create
invocation used to upload it.
Secrets
Secrets are managed with sops-nix and pulled from
the private elf-secrets flake input. Each host+stage has its own encrypted file,
<host>.<stage>.yaml (e.g. elf-forge01.prod.yaml).
Binary cache
Prebuilt artifacts (notably Authentik and Forgejo) come from the Gradient cache at
gradient.c3d2.de, configured in flake.nix. The hydraJobs output
is what gets built and pushed there.