Home Blog CV Projects Patterns Notes Book Colophon Search

Systemd Nspawn

10 Jan, 2022

This is for Debian 11 only.

On the host

sudo apt install systemd-container debootstrap
sudo systemctl enable machines.target
sudo systemctl enable systemd-networkd
sudo systemctl start systemd-networkd
sudo systemctl enable systemd-resolved
sudo systemctl start systemd-resolved


export MACHINE=debian
sudo debootstrap --variant=minbase --include=systemd-container stable /var/lib/machines/$MACHINE
sudo du -hs /var/lib/machines/$MACHINE
sudo systemd-nspawn -D /var/lib/machines/$MACHINE -U --machine $MACHINE

Set the root password, set the hostname and enable networking at boot:

systemctl enable systemd-networkd.service
systemctl enable systemd-resolved.service
echo 'debian' > /etc/hostname

Back on the host:

sudo mkdir -p /etc/systemd/nspawn
cat << EOF | sudo tee /etc/systemd/nspawn/$MACHINE.nspawn > /dev/null

# Forward port 80 in the host to port 80 in the container so it is accessible externally


If you change the above file later, run this to make the change take effect:

sudo systemctl daemon-reload

Now let's set it up:

# Start it at reboot:
sudo systemctl enable systemd-nspawn@$MACHINE.service
# Start it now
sudo systemctl start systemd-nspawn@$MACHINE
systemctl status systemd-nspawn@$MACHINE.service
journalctl -u systemd-nspawn@$MACHINE.service

If you want to be able to change the file limits within the container you can add LimitNOFILE to /etc/systemd/nspawn/$MACHINE.nspawn in the [Exec] section:


Now login with:

sudo machinectl login $MACHINE

WARNING: Make sure $MACHINE is really set, otherwise you'll actually be logging into the host machine by mistake!

Escape with Ctrl+]]]

Install some tools:

apt update
apt install -y nginx iproute2 iputils-ping curl

Then within the container you can do:


and on the host you can do (but doesn't work):

curl http://<public_ip_address>

If you reboot everything will all still be running.

Then in future on the host:

sudo machinectl start $MACHNINE
sudo machinectl stop $MACHINE
sudo machinectl list

Common tasks

I like to set up a new user with sudo access and then install openSSH server for remote login:

apt update
apt install -y openssh-server sudo
/sbin/adduser james
/sbin/usermod -a -G sudo james

Then I can login from the host like this, and I have sudo access when needed:

ssh james@$MACHINE

(If you SSH in before adding james to the sudo group, you'll need to login again for the change to be noticed).

I'll normally add these too:

sudo apt install -y python3 vim screen


Cleaning Up

sudo systemctl stop systemd-nspawn@$MACHINE
sudo systemctl disable systemd-nspawn@$MACHINE.service
sudo rm /etc/systemd/nspawn/$MACHINE.nspawn

Then delete /var/lib/machines/$MACHINE.


Be the first to comment.

Add Comment

Copyright James Gardner 1996-2020 All Rights Reserved. Admin.