Running NixOS in a Linux Container
init
and the init
path lxc
expects across multiple
NixOS versions. See this
thread
for a possible fix.

NixOS is seen as the holy grail of
[pdf]
. The state is declarative — entire systems, deployment artifacts, or
services can be built from a single file.
Let’s try out NixOS
in a
LXC
). The NixOS
Hydra
builds
(aarch64
)
provide container images but they don’t seem to
rootfs.
Bootstrapping
The best way to get a NixOS
root file system is to bootstrap using
nixos-generate
.
This will require a live NixOS
environment or
installing nix
onto your Linux
distribution. Download the latest
NixOS
minimal image and boot
into the live environment using preferred means.
Inside the live environment or after installing nix
bootstrap a Linux
container’s rootfs
using nixos-generate
.
shell
nixos-generate --format lxc
shell
nixos-generate --format lxc --configuration configuration.nix
If the command nixos-generate
is not found — install nixos-generators
using nix-env
.
shell
nix-env -iA nixos.nixos-generators
Once completed, this command will print a hashed path like
/nix/store/3ipfpzhk4dllwhcnldsbfldi1favyxsm-tarball/nix-support/hydra-build-products
.
This file contains the location of the rootfs
archive.
shell
$ cat /nix/store/3ipfpzhk4dllwhcnldsbfldi1favyxsm-tarball/nix-support/hydra-build-products
file system-tarball /nix/store/3ipfpzhk4dllwhcnldsbfldi1favyxsm-tarball/tarball/nixos-system-x86_64-linux.tar.xz
Save the generated archive nixos-system-x86_64-linux.tar.xz
and exit the live
environment.
Setup the Linux Container
Now that we have a clean rootfs
archive. Create an empty linux container and
rootfs
directory. Extract nixos-system-x86_64-linux.tar.xz
to rootfs
.
shell
lxc-create -n nixos -t none
cd /var/lib/lxc/nixos
mkdir rootfs
tar -xvf nixos-system-x86_64-linux.tar.xz -C rootfs/
Let’s massage our Debian
and Arch Linux.
NixOS
at
/var/lib/lxc/nixos/config
. Our entry point is /sbin/init
and we must mount
/proc
to run nixos-rebuild
.
ini
# Distribution configuration
lxc.include = /usr/share/lxc/config/common.conf
lxc.arch = linux64
# Container specific configuration
lxc.rootfs.path = dir:/var/lib/lxc/nixos/rootfs
lxc.uts.name = nixos
# Network configuration
lxc.net.0.type = veth
lxc.net.0.link = lxcbr0
lxc.net.0.flags = up
lxc.net.0.hwaddr = 00:16:3e:01:77:76
lxc.apparmor.profile = generated
lxc.apparmor.allow_nesting = 1
# NixOS configuration
lxc.init.cmd = /sbin/init
lxc.mount.entry = proc mnt/proc proc create=dir 0 0
Setup and Run NixOS
Now
NixOS
Container Setup
lxc-attach
.
shell
lxc-start -n nixos
lxc-attach -n nixos
The default /etc/nixos/configuration.nix
is empty. Tell NixOS
that we are a
container by adding boot.isContainer = true
.
nix
{ config, pkgs, ... }:
{
imports = [ ];
boot.isContainer = true;
}
Now run a IPv6
filters mean you either run an old kernel or you need to
sudo modprobe ip6table_filter
shell
nixos-rebuild switch --upgrade
We now have a base NixOS
system in a Linux container. You can build
reproducible desktops, servers, deployment artifacts — anything, using your
own configuration.nix
and consulting the
NixOS
options index. This approach is
great because when you make something it just works — all the time.