Instead of downloading at first login, everything is ready at boot:
- iso/build-live-iso.sh:
* apply-live-settings.sh XDG autostart applies theme/wallpaper/terminal
via gsettings at first Cinnamon login (reliable vs dconf binary format)
* /etc/environment: XDG_DATA_DIRS includes nix profile so Cinnamon menu
shows pre-baked nix apps immediately
* /etc/profile.d/nix-prebaked.sh: PATH setup for terminal sessions
* first-login.sh kept at /usr/local/libexec but NOT autostarted (manual
use for Claude/NVM installs)
* NIX_PACKAGES_PREBAKE passed to Docker build
- iso/_inner-build-live.sh:
* Pre-bake nix packages inside Docker before mklive.sh; copy /nix store
into squashfs overlay; set /etc/skel/.nix-profile → store profile path
* Cached at /cache/nix-prebake (keyed by package list md5)
- iso/Dockerfile: add rsync (needed by nix prebake)
- packages.live-desktop.list: add vscode + chromium (XBPS, no download)
void-installer — XPS 17 (xps9700)
Auto-installing Void Linux ISO targeted at a Dell XPS 17 9700 dual-booting Windows. Final installed system ships with: Cinnamon, Docker, VS Code, your SSH config, NVIDIA PRIME render-offload, and Nix for Spotify/Discord/LocalSend.
⚠️ Destructive. This installer wipes one partition. Read the Safety section before running on real hardware.
Layout produced
| What | Where |
|---|---|
Void root (btrfs @) |
/dev/nvme0n1p5 (replaces Mint) |
/home, /.snapshots, etc. |
btrfs subvolumes on the same device |
| EFI System Partition | /dev/nvme0n1p1 (shared, untouched) |
| GRUB target | \EFI\Void\ (Windows entry preserved) |
| Windows | /dev/nvme0n1p3 (left alone) |
Repo layout
config/install.conf # all knobs (hostname, locale, kbd, GPU, etc.)
config/packages.target.list # xbps packages installed into target
config/packages.live.list # extra packages added to the LIVE iso
secrets.env # USER_PASSWORD / ROOT_PASSWORD (gitignored)
installer/
install.sh # main entrypoint, runs in the live env
lib/ # tui, partition, bootstrap, grub, postinstall
iso/
build-iso.sh # host-side: stages overlay, then runs mklive in docker
_inner-build.sh # invoked inside the docker container as root
Dockerfile # debian:stable-slim + mtools/xorriso/squashfs-tools
patches/ # patches applied to upstream void-mklive
tests/
make-test-disk.sh # builds a qcow2 mimicking the XPS 17 partition table
run-qemu-test.sh # automated headless install + smoke tests
interactive-qemu.sh # GUI QEMU for manual exploration
lib/make-test-overlay.sh
Makefile # build / test entrypoints
Quick start
Build dependencies (host)
Any Linux with bash, git, curl, docker (and qemu + ovmf if you want to run
make test / make qemu). The mklive build runs inside a Debian container, so
you don't need mtools, xorriso, squashfs-tools, etc. on the host.
- Void:
xbps-install -S git curl docker qemu ovmf - Debian/Ubuntu/Mint:
apt install git curl docker.io qemu-system-x86 qemu-utils ovmf - Arch:
pacman -S git curl docker qemu-full edk2-ovmf
Make sure your user is in the docker group (sudo usermod -aG docker $USER,
then log out / back in) so the build runs without sudo.
1. Provide secrets
secrets.env is gitignored and pre-populated for you with the values from the
chat. Edit if you want different passwords.
2. Build the ISO
make iso
# -> out/void-install-xps9700-YYYYMMDD.iso
3. Test in QEMU (recommended before flashing!)
make test # full headless install + smoke tests (~15-30 min)
# or
make qemu # interactive QEMU window with the ISO booted
4. Flash to USB and boot the XPS 17
sudo dd if=out/void-install-xps9700-*.iso of=/dev/sdX bs=4M status=progress conv=fsync
Boot the XPS from the USB (F12 boot menu). The TUI shows detected partitions
with [WINDOWS] and [EFI] markers. Pick /dev/nvme0n1p5, type the device
path verbatim to confirm, and let it run.
Safety
- The installer refuses to wipe any NTFS partition.
- A TUI confirmation step requires you to type the full device path before any destructive action.
- The shared EFI partition is mounted read-write but never reformatted;
Windows boot files under
EFI/Microsoft/are preserved. - All passwords come from
/etc/installer-secrets.envbaked into the ISO at build time (mode0600). They are not on the network and not inargv.
If you want to be paranoid, run make test first — the smoke test asserts
that EFI/Microsoft/Boot/bootmgfw.efi survives the install on a simulated
disk with the same layout as the XPS.
Configuration
Everything tunable lives in config/install.conf:
- locale
en_US.UTF-8, keymapch-fr_nodeadkeys, timezoneEurope/Zurich - hostname
xps9700, usermozeinwheel,docker,video,audio,... - btrfs subvolumes
@,@home,@snapshots,@var_log,@var_cache - GPU mode
prime-offload(Intel UHD primary, NVIDIA GTX 1650 Ti viaprime-run) - zram swap at 50% RAM (zramen)
- nonfree + multilib + multilib-nonfree repos enabled
What's installed
xbps: base-system, linux, intel-ucode, NetworkManager, cinnamon, lightdm, docker, docker-compose, vscode (Microsoft), firefox, vlc, obs, flameshot, nvidia + nvidia-libs-32bit, pipewire, sudo, git, curl, vim, tlp, nix, … (full list in config/packages.target.list)
nix profile (first boot, as moze): spotify, discord, localsend.
The first-boot service runs once after nix-daemon is up, then exits.
Post-install
After first reboot:
- Log in as
moze(password:void). - The Cinnamon greeter appears (LightDM).
- The first-boot Nix service installs Spotify/Discord/LocalSend in the
background (~5–15 min depending on connection). Watch with
journalctl -fu first-boot-nixis replaced bytail -f /var/log/socklog/everything/currenton Void's runit; or just checknix profile listlater. - Run NVIDIA-accelerated apps with
prime-run <app>.
Test harness
tests/run-qemu-test.sh runs end-to-end:
- Builds a TEST ISO variant (overlay forces
UNATTENDED=1 TEST_MODE=1and bakes a one-off ssh keypair for the harness). - Builds a fresh
out/test-disk.qcow2with the same partition layout as the XPS (EFI + MSR + NTFS "Windows" placeholder + btrfs "Mint"). - Boots the ISO under QEMU/OVMF; installer runs unattended; VM powers off.
- Boots the installed disk; ssh's in as
moze; runs ~20 smoke assertions.
make test # default
TIMEOUT_INSTALL=5400 make test # slower hosts
ACCEL=tcg make test # no KVM (e.g., nested virt without)
Files of interest while debugging
| File on installed system | Purpose |
|---|---|
/var/log/void-installer.log |
full installer log |
/etc/sv/first-boot-nix/run |
one-shot nix profile installer |
/usr/local/bin/prime-run |
NVIDIA PRIME offload wrapper |
/etc/X11/xorg.conf.d/20-nvidia.conf |
NVIDIA display config |
/etc/runit/runsvdir/default/ |
enabled services |
| File on the live ISO | Purpose |
|---|---|
/usr/local/share/installer/ |
installer scripts + config + packages |
/etc/installer-secrets.env |
passwords (mode 0600) |
/etc/installer-ssh/ |
snapshot of build-host ~/.ssh/ |
Caveats
- 150 MB shared EFI is tight (was 91 % full before install). Void puts only
\EFI\Void\grubx64.efi(~150 KB) there; kernels live on btrfs/boot. - Secure Boot is off (per the input). NVIDIA proprietary modules won't load with SB on without manual MOK enrollment.
- The installer assumes
/dev/nvme0n1p5is currently Linux Mint (btrfs). If that ever changes, the TUI default will be wrong but the listing is always live, and the confirmation step prevents accidents.