Hey there,

Quick post to report back on my experiment with guix on a Vultr VPS.

There are 2 options to get a Guix system running:

Custom ISO

From your Vultr panel you need to add a custom iso, simply points it toward the guix installer iso.

Then on your VPS go to server details -> and look for isos, attach your iso.

Now this is all good if you want to do things manually but what about something more automatable?

Vultr snapshot and guix images

Fortunately Vultr allows you to bring in your own snapshots.

As of 2023 Guix does not provide an equivalent of Preseed/Kickstart or answers file so that’s why we’re not going to make an iso using that feature.

The only way for you to make a pre-made system is via the guix system image api.

The workflow is like this:

  1. Generate an image with the api (in our case we will need to generate an efi-raw image as the vultr snapshot feature only accept those, which is a shame as they do take more space than qcow2)

  2. Upload that image to a bucket on scaleway or something equivalent (see vultr snapshot page for more info on what link are accepted.)

  3. Download that image on Vultr, it can take quite a while depending on the size of the image.

  4. On your vps panel look for snapshot, and simply attach the snapshot you downloaded, it will restart with your snapshot and everything should be good.

Creating the image

Here is a sample os.scm:

(use-modules (gnu))

(use-service-modules networking ssh admin virtualization sysctl web)

(use-package-modules bootloaders ssh certs tls python)

(operating-system
 (bootloader
  (bootloader-configuration
   (bootloader grub-bootloader)
   (targets (list "/dev/vda"))
   (terminal-outputs (quote (console)))))

 (host-name "web")

 (sudoers-file (plain-file "sudoers" "\
 root ALL=(ALL) ALL
 %wheel ALL=(ALL) NOPASSWD: ALL
 "))

 (timezone "Etc/UTC")
 (kernel-arguments (list "console=ttyS0,115200"))

 ;; Using vda2 here, because on an efi-raw image, vda1 is a boot partition

 (file-systems (cons*
              (file-system (mount-point "/")
                           (device "/dev/vda2")
                           (type "ext4"))
              %base-file-systems))
 (users (cons*
       (user-account
        (name "guix")
        (comment "guix")
        (group "users")
        (supplementary-groups (quote ("wheel")))
        (home-directory "/home/guix"))
       %base-user-accounts))

 (packages (cons* nss-certs gnutls python %base-packages))

 ;; TODO: Add mcron job to garbage collect the store.
 (services (append (list
                  (service dhcp-client-service-type)
                  (service unattended-upgrade-service-type)
                  (service openssh-service-type
                           (openssh-configuration
                            (openssh openssh-sans-x)
                            (permit-root-login #f)
                            (authorized-keys (quasiquote
                                              (((unquote "guix")
                                                (unquote
                                                 (plain-file "key.pub" "REPLACE_ME"))))))))
                  (service nginx-service-type
                           (nginx-configuration
                            (server-blocks
                             (list
                              (nginx-server-configuration
                               (listen (quote ("80")))
                               (server-name (quote ("REPLACE_ME")))
                               (root "REPLACE_ME")))))))
                 %base-services)))

Adjust the settings as you need, note that there is a chicken and egg problem if you activate both nginx and certbot at the same time.

Nginx will fail to activate because the certificates are not there yet(that is if you run with 443 ssl, if you just want a quick test simply override the listen field of the nginx config to only listen on port 80) and Certbot will not actually immediately fetch the certificates, it will make a cron job to do that and that can be set at midnight or later.

If you want to get the certificates immediately you’ll need to run manually with sudo the /var/lib/certbot/renew-certificates scripts.

To create an image from os.scm run:

# size is in bytes, ~10gb
guix system image --image-type=efi-raw --image-size=10737418240 os.scm

Now this will creates an image in your store, you will need to copy it manually where you want and give it write permissions if you want to run the vm locally with qemu.

Upload the image

I chose scaleway because they offer ~70gb for free in object storage.

You can do everything by the gui so not much to say there, just don’t forget to configure the visibility of the object to public.

Download from vultr

Products -> Snapshots -> Add Snapshot -> Upload snapshot from remote machine

Then:

Products -> your vps -> snapshots -> restore

Conclusion

Well you should have a guix system running, it’s working okayish for me at the moment.

I have the cheapest vps, so guix pull are incredibly slow, and I had some weird hangs where I had to hard reboot the machine via the ui of Vultr.

From what I could gather, this is caused by shepherd becoming unresponsive, in my case it was because syslog was eating 100% cpu so I had to pkill it via the kvm console.