Table of Contents

GNU Guix System

GNU Guix System is a distribution where the system, services, and packages are described declaratively in Guile Scheme. Like NixOS, it creates system generations when the configuration changes and lets you return to an earlier generation.

How the template works

The vpsFree template contains a minimal Guix System with OpenSSH and two files:

system.scm loads the vpsadminos module from the second file. Keep this connection: it defines the container bootloader, file systems, and the service which applies the network configuration generated by vpsAdminOS during boot. The current versions of both files are available in the Guix template sources.

The kernel is managed by vpsAdminOS. Do not add your own Linux kernel or a bootloader intended for a physical machine to the configuration.

Editing the configuration

Start by editing /etc/config/system.scm. You can change the host name, packages, and services, for example. Keep %ct-services, %ct-file-systems, and %ct-bootloader from the vpsadminos module.

Activate the configuration as root:

#!/usr/bin/env bash
set -eo pipefail
 
# Use the Guix revision that built the active system generation.
export GUIX_PROFILE=/run/current-system/profile
# shellcheck disable=SC1091
. "$GUIX_PROFILE/etc/profile"
hash guix
 
test -r /etc/config/system.scm
test -r /etc/config/vpsadminos.scm
test -r /run/current-system/channels.scm
guix time-machine -C /run/current-system/channels.scm -- \
  system reconfigure -L /etc/config /etc/config/system.scm

guix time-machine uses the channels recorded in the active generation, so reconfiguration does not depend on later channel-history changes. The -L /etc/config option makes the vpsadminos module available. The command builds and immediately activates a new generation. Before logging out, verify that SSH and the services you need are running. See the manuals for guix time-machine and guix system for details.

Updating Guix

The example above selects the Guix revision and channels that built the active system generation. Reconfiguration therefore does not require guix pull before every configuration change, keeping repeated deployments predictable.

When you intentionally update Guix, first record the current channels with guix describe. Then run guix pull, load the updated profile as instructed by the command, and reconfigure again. Read the news before changing revisions, and allow extra time, memory, and disk space for the build. The channels manual explains channels and pinned revisions.

Network and SSH

Do not configure the primary network with static-networking-service-type. At every boot, vpsAdminOS creates /ifcfg.add from the current addresses and the vpsadminos-networking service runs it. Add any custom networking services on top of this layer.

For convenient first access, the default template permits SSH login as root. Once your keys work, you can harden access as described in SSH.

Deploying with guix deploy

If you manage several Guix VPSes, you can keep their configurations on one coordinator Guix system and deploy them with guix deploy. The complete configuration below is a starting point for one VPS. You maintain only deploy.scm; the container details continue to come from the maintained /etc/config/vpsadminos.scm module.

The coordinator needs the SSH key /root/.ssh/id_ed25519, and you must add its public part to root on the target VPS before the first deployment. Test key-only login first. Run cat /etc/ssh/ssh_host_ed25519_key.pub on the target VPS and verify the resulting key fingerprint by following the SSH guide. The configuration needs the whole line beginning with ssh-ed25519, not just the fingerprint.

Save this configuration as /etc/config/deploy.scm on the coordinator and replace the target VPS address and host key:

;; Load the maintained vpsAdminOS container integration.
(add-to-load-path "/etc/config")
(use-modules (vpsadminos)
             (gnu)
             (gnu machine)
             (gnu machine ssh)
             (gnu services base))
(use-package-modules nss ssh)
(use-service-modules ssh)
 
;; These files belong to the machine from which you run guix deploy.
(define %controller-signing-key
  (local-file "/etc/guix/signing-key.pub"))
(define %root-ssh-key
  (local-file "/root/.ssh/id_ed25519.pub"))
 
(define %system
  (operating-system
    (host-name "guix-target")
    (timezone "Etc/UTC")
    (locale "en_US.utf8")
    (firmware '())
    (initrd-modules '())
    (kernel %ct-dummy-kernel)
 
    (packages (cons* nss-certs
                     %base-packages))
 
    (essential-services
     (modify-services
         (operating-system-default-essential-services this-operating-system)
       (delete firmware-service-type)
       (delete (service-kind %linux-bare-metal-service))))
 
    (bootloader %ct-bootloader)
    (file-systems %ct-file-systems)
 
    (services
     (cons* (service openssh-service-type
                     (openssh-configuration
                      (openssh openssh-sans-x)
                      (permit-root-login 'prohibit-password)
                      (password-authentication? #f)
                      (authorized-keys
                       `(("root" ,%root-ssh-key)))))
            (simple-service 'controller-signing-key
                            guix-service-type
                            (guix-extension
                             (authorized-keys
                              (list %controller-signing-key))))
            %ct-services))))
 
(define %machine
  (machine
    (operating-system %system)
    (environment managed-host-environment-type)
    (configuration
     (machine-ssh-configuration
      ;; Replace the address and host key with those of your target VPS.
      (host-name "192.0.2.3")
      (system "x86_64-linux")
      (user "root")
      (identity "/root/.ssh/id_ed25519")
      (host-key "ssh-ed25519 REPLACE_WITH_TARGET_HOST_KEY")
      (authorize? #t)
      (allow-downgrades? #f)
      ;; vpsAdminOS supplies the kernel and exposes a dummy /dev/null root.
      ;; Guix's bare-metal file-system/initrd checks cannot inspect it.
      (safety-checks? #f)))))
 
(list %machine)

First load the configuration without deploying it with guix time-machine -C /run/current-system/channels.scm – deploy -L /etc/config /etc/config/deploy.scm –dry-run. Then run the same command without –dry-run. The first deployment automatically authorizes the coordinator's signing key on the target, and the declaration keeps it authorized in the new generation.

The configuration deliberately allows only key-based root login and verifies the target host key. The container-specific safety-checks? #f disables Guix checks for physical file systems and initrd modules: vpsAdminOS supplies the kernel and its integration module exposes a dummy /dev/null root which current Guix cannot inspect. Downgrade protection stays enabled. If deployment fails, fix its cause instead of enabling allow-downgrades?.

Generations and recovery

List generations with guix system list-generations. Verify the new system before deleting older generations. The Guix manual describes rollback and generation management.

If a new configuration does not boot or you lose SSH access, follow the remote console guide. The vpsAdminOS start menu guide explains how to restore an older Guix generation. Fix the configuration and reconfigure again.