main
Imperative Configuration
Configuration for hosts not managed declaratively by NixOS.
Overview
This directory holds configuration for machines that run a traditional Linux distribution (Fedora, Debian) instead of NixOS. Two complementary approaches live here:
- Nix on top of the host OS — using the Determinate Nix installer with
system-manager(system services) andhome-manager(user environment). This is the current, preferred approach. See aomi and nagoya. - Idempotent bash scripts — self-contained
apply.shscripts that bring a host to the desired state. Kept as a fallback / bootstrap aid (e.g. the legacy nagoyaapply.sh).
Why this exists
Some systems can’t run NixOS directly:
- Hardware or organizational constraints (e.g. IT-managed corporate laptop)
- Transition periods before a full NixOS migration
- Lightweight servers where a single script is enough
Directory Structure
imperative/
├── README.md # This file
├── aomi/ # Fedora CSB laptop — Nix (system-manager + home-manager)
│ ├── README.md
│ └── bootstrap.sh
└── nagoya/ # Debian server — Nix (system-manager), bash fallback
├── README.md
└── apply.sh
Current Hosts
aomi — Fedora CSB + Nix
- OS: Red Hat CSB (Fedora), aarch64/x86_64 laptop (ThinkPad P1 Gen 3)
- Type: Work desktop/laptop, IT-managed base OS
- Approach: Nix (Determinate installer) with
system-manager+home-manager - Components: WireGuard, Syncthing, shell, editors, dev tools
- Bootstrap:
bootstrap.sh
See aomi/README.md for details.
nagoya — Debian Server
- OS: Debian, aarch64
- Type: Server
- Approach: Nix
system-manager(systems/nagoya/system.nix), with a legacy idempotentapply.shbash script as fallback - Components: Docker, Kind, WireGuard, Syncthing
- VPN IP: 10.100.0.80/24
- Status: 🚧 Needs rework — being consolidated onto the system-manager
config; the
apply.shscript remains as a bootstrap fallback.
See nagoya/README.md for details.
Usage
Nix-managed hosts (aomi)
cd ~/src/home
# System-manager (WireGuard, Syncthing, system services)
nix build .#systemConfigs.<hostname> && sudo ./result/bin/activate
# Home-manager (shell, editors, dev tools)
home-manager switch --flake .#vdemeest@<hostname>
Initial provisioning is done via the host’s bootstrap.sh. See the host
README for the exact invocation.
Script-managed hosts (nagoya)
# Apply configuration for a specific host
sudo ./imperative/<hostname>/apply.sh
# With environment variables (e.g. wireguard key)
sudo WG_PRIVATE_KEY="..." ./imperative/<hostname>/apply.sh
Adding a New Host
Pick the approach that fits the machine:
Nix-managed (preferred)
- Add a
systemConfigs.<hostname>(system-manager) and/orhomeConfigurations."vdemeest@<hostname>"entry inflake.nix. - Create
imperative/<hostname>/bootstrap.shto install Nix and run the first activation. - Document the host in
imperative/<hostname>/README.md.
Script-managed (fallback)
- Create
imperative/<hostname>/apply.shfollowing the existing patterns:set -euo pipefailfor safety- Colored logging helpers (
log_info,log_warn,log_error) - Idempotent
setup.*functions
- Document the host in
imperative/<hostname>/README.md(system info, components, env vars, usage). chmod +x imperative/<hostname>/apply.sh.
Then update this README to list the new host.
Script Conventions
Bash scripts in this directory follow these conventions:
- Strict mode:
set -euo pipefail - Idempotency: check before mutating, guard re-runs, avoid destructive ops
- Function naming:
setup.*prefix (setup.docker,setup.wireguard, …) - Logging: colored
log_info/log_warn/log_errorhelpers - Environment variables: documented per-host, fail or warn gracefully when missing
- Linting: run
shellcheck imperative/<hostname>/apply.sh
Integration with NixOS / globals.nix
Even imperative hosts share the repo’s source of truth:
- WireGuard addressing follows the topology in
globals.nix(10.100.0.0/24) - Syncthing device IDs are coordinated via
globals.nixand accepted on other nodes - New keys/IDs generated on first activation should be written back into
globals.nix
Transitioning to Full NixOS
When migrating a host to NixOS:
- Use the imperative config as a reference for current state
- Create
systems/<hostname>and test in a VM - Perform the migration, then archive the imperative config
Comparison
| Aspect | Nix on host (aomi) | Bash script (nagoya) | Full NixOS (/systems) |
|---|---|---|---|
| Approach | Declare via Nix | Scripts to reach state | Declare desired state |
| Base OS | Any (Fedora, …) | Any Linux | NixOS only |
| Idempotency | Automatic | Manual (careful coding) | Automatic |
| Rollback | Per-generation (Nix) | Manual/difficult | Built-in generations |
| Reproducibility | High | Best effort | Guaranteed |