This guide will explain how to install NixOS as an LXC container inside of proxmox. Do be warned that this setup isn’t extensively tested for stability or officially supported.

Getting the container tarball

The first step is to download the NixOS container tarball. To do so simply go to its pipeline. And click on the latest successful build, and download the corresponding .tar.xz file. A screenshot of the NixOS container tarball download page

After it’s downloaded we should rename the file to follow proxmox conventions (recommended but optional):

1
mv nixos-system-x86_64-linux.tar.xz nixos-$RELEASE-default_$BUILDID_amd64.tar.xz

Uploading to proxmox

Uploading it to proxmox is quite easy: just go to your storage, most likely called “local” then to “CT Templates” and click on upload and upload the tarball.

Creating the container

To create the container on proxmox we need to either ssh into it or use the web shell. After in a shell on the proxmox host execute the following command. However, make sure you understand what the options do before executing it. You can see the proxmox docs if you are unsure.

1
2
3
4
5
6
7
8
pct create $(pvesh get /cluster/nextid) \
  --arch amd64 \
  --description nixos-template \
  local:vztmpl/nixos-$RELEASE-default_$BUILDID_amd64.tar.xz \
  --ostype unmanaged \
  --net0 name=eth0 \
  --storage local-zfs \
  --unprivileged 1

after running this the container should show up in the Proxmox Web UI.

Fix LXC config

This step is only necessary if you are using nix older than 21.11, if using a newer version feel free to skip

After creating the container we need to make a simple edit to the lxc config file located in /etc/pve/lxc/$ID.conf, $ID being the ID you passed in the previous step, if unsure you can check the web UI.

After opening the file add the following line to the bottom:

1
lxc.init.cmd: /init

This will point proxmox to the correct init binary of NixOS.

Enable nesting

We are now done with all the cli configuration and need to enable a feature flag in the web interface. Under container options, go to “Features” and enable “Nesting”. This is needed as nix makes heavy use of sandboxing.

Picture showing the proxmox featues dialog with nesting enabled

Do note the following (from the proxmox wiki)

Nesting is best used with unprivileged containers with additional id mapping. Note that this will expose procfs and sysfs contents of the host to the guest.

Fix Network settings

If you didn’t specify a full network configuration during container creation you must now do so in the web UI or else the container won’t start. The easiest being to just to set both ipv4 and ipv6 to dhcp.

Do mind that these network settings seem mostly to just be defaults that are able to be overwritten inside of the container, except things like MAC address presumably.

In-Container tweaks

Now you can finally start up the container! But we are not done yet, we need to set some minor settings to make NixOS play nice with the fact that it is running inside of an lxc container.

Populate Nixpkgs

nixpkgs isn’t properly initialized when booting a fresh container, which would result in errors when running other nix commands, to fix this simply run:

1
nix-channel --update

configuration.nix tweak

Finally we need to add a small tweak inside of /etc/nixos/configuration.nix. We will supress some systemds unit as they will otherwise error upon every invocation of nixos-rebuild switch which can be annoying.

1
2
3
4
5
6
  # Supress systemd units that don't work because of LXC
  systemd.suppressedSystemUnits = [
    "dev-mqueue.mount"
    "sys-kernel-debug.mount"
    "sys-fs-fuse-connections.mount"
  ];

Done!

After doing the final tweaks you should be done and able to run
nixos-rebuild switch without any errors.

A screenshot of a succesful `nixos-rebuild switch` invocation

References

This guide is based heavily on the resources below