<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title>Ryan Campbell</title><id>https://campbellr.ca/feeds/tags/proxmox.xml</id><subtitle>Tag: proxmox</subtitle><updated>2026-05-01T02:12:19Z</updated><link href="https://campbellr.ca/feeds/tags/proxmox.xml" rel="self" /><link href="https://campbellr.ca" /><entry><title>Installing Guix System on Proxmox LXC</title><id>https://campbellr.ca/blog/installing-guix-system-on-proxmox-lxc.html</id><author><name>Ryan Campbell</name></author><updated>2026-04-26T16:00:00Z</updated><link href="https://campbellr.ca/blog/installing-guix-system-on-proxmox-lxc.html" rel="alternate" /><content type="html">&lt;p&gt;I use &lt;a href=&quot;https://www.proxmox.com/en/&quot;&gt;Proxmox&lt;/a&gt; for hosting most of my personal
services, and since I've been writing a lot of &lt;a href=&quot;https://www.gnu.org/software/guile/&quot;&gt;Guile
Scheme&lt;/a&gt; lately, I wanted a lightweight
Guix System container for hosting &lt;a href=&quot;/projects/scrap.html&quot;&gt;scrap&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Specifically, I want a fully working Guix System inside an unprivileged LXC
container that behaves as close to a bare-metal install as possible. It's not
enough to just have a static image, &lt;code&gt;guix system reconfigure&lt;/code&gt; and everything
else should work from inside the container.&lt;/p&gt;&lt;p&gt;There's not a lot of good information on how to do this, and what does exist
seems to be a bit stale.&lt;/p&gt;&lt;p&gt;It turned out to be &lt;em&gt;much&lt;/em&gt; more work than I had anticipated.&lt;/p&gt;&lt;p&gt;Posting this all here for my future self, or in the off chance that someone
else stumbles upon this while trying to solve the same problem.&lt;/p&gt;&lt;h2&gt;Problem 1: Guix doesn't do FHS&lt;/h2&gt;&lt;p&gt;This isn't a surprise, and isn't really a &lt;em&gt;problem&lt;/em&gt;, but it does mean that the
default Proxmox LXC configuration doesn't know how to boot a standard guix
image.&lt;/p&gt;&lt;p&gt;Most guides for running Guix in LXC (including &lt;a href=&quot;https://www.thedroneely.com/posts/guix-in-a-linux-container/&quot;&gt;this otherwise excellent
one&lt;/a&gt;) hardcode
specific &lt;code&gt;/gnu/store/...&lt;/code&gt; paths in the container config. They set
&lt;code&gt;lxc.init.cmd&lt;/code&gt; to something like:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;/gnu/store/vbcdwklck7cd28j4jv9wchfw60abivfd-guile-3.0.9/bin/guile \
  /gnu/store/hgi3i9ydjhi5bxnpz7zmzaqn60iw3ak1-boot&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This works fine, particularly if you are just spinning up a one-off container.&lt;/p&gt;&lt;p&gt;But it is something you need to remember to edit in &lt;code&gt;/etc/pve/lxc/&amp;lt;CTID&amp;gt;.conf&lt;/code&gt;
&lt;em&gt;every time you spin up a new container&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;And as soon as you run &lt;code&gt;guix system reconfigure&lt;/code&gt;, or update the
daemon and the store gets garbage collected -- the container refuses to start.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; use &lt;code&gt;program-file&lt;/code&gt; to build a small Guile script that resolves
&lt;code&gt;/var/guix/profiles/system&lt;/code&gt; at boot time, sets &lt;code&gt;GUIX_NEW_SYSTEM&lt;/code&gt;, and &lt;code&gt;execl&lt;/code&gt;s
the correct Shepherd boot script. Then use &lt;code&gt;special-files-service-type&lt;/code&gt; to
symlink it to &lt;code&gt;/sbin/init&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;%lxc-special-files&lt;/span&gt;
  &lt;span class=&quot;syntax-symbol&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;/sbin/init&amp;quot;&lt;/span&gt;
     &lt;span class=&quot;syntax-symbol&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;program-file&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;lxc-init&amp;quot;&lt;/span&gt;
                    &lt;span class=&quot;syntax-symbol&quot;&gt;#~&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;begin&lt;/span&gt;
                        &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;setenv&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;HOME&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;/root&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                        &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;let*&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;system&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;canonicalize-path&lt;/span&gt;
                                        &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;/var/guix/profiles/system&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                               &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;guile&lt;/span&gt;  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;string-append&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;system&lt;/span&gt;
                                         &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;/profile/bin/guile&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                               &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;boot&lt;/span&gt;   &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;string-append&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;system&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;/boot&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                          &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;setenv&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;GUIX_NEW_SYSTEM&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                          &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;execl&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;guile&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;guile&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;boot&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;/bin/sh&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;file-append&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;bash&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;/bin/sh&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;/usr/bin/env&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;file-append&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;coreutils&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;/bin/env&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;From the outside the container now looks like any FHS-compatible distro:
Proxmox execs &lt;code&gt;/sbin/init&lt;/code&gt;, which always resolves the &lt;em&gt;current&lt;/em&gt; generation.
Reconfigure changes the profile symlink, and the next boot picks it up
automatically.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Catch:&lt;/strong&gt; &lt;code&gt;special-files-service-type&lt;/code&gt; creates these symlinks during
activation. Activation runs &lt;em&gt;after&lt;/em&gt; PID 1 starts. PID 1 &lt;em&gt;is&lt;/em&gt; &lt;code&gt;/sbin/init&lt;/code&gt;. So
on first boot, &lt;code&gt;/sbin/init&lt;/code&gt; needs to exist before the thing that creates it can
run, which is a bit of chicken-and-egg situation.&lt;/p&gt;&lt;p&gt;We work around &lt;em&gt;that&lt;/em&gt; by manually injecting a stub that gets replaced on first
boot.&lt;/p&gt;&lt;h2&gt;Problem 2: &lt;code&gt;guix system init&lt;/code&gt; doesn't work in 2026 (for container images)&lt;/h2&gt;&lt;p&gt;Most instructions on the web suggest using &lt;code&gt;guix system init&lt;/code&gt;. But
unfortunately as of 2026, it can no longer produce a usable LXC rootfs due to
the addition of some extra checks that require a valid filesystem, so filling
it in with a &amp;quot;dummy&amp;quot; filesystem fails.&lt;/p&gt;&lt;p&gt;The problem:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;&lt;code&gt;store-file-system&lt;/code&gt; (in &lt;code&gt;gnu/system.scm&lt;/code&gt;) filters &lt;code&gt;file-systems&lt;/code&gt; for
&lt;code&gt;(mount? #t)&lt;/code&gt; and crashes with a match error if the result is empty. Any
&lt;code&gt;(mount? #f)&lt;/code&gt; dummy root crashes before it does anything useful.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;With &lt;code&gt;(mount? #t)&lt;/code&gt;, &lt;code&gt;check-file-system-availability&lt;/code&gt; tries to &lt;code&gt;stat()&lt;/code&gt; the
device or look up the partition label against the &lt;em&gt;host's&lt;/em&gt; block devices at
build-time. Nothing works: &lt;code&gt;/dev/null&lt;/code&gt; errors, made-up paths error, labels
don't exist on the host.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Even past those checks, shepherd unconditionally calls &lt;code&gt;mount(2)&lt;/code&gt; for every
&lt;code&gt;(mount? #t)&lt;/code&gt; file-system. The container's &lt;code&gt;/&lt;/code&gt; is already mounted by LXC --
it would either be clobbered (tmpfs) or the syscall would fail.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;There doesn't seem to be any way to provide a dummy/stub filesystem that will
satisfy &lt;code&gt;guix system init&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; use &lt;code&gt;guix system image -t tarball&lt;/code&gt; instead. It builds in a sandbox
where the root filesystem is synthesized (&lt;code&gt;image-&amp;gt;root-file-system&lt;/code&gt; in
&lt;code&gt;gnu/system/image.scm&lt;/code&gt; rewrites the root type to &lt;code&gt;&amp;quot;dummy&amp;quot;&lt;/code&gt;), so the host's
block devices never get involved.&lt;/p&gt;&lt;p&gt;We do still declare a root filesystem with &lt;code&gt;(mount-may-fail? #t)&lt;/code&gt; in the config
because at boot shepherd will attempt the mount, fail (the host filesystem
isn't labelled &lt;code&gt;Guix&lt;/code&gt;), and we don't want that to abort boot.&lt;/p&gt;&lt;p&gt;Why &lt;code&gt;tarball&lt;/code&gt; and not &lt;code&gt;docker&lt;/code&gt;? &lt;code&gt;image -t docker&lt;/code&gt; applies
&lt;code&gt;containerized-operating-system&lt;/code&gt; automatically -- it swaps the kernel, drops
console services, replaces networking with &lt;code&gt;dummy-networking-service-type&lt;/code&gt;, and
wraps the output in a docker manifest.&lt;/p&gt;&lt;p&gt;That's too docker-specific though (as you would expect from the name). It
strips things we might actually want (like &lt;code&gt;/dev/shm&lt;/code&gt; and &lt;code&gt;/gnu/store&lt;/code&gt; mounts
that work fine in unprivileged LXC) and adds a manifest wrapper we'd have to
discard. &lt;code&gt;tarball&lt;/code&gt; emits a flat rootfs directly usable by &lt;code&gt;pct create&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;So we have to replicate the relevant subset of &lt;code&gt;containerized-operating-system&lt;/code&gt; by
hand.&lt;/p&gt;&lt;h2&gt;Problem 3: Hardware-related services need to be removed&lt;/h2&gt;&lt;p&gt;There are a bunch of things that aren't relevant to a container (firmware,
kernel, hardware-related services, etc...) that we have to remove:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;code&gt;firmware-service-type&lt;/code&gt; -- activation fails because &lt;code&gt;/proc&lt;/code&gt; and &lt;code&gt;/sys&lt;/code&gt; are
partially masked&lt;/li&gt;&lt;li&gt;&lt;code&gt;%linux-bare-metal-service&lt;/code&gt; -- tries to run &lt;code&gt;modprobe&lt;/code&gt; etc.&lt;/li&gt;&lt;li&gt;&lt;code&gt;host-name-service-type&lt;/code&gt; -- would clobber the hostname Proxmox injects via
&lt;code&gt;lxc.uts.name&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;hosts-service-type&lt;/code&gt; -- creates a read-only &lt;code&gt;/etc/hosts&lt;/code&gt; with the &amp;quot;wrong&amp;quot;
hostname -- we want to pick up the hostname provided by Proxmox/LXC&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; delete them from &lt;code&gt;essential-services&lt;/code&gt; using &lt;code&gt;modify-services&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;essential-services&lt;/span&gt;
 &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;modify-services&lt;/span&gt;
     &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;operating-system-default-essential-services&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;this-operating-system&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;delete&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;firmware-service-type&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;delete&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;service-kind&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;%linux-bare-metal-service&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;delete&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;host-name-service-type&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;delete&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;hosts-service-type&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We also stub out &lt;code&gt;kernel&lt;/code&gt;, &lt;code&gt;firmware&lt;/code&gt;, and &lt;code&gt;initrd-modules&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;operating-system&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;firmware&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;initrd-modules&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;kernel&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;hello&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Deleting &lt;code&gt;host-name-service-type&lt;/code&gt; causes more problems though: agetty's
shepherd service hardcodes &lt;code&gt;host-name&lt;/code&gt; as a requirement. Without something
providing it, agetty won't start. So we have to replace it with a dummy service:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;%dummy-host-name&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;simple-service&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;'dummy-host-name&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;shepherd-root-service-type&lt;/span&gt;
                  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;shepherd-service&lt;/span&gt;
                         &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;provision&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;host-name&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                         &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;one-shot?&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;#t&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                         &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;start&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;#~&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;#t&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We also need &lt;code&gt;(chroot? #f)&lt;/code&gt; on &lt;code&gt;guix-service-type&lt;/code&gt; if we want to use
unpriviledged containers,  because unprivileged can't use &lt;code&gt;chroot()&lt;/code&gt; and the
various mounts the daemon's build sandbox uses.&lt;/p&gt;&lt;h2&gt;Problem 4: &lt;code&gt;%base-file-systems&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;You can't use &lt;code&gt;%base-file-systems&lt;/code&gt; wholesale.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;%debug-file-system&lt;/code&gt;&lt;/strong&gt; (debugfs at &lt;code&gt;/sys/kernel/debug&lt;/code&gt;) -- mount gets blocked
by LXC and fails the shepherd service. That blocks the rest of the boot, which
blocks the rest of the boot process.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;%pseudo-terminal-file-system&lt;/code&gt;&lt;/strong&gt; (devpts at &lt;code&gt;/dev/pts&lt;/code&gt;) -- PVE pre-mounts a
healthy devpts with &lt;code&gt;ptmxmode=666&lt;/code&gt; before PID 1 starts. Guix then mounts
&lt;em&gt;another&lt;/em&gt; devpts on top with &lt;code&gt;ptmxmode=000&lt;/code&gt;. Both succeed, but devpts has
per-instance slave-node namespaces. &lt;code&gt;/dev/ptmx&lt;/code&gt; allocates PTYs on LXC's
instance; &lt;code&gt;/dev/pts/&lt;/code&gt; now shows Guix's instance where those slaves don't exist.
&lt;code&gt;openpty(3)&lt;/code&gt; returns ENOENT and sshd reports &lt;code&gt;PTY allocation request failed on channel 0&lt;/code&gt; when you attempt to SSH into the container or use &lt;code&gt;pct console&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;%efivars-file-system&lt;/code&gt;&lt;/strong&gt; -- harmless (has &lt;code&gt;mount-may-fail?&lt;/code&gt;), but pointless
in a container.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; declare a minimal set of file systems explicitly. We only really need
&lt;code&gt;%immutable-store&lt;/code&gt; and &lt;code&gt;%shared-memory-file-system&lt;/code&gt; (and even the latter is
questionable, but it doesn't cause any problems):&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;file-systems&lt;/span&gt;
 &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;file-system&lt;/span&gt;
         &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;device&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;file-system-label&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;Guix&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
         &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;mount-point&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;/&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
         &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;ext4&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
         &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;mount-may-fail?&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;#t&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
         &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;check?&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;#f&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
       &lt;span class=&quot;syntax-symbol&quot;&gt;%shared-memory-file-system&lt;/span&gt;
       &lt;span class=&quot;syntax-symbol&quot;&gt;%immutable-store&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Problem 5: mingetty doesn't work on &lt;code&gt;pct console&lt;/code&gt;&lt;/h2&gt;&lt;p&gt;I initially tried to use &lt;code&gt;mingetty-service-type&lt;/code&gt; for the console login. Two problems:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;p&gt;mingetty's &lt;code&gt;login-program&lt;/code&gt; defaults to &lt;code&gt;#f&lt;/code&gt;, which resolves to the
compile-time default &lt;code&gt;/bin/login&lt;/code&gt;. That obviously doesn't exist on Guix.
(agetty defaults to &lt;code&gt;(file-append shadow &amp;quot;/bin/login&amp;quot;)&lt;/code&gt;, which works). This
might be worth filing as a Guix bug...&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Even after fixing that, every login attempt produced &lt;code&gt;tty1: too long login name&lt;/code&gt;. At this point I was getting too exhausted to dig into exactly why,
so it's still a mystery.&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; use &lt;code&gt;agetty-service-type&lt;/code&gt;. It seems to &amp;quot;Just Work&amp;quot;, is what
&lt;code&gt;%base-services&lt;/code&gt; uses on bare metal anyway. I can't even remember why I
initially picked mingetty. I probably just copied it from another LXC example...&lt;/p&gt;&lt;h2&gt;Problem 6: &lt;code&gt;guix system reconfigure&lt;/code&gt; fails inside the container&lt;/h2&gt;&lt;p&gt;Once I finally got a working container, I struggled a bit getting &lt;code&gt;guix system reconfigure&lt;/code&gt; to work:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;--skip-checks&lt;/code&gt; needed:&lt;/strong&gt; &lt;code&gt;check-file-system-availability&lt;/code&gt; walks
&lt;code&gt;/proc/partitions&lt;/code&gt; looking for a block device with the fake/dummy &lt;code&gt;Guix&lt;/code&gt; label.
Inside the LXC container, &lt;code&gt;/proc/partitions&lt;/code&gt; shows the &lt;em&gt;host's&lt;/em&gt; block devices
but the container's &lt;code&gt;/dev/&lt;/code&gt; is its own tmpfs, so every probe fails. The
template build doesn't hit this because &lt;code&gt;image -t tarball&lt;/code&gt; rewrites the root
type to &lt;code&gt;&amp;quot;dummy&amp;quot;&lt;/code&gt; in its sandbox; &lt;code&gt;reconfigure&lt;/code&gt; reads the config as-is.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;--no-bootloader&lt;/code&gt; needed:&lt;/strong&gt; grub-install inspects the host's mount table,
finds PVE's ZFS subvolume name, and can't canonicalize it from inside the
container. The template build doesn't hit this because &lt;code&gt;image -t tarball&lt;/code&gt;
skips the bootloader installer entirely.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt;&lt;/p&gt;&lt;pre&gt;&lt;code&gt;sudo -i guix system reconfigure --skip-checks --no-bootloader /etc/config.scm&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;The End Result&lt;/h2&gt;&lt;p&gt;This is the &lt;code&gt;config.scm&lt;/code&gt; I ended up with&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;use-modules&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;gnu&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
             &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;gnu&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;system&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;locale&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
             &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;gnu&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;system&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;shadow&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
             &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;guix&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;channels&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
             &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;guix&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;gexp&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
             &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;guix&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;packages&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
             &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;guix&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;download&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;use-service-modules&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;networking&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;ssh&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;admin&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;shepherd&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;use-package-modules&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;ssh&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;bash&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;package-management&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;admin&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;%lxc-special-files&lt;/span&gt;
  &lt;span class=&quot;syntax-symbol&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;/sbin/init&amp;quot;&lt;/span&gt;
     &lt;span class=&quot;syntax-symbol&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;program-file&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;lxc-init&amp;quot;&lt;/span&gt;
                    &lt;span class=&quot;syntax-symbol&quot;&gt;#~&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;begin&lt;/span&gt;
                        &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;setenv&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;HOME&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;/root&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                        &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;let*&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;system&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;canonicalize-path&lt;/span&gt;
                                         &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;/var/guix/profiles/system&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                               &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;guile&lt;/span&gt;  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;string-append&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;system&lt;/span&gt;
                                         &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;/profile/bin/guile&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                               &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;boot&lt;/span&gt;   &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;string-append&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;system&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;/boot&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                          &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;setenv&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;GUIX_NEW_SYSTEM&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;system&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                          &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;execl&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;guile&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;guile&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;boot&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;/bin/sh&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;file-append&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;bash&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;/bin/sh&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;/usr/bin/env&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;file-append&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;coreutils&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;/bin/env&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;%dynamic-hosts&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;simple-service&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;'dynamic-hosts-file&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;activation-service-type&lt;/span&gt;
                  &lt;span class=&quot;syntax-symbol&quot;&gt;#~&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;hostname&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;gethostname&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                      &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;call-with-output-file&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;/etc/hosts&amp;quot;&lt;/span&gt;
                        &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                          &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;display&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;127.0.0.1 localhost\n&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                          &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;display&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;::1       localhost\n&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                          &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;display&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;string-append&lt;/span&gt;
                                    &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;127.0.1.1 &amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;hostname&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;%dummy-host-name&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;simple-service&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;'dummy-host-name&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;shepherd-root-service-type&lt;/span&gt;
                  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;shepherd-service&lt;/span&gt;
                         &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;documentation&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;No-op host-name service for LXC.&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                         &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;provision&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;host-name&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                         &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;one-shot?&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;#t&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                         &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;start&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;#~&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;#t&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;operating-system&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;host-name&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;localhost&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;timezone&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;America/Edmonton&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;locale&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;en_US.utf8&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;firmware&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;initrd-modules&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;kernel&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;hello&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;packages&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;cons*&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;guix&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;sudo&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;%base-packages&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;users&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;cons*&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;user-account&lt;/span&gt;
                  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;ryan&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;comment&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;Ryan&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;group&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;users&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;supplementary-groups&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;wheel&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;home-directory&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;/home/ryan&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;password&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;$6$...&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;  &lt;span class=&quot;syntax-comment&quot;&gt;;; mkpasswd -m sha-512
&lt;/span&gt;                &lt;span class=&quot;syntax-symbol&quot;&gt;%base-user-accounts&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;essential-services&lt;/span&gt;
   &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;modify-services&lt;/span&gt;
       &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;operating-system-default-essential-services&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;this-operating-system&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
     &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;delete&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;firmware-service-type&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
     &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;delete&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;service-kind&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;%linux-bare-metal-service&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
     &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;delete&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;host-name-service-type&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
     &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;delete&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;hosts-service-type&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;locale-definitions&lt;/span&gt;
   &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;locale-definition&lt;/span&gt;
           &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;en_US.utf8&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
           &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;source&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;en_US&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
           &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;charset&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;UTF-8&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;bootloader&lt;/span&gt;
   &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;bootloader-configuration&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;bootloader&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;grub-bootloader&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;targets&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;/dev/null&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;file-systems&lt;/span&gt;
   &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;file-system&lt;/span&gt;
           &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;device&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;file-system-label&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;Guix&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
           &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;mount-point&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;/&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
           &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;ext4&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
           &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;mount-may-fail?&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;#t&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
           &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;check?&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;#f&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
         &lt;span class=&quot;syntax-symbol&quot;&gt;%shared-memory-file-system&lt;/span&gt;
         &lt;span class=&quot;syntax-symbol&quot;&gt;%immutable-store&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;services&lt;/span&gt;
   &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;list&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;service&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;dhcpcd-service-type&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;service&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;syslog-service-type&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;service&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;agetty-service-type&lt;/span&gt;
             &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;agetty-configuration&lt;/span&gt;
              &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;tty&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;tty1&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
              &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;term&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;linux&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
              &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;extra-options&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;-L&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
              &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;shepherd-requirement&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;user-processes&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;udev&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;syslogd&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;service&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;login-service-type&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;service&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;guix-service-type&lt;/span&gt;
             &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;guix-configuration&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;chroot?&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;#f&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;service&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;static-networking-service-type&lt;/span&gt;
             &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;list&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;%loopback-static-networking&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;service&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;special-files-service-type&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;%lxc-special-files&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;service&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;udev-service-type&lt;/span&gt;
             &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;udev-configuration&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;rules&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;'&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;syntax-symbol&quot;&gt;%dynamic-hosts&lt;/span&gt;
    &lt;span class=&quot;syntax-symbol&quot;&gt;%dummy-host-name&lt;/span&gt;
    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;service&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;openssh-service-type&lt;/span&gt;
             &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;openssh-configuration&lt;/span&gt;
              &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;password-authentication?&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;#f&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
              &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;authorized-keys&lt;/span&gt;
                &lt;span class=&quot;syntax-symbol&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;ryan&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;local-file&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;keys/ryan.pub&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We can build it with:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;guix system image -t tarball config.scm&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Unfortunately, as mentioned above, we can't use the image as-is.&lt;/p&gt;&lt;p&gt;The tarball from &lt;code&gt;guix system image&lt;/code&gt; doesn't have &lt;code&gt;/sbin/init&lt;/code&gt;, &lt;code&gt;/bin/sh&lt;/code&gt;, or
&lt;code&gt;/usr/bin/env&lt;/code&gt; because activation hasn't run yet (see Problem 1). Since we're
already messing with the image, we also want to inject the source &lt;code&gt;config.scm&lt;/code&gt;
so reconfigure works out of the box without having to manually &lt;code&gt;scp&lt;/code&gt; it over
later.&lt;/p&gt;&lt;p&gt;Here's the shell script that handles it:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;#!/usr/bin/env bash
set -euo pipefail

CONFIG=config.scm
OUTPUT=guix-lxc-template.tar.zst
BUILDDIR=build

# 1. Build the rootfs tarball.
image_path=$(guix system image -t tarball &amp;quot;$CONFIG&amp;quot;)

# 2. Decompress and extract.
rm -rf &amp;quot;$BUILDDIR/rootfs&amp;quot;
mkdir -p &amp;quot;$BUILDDIR/rootfs&amp;quot;
case &amp;quot;$image_path&amp;quot; in
    *.tar.gz)  gzip -dc &amp;quot;$image_path&amp;quot; | tar -xC &amp;quot;$BUILDDIR/rootfs&amp;quot; ;;
    *.tar.xz)  xz   -dc &amp;quot;$image_path&amp;quot; | tar -xC &amp;quot;$BUILDDIR/rootfs&amp;quot; ;;
    *.tar.zst) zstd -dc &amp;quot;$image_path&amp;quot; | tar -xC &amp;quot;$BUILDDIR/rootfs&amp;quot; ;;
    *.tar)     tar -xf  &amp;quot;$image_path&amp;quot; -C &amp;quot;$BUILDDIR/rootfs&amp;quot; ;;
    *)         echo &amp;quot;unexpected extension: $image_path&amp;quot;; exit 1 ;;
esac

# 3. Seed /sbin/init, /bin/sh, /usr/bin/env.
#    The activation script in the store contains the link targets.
#    Parse them out and create the symlinks directly in the rootfs.
activate=$(find &amp;quot;$BUILDDIR/rootfs/gnu/store&amp;quot; -name '*-activate-service.scm' \
           -exec grep -l activate-special-files {} + | head -1)
if [ -z &amp;quot;$activate&amp;quot; ]; then
    echo &amp;quot;no activate-special-files script found&amp;quot;; exit 1
fi
# Extract pairs: &amp;quot;/sbin/init&amp;quot; &amp;quot;/gnu/store/...-lxc-init&amp;quot; etc.
grep -oP '&amp;quot;/([^&amp;quot;]+)&amp;quot;\s+&amp;quot;/gnu/store/[^&amp;quot;]+&amp;quot;' &amp;quot;$activate&amp;quot; |
while read -r line; do
    link=$(echo &amp;quot;$line&amp;quot; | grep -oP '^&amp;quot;/[^&amp;quot;]+&amp;quot;' | tr -d '&amp;quot;')
    target=$(echo &amp;quot;$line&amp;quot; | grep -oP '&amp;quot;/gnu/store/[^&amp;quot;]+&amp;quot;' | tr -d '&amp;quot;')
    dest=&amp;quot;$BUILDDIR/rootfs${link}&amp;quot;
    mkdir -p &amp;quot;$(dirname &amp;quot;$dest&amp;quot;)&amp;quot;
    ln -sf &amp;quot;$target&amp;quot; &amp;quot;$dest&amp;quot;
    echo &amp;quot;  $link -&amp;gt; $target&amp;quot;
done

# 4. Inject config.scm for in-container reconfigure.
cp &amp;quot;$CONFIG&amp;quot; &amp;quot;$BUILDDIR/rootfs/etc/config.scm&amp;quot;
chmod 600 &amp;quot;$BUILDDIR/rootfs/etc/config.scm&amp;quot;

# 5. Repack as zstd with root ownership, because zstd is better than gzip.
ZSTD_CLEVEL=19 tar -C &amp;quot;$BUILDDIR/rootfs&amp;quot; --zstd \
    --numeric-owner --owner=0 --group=0 -cf &amp;quot;$OUTPUT&amp;quot; .

echo &amp;quot;Built $OUTPUT ($(du -h &amp;quot;$OUTPUT&amp;quot; | cut -f1))&amp;quot;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Deploy to Proxmox:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;scp guix-lxc-template.tar.zst &amp;lt;proxmox-host&amp;gt;:/var/lib/vz/template/cache/

pct create &amp;lt;vmid&amp;gt; local:vztmpl/guix-lxc-template.tar.zst \
    --hostname guix \
    --rootfs local-zfs:20 \
    --memory 2048 \
    --net0 name=eth0,bridge=vmbr0,ip=dhcp,ip6=auto \
    --features nesting=1,keyctl=1 \
    --ostype unmanaged \
    --unprivileged 1&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;ostype unmanaged&lt;/code&gt; because Proxmox doesn't know about Guix.&lt;/p&gt;&lt;p&gt;&lt;code&gt;nesting=1&lt;/code&gt; relaxes user-namespace restrictions enough for shepherd,
guix-daemon, and activation.&lt;/p&gt;&lt;p&gt;As I'm writing this I'm realizing that I didn't even confirm whether or not
either &lt;code&gt;nesting=1&lt;/code&gt; or &lt;code&gt;keyctl=1&lt;/code&gt; is required after setting &lt;code&gt;(chroot #f)&lt;/code&gt;. I'll
have to revisit that.&lt;/p&gt;&lt;h2&gt;Niceties&lt;/h2&gt;&lt;p&gt;A few optional but handy things in the config:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;DHCP inside the container&lt;/strong&gt; via &lt;code&gt;dhcpcd-service-type&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;Dynamic &lt;code&gt;/etc/hosts&lt;/code&gt;&lt;/strong&gt; generated from the Proxmox-assigned hostname at
boot, rather than hardcoding a hostname in &lt;code&gt;config.scm&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;define&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;%dynamic-hosts&lt;/span&gt;
&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;simple-service&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;'dynamic-hosts-file&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;activation-service-type&lt;/span&gt;
                &lt;span class=&quot;syntax-symbol&quot;&gt;#~&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;hostname&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;gethostname&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;call-with-output-file&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;/etc/hosts&amp;quot;&lt;/span&gt;
                      &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-special&quot;&gt;lambda&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                        &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;display&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;127.0.0.1 localhost\n&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                        &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;display&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;::1       localhost\n&amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;
                        &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;display&lt;/span&gt; &lt;span class=&quot;syntax-open&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-symbol&quot;&gt;string-append&lt;/span&gt;
                                  &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;127.0.1.1 &amp;quot;&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;hostname&lt;/span&gt; &lt;span class=&quot;syntax-string&quot;&gt;&amp;quot;\n&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;syntax-symbol&quot;&gt;port&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-close&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;SSH public keys from SourceHut&lt;/strong&gt; at build time so that we don't have to
manage key files manually.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2&gt;References&lt;/h2&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;https://www.thedroneely.com/posts/guix-in-a-linux-container/&quot;&gt;Guix in a Linux Container -- Thedro Neely&lt;/a&gt; -- the article that got me started&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://lists.gnu.org/archive/html/guix-devel/2017-06/msg00078.html&quot;&gt;GuixSD in LXD -- Eddy Pronk&lt;/a&gt; -- 2017 thread exploring /sbin/init shims&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://lists.gnu.org/archive/html/help-guix/2025-09/msg00128.html&quot;&gt;Init command setup for Incus&lt;/a&gt; -- Sept 2025, still manually updating store hashes&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://lists.gnu.org/archive/html/help-guix/2025-11/msg00020.html&quot;&gt;System containers workflow&lt;/a&gt; -- Nov 2025, the immutable rebuild-and-replace default&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://lists.gnu.org/archive/html/help-guix/2018-10/msg00057.html&quot;&gt;AppArmor and guix-daemon&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;https://pve.proxmox.com/wiki/Linux_Container&quot;&gt;Proxmox LXC documentation&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;</content></entry></feed>