Guix System installer. Boot a Guix ISO, run one binary, get a working system — libre Guix, Nonguix, PantherX, or an enterprise config from a server.
The existing Python installer (px-install) had gotten hard to live with — partitioning tangled into config generation, no resume on failure, four modes bolted on with conditionals. Rewrote it in Rust with the install mode as the central axis.
Pre-1.0. Runs end-to-end on the machines I've tested. Read what it's about to do before you let it touch your disk. --dry-run prints the generated system.scm (+ channels.scm) without partitioning anything.
Prebuilt static x86_64 binaries (musl, no runtime deps) are attached to each GitHub release so you can use this on a plain Guix ISO without building anything.
| Channel | Kernel | Notes |
|---|---|---|
guix |
linux-libre | Hardware preflight warns about Wi-Fi/GPU/Ethernet needing non-free firmware. |
nonguix |
linux + microcode | substitutes.nonguix.org key compiled in. |
panther (default) |
linux + microcode | Pulls nonguix transitively. Inherits %os-base from (px system os). substitutes.guix.gofranz.com key compiled in. |
enterprise |
from remote | Fetches a tarball over HTTPS by config ID. Skips locale/timezone/hostname/users/desktop. |
guix shell rust rust:cargo gcc-toolchain -- sh -c "CC=gcc cargo build --release"
# or
guix shell -m manifest.scm -- cargo build --releaseOn the PantherX ISO the binary is pre-installed — just run:
guix-installLatest PantherX ISO (2.2 GB, BIOS + UEFI, x86_64):
https://temp.pantherx.org/1xnvrrk5n25llks8pjx64f2kb3nfasn4-image.iso
Hash (Guix nix-base32, SHA-256): 0vvnfzw6y52z1qd2k60jcxw9r5y9mfvp9s1p4nj53ii4l3gyhbmg
On a plain Guix ISO (or anywhere else), grab the static musl binary from a release:
curl -L -o guix-install \
https://github.com/franzos/guix-install/releases/latest/download/guix-install-x86_64-linux-musl
chmod +x guix-install
./guix-installWalks through Mode → Locale → Timezone → Hostname → Disk → Encryption → Users → Desktop → Summary. Escape goes back a step. Enterprise mode collapses the middle to just Disk + Encryption.
Dry run (no disk touched):
guix-install --dry-run --mode nonguix --hostname mybox --disk /dev/sda \
--filesystem btrfs --encrypt --desktop gnomeCommon flags:
| Flag | Default | |
|---|---|---|
--mode |
panther |
guix, nonguix, panther, enterprise |
--hostname |
<mode>-<6 random> |
|
--timezone |
Europe/Berlin |
|
--locale |
en_US.utf8 |
|
--disk |
/dev/sda |
|
--filesystem |
ext4 |
or btrfs |
--encrypt |
off | LUKS on / |
--username |
panther |
login name for the primary user |
--keyboard |
none | layout, e.g. us, de |
--desktop |
none | gnome, kde, xfce, mate, sway, i3, lxqt |
--swap |
4096 MB |
swap file size |
--ssh-key |
none | dropped into the user's authorized_keys |
--config <ID> |
implies --mode enterprise |
|
--config-url |
https://temp.pantherx.org/install |
enterprise base URL |
--dry-run |
off | print scheme, do nothing |
Subcommands:
guix-install list-disks # lsblk-style summary
guix-install wifi # connmanctl WiFi setup8 phases, state persisted to /tmp/.guix-install-state after each:
- Partition (parted, BIOS/EFI auto-detected from
/sys/firmware/efi) - Format (ext4/btrfs, optional LUKS)
- Mount under
/mnt - Swap file
- Generate
system.scm+channels.scm(or fetch enterprise tarball) - Authorize substitute servers
guix pull(skipped for plain Guix)guix system init, set user password
Re-running picks up at the failed phase. Change disk/mode/firmware and state is discarded.
- Passwords never land in
system.scm. SHA-512-crypted in-process, atomically written to/mnt/etc/shadow(sibling-write + fsync + rename + dir fsync). Plaintext held inZeroizing<String>. Nochroot/chpasswd. - Substitute keys compiled in via
include_str!. - Enterprise tarballs streamed through
ureq → flate2 → tar. No intermediate file. - Partition naming handles NVMe/MMC (
/dev/nvme0n1p1) vs SATA (/dev/sda1) viadisk::partition_path. - UI is a trait (
UserInterface). REPL usesdialoguer; TUI/GUI plug in without touching step logic.
Three layers of testing, in order of how often I run them.
1. Unit + golden tests. Pure-Rust assertions on the action sequences and the rendered scheme. Covers the 2×2×2×4 matrix (firmware × encryption × filesystem × mode). Fast.
guix shell rust rust:cargo gcc-toolchain -- sh -c "CC=gcc cargo test"2. Scheme validation. Pipes each generated system.scm through guix time-machine ... system build -d to confirm Guix actually accepts it. #[ignore]d by default — first run is slow.
guix shell guix -- cargo test --test scheme_validate -- --ignored3. Guided VM install (Claude Code). The /guix-install-test skill drives a QEMU VM end-to-end: builds the binary, boots a Guix ISO, copies the binary in over SSH, and walks through real install scenarios (mode × filesystem × encryption × firmware) with reboots between cycles. Use it when changing partition / format / mount / cow-store / pull / system-init paths.
/guix-install-test
Format:
podman run --rm -v $PWD:/work -w /work rust:latest \
sh -c "rustup component add rustfmt && cargo fmt"