Installation & Workflow Setup
NXD is consumed as a flake input by your existing Nix configuration repository. It does not need to be installed globally, and it does not take ownership of your repository layout.
Pre-release. Pin an exact revision and read a plan before applying it. Interfaces still change between revisions.
1. Pin NXD in your flake
{
description = "Homelab Nix system configuration";
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-26.05";
nxd = {
# Pin an exact revision. `nix flake update nxd` moves it deliberately.
url = "github:lamtt77/nxd";
};
};
outputs = { self, nixpkgs, nxd, ... }: {
nxdConfigurations.default = nxd.lib.evalConfiguration {
modules = [ ./nxd/site.nix ];
};
};
}
evalConfiguration is the stable entry point. evalConfigurationUnstable
exists for schemas still in development and may change without notice.
2. Try it against fixtures first
Before pointing NXD at real infrastructure, run it against checked-in synthetic fixtures. Nothing here contacts a provider or resolves a secret:
nix develop
cargo run -- validate --config-json tests/fixtures/canonical/minimal-site.json --format json
cargo run -- show config --config-json tests/fixtures/canonical/minimal-site.json
3. Run against your own site
# Evaluate and inspect the action graph — no mutation
nix run .#nxd -- plan medo --source ".#nxdConfigurations.default"
# Apply a system closure to a live host
nix run .#nxd -- switch medo --source ".#nxdConfigurations.default"
# Re-enroll a node whose endpoint moved out of band
nix run .#nxd -- switch medo=203.0.113.48 --reenroll --source ".#nxdConfigurations.default"
# Machine-readable output for CI or a coding agent
nix run .#nxd -- plan medo --source ".#nxdConfigurations.default" --format json
Read the plan before approving it. Destructive and identity-critical actions are listed first, with the exact resources they touch.
4. Faster local iteration
nix run rebuilds on every invocation. For a tight loop, build the CLI once and
point NXD_BIN at it:
nix develop
cargo build -p nxd-cli
export NXD_BIN="$PWD/target/debug/nxd"
"$NXD_BIN" plan medo --source ".#nxdConfigurations.default"
just check # workspace checks before committing
5. What a managed target needs
| Requirement | Detail |
|---|---|
| OpenSSH | Reachable, with an Ed25519 host key NXD can pin |
| Deployment user | Key-based SSH plus passwordless sudo (or root) |
| Nix | Flake support enabled — except on a fresh install target, which NXD provisions |
The orchestrator additionally needs the SOPS/age identity that decrypts your secrets. NXD resolves bindings at apply time; it never reads secrets during evaluation.
6. Build placement
By default NXD chooses where each closure is built. You can be explicit when the target cannot build for itself:
- On a builder — the usual choice for low-memory or slow targets. The target receives store paths and compiles nothing.
- On the orchestrator — when it can realize the target’s system.
- On the target — when it is the most capable machine available.
Declare builders with builderBySystem rather than relying on an ambient
/etc/nix/machines. NXD deliberately does not inherit ambient builder
configuration, so placement stays visible in your repository.
Next steps
- Technical manual — architecture, safety model, and full reference.
- Features — what NXD manages, per provider.
- Compatibility — verified platforms and versions.