main
..
rw-r--r--
5.5 KB

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:

  1. Nix on top of the host OS — using the Determinate Nix installer with system-manager (system services) and home-manager (user environment). This is the current, preferred approach. See aomi and nagoya.
  2. Idempotent bash scripts — self-contained apply.sh scripts that bring a host to the desired state. Kept as a fallback / bootstrap aid (e.g. the legacy nagoya apply.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 idempotent apply.sh bash 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.sh script 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)

  1. Add a systemConfigs.<hostname> (system-manager) and/or homeConfigurations."vdemeest@<hostname>" entry in flake.nix.
  2. Create imperative/<hostname>/bootstrap.sh to install Nix and run the first activation.
  3. Document the host in imperative/<hostname>/README.md.

Script-managed (fallback)

  1. Create imperative/<hostname>/apply.sh following the existing patterns:
    • set -euo pipefail for safety
    • Colored logging helpers (log_info, log_warn, log_error)
    • Idempotent setup.* functions
  2. Document the host in imperative/<hostname>/README.md (system info, components, env vars, usage).
  3. 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_error helpers
  • 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.nix and 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:

  1. Use the imperative config as a reference for current state
  2. Create systems/<hostname> and test in a VM
  3. 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