Deploying Guix on Linode has a documented route: start from Linode’s built-in Debian image and convert it into a Guix system. David Thompson, a Guix developer, wanted the other thing: a disk image that is ready to go, uploaded once. He wrote it up while moving his own server between providers, and the whole recipe is in the post, with the OS config in a public repository.

What the image does

On boot it mounts the right devices for root and swap, then resizes the root filesystem to fill the volume, a custom service because Guix’s own resize service makes assumptions that do not hold in this environment. It starts SSH with a public key and no password login, allows passwordless sudo so guix deploy works from another machine, and authorizes signing keys so other Guix machines can push store items to it from the start. It also takes an IPv6 address over DHCP alongside IPv4, with a SLAAC setting the default config does not use, and the base config carries a default-deny nftables firewall.

Lower down, the initial RAM disk carries the virtual disk modules Linode attaches, and the bootloader files are installed where Linode expects to find them (GRUB’s modules and a font, copied onto the root filesystem), since running grub-install against the boot device the usual way does not work here.

Building and uploading

The image comes out of guix system image --image-type=mbr-raw, which gets most of the way there but not quite. The config evaluates to the operating system in batch mode, which is what lets the image build straight from the repository. Linode wants an image that only contains the root partition, so the packing script skips the first megabyte with dd (eight blocks of 128K) and gzips the result, a Linode requirement rather than a preference. One more trap waits at first boot: Linode’s default configuration profile kernel-panics, and it takes two changes before the server comes up, choosing GRUB 2 as the kernel and turning off every filesystem and boot helper switch.

After that

The server boots, guix deploy takes over updates over SSH, and the machine stays declarative from then on. The conversion route in the cookbook remains for anyone starting from an existing Debian box, and Thompson notes the cookbook has not been updated with this route yet, so the post and the config repository are the working documentation for now.

My read

The value is in the undocumented parts: which GRUB Linode boots, how much of the image to cut away, and the two switches between an upload and a kernel panic. That knowledge usually lives in one person’s shell history. A post and a public config repo are exactly where it should live instead.

Source: Deploying Guix images on Linode and the config repository.