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.
The vpsFree template contains a minimal Guix System with OpenSSH and two files:
/etc/config/system.scm is your main system configuration;/etc/config/vpsadminos.scm makes Guix work inside a vpsAdminOS container.
system.scm resolves %ct-operating-system-base from the vpsadminos
module and inherits it. Keep the module lookup and inheritance: the platform
base provides the container bootloader, file systems, kernel placeholder,
packages, services, and network integration. 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.
Start by editing /etc/config/system.scm. The host name, timezone, and locale
are visible there as defaults that you can change. You can also add fields such
as packages, which Guix evaluates directly. Keep the platform-system
lookup and (inherit platform-system) so the platform-specific settings
remain active.
When changing services, first derive and bind the service list outside the
operating-system record, then assign that binding to the services field.
The deployment example below follows this pattern. Guix evaluates service
fields after loading the configuration, so they must not depend on bindings
from its temporary configuration 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.
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.
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.
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 (gnu) (gnu machine) (gnu machine ssh) (gnu services base)) (use-service-modules ssh) (let* ((platform-system (module-ref (resolve-interface '(vpsadminos)) '%ct-operating-system-base)) ;; These files belong to the machine from which you run guix deploy. (controller-signing-key (local-file "/etc/guix/signing-key.pub")) (root-ssh-key (local-file "/root/.ssh/id_ed25519.pub")) ;; Build the service list before assigning the delayed services field. (user-services (cons (simple-service 'controller-signing-key guix-service-type (guix-extension (authorized-keys (list controller-signing-key)))) (modify-services (operating-system-user-services platform-system) (openssh-service-type config => (openssh-configuration (inherit config) (permit-root-login 'prohibit-password) (password-authentication? #f) (authorized-keys `(("root" ,root-ssh-key)))))))) (system (operating-system (inherit platform-system) (host-name "guix-target") (timezone "Etc/UTC") (locale "en_US.utf8") (services user-services))) (target-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 target-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?.
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.