Skip to content

Kexec

Boot a NixOS installer image on the target without physical access, by replacing the running kernel in memory.

Kexec loads a new kernel and initramfs directly into memory, bypassing the BIOS/UEFI boot process. Once in the installer environment, disko can repartition the disks and the NixOS bootstrap flow continues: transfer the closure (kexec does not reuse the previous one), run nixos-install, and reboot into the freshly installed system.

After kexec starts, Panix reconnects using the same SSH settings as before (hostname, username, identity_file) and the port from kexec.ssh_port (default: 22 for the default kexec image).

If your custom kexec installer uses a different SSH port, configure it:

bootstrap:
kexec:
ssh_port: 22222 # Custom SSH port for kexec installer

You can provide a custom kexec tarball:

bootstrap:
kexec:
image: https://example.com/custom-kexec-$PANIX_ARCH.tar.gz # Optional custom image tarball (default: https://github.com/nix-community/nixos-images/releases/latest/download/nixos-kexec-installer-noninteractive-$PANIX_ARCH-linux.tar.gz);
# $PANIX_ARCH is expanded from the detected machine architecture
extra_flags: # Optional flags passed to kexec (default: "")
- "--no-sync"
ssh_port: 22 # Optional kexec ssh port (default: 22)

For machines without internet access or for faster deployments, download the kexec tarball locally and Panix will transfer it instead of downloading it remotely.

Download locally:

Terminal window
export ARCH=x86_64 # or aarch64
curl -L -o ./kexec-$ARCH.tar.gz \
https://github.com/nix-community/nixos-images/releases/latest/download/nixos-kexec-installer-noninteractive-$ARCH-linux.tar.gz

Configure in panix.yml:

Fragment: nest under fleet.flakes.<flake>.installables.<type>.<name>.machines.

machines:
my-machine:
ssh:
hostname: 192.168.1.100
bootstrap:
kexec:
image: ./kexec-$PANIX_ARCH.tar.gz # $PANIX_ARCH expanded from detected architecture

The $PANIX_ARCH variable is replaced with the detected architecture (e.g. x86_64). Unknown PANIX_* variables, and known ones that are not available in the current context, fail the deployment with an error. Panix detects whether image is a local path or an HTTP URL: local paths are transferred via rsync (which needs a modern rsync, see Requirements), URLs trigger a remote download with curl.