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

Then:

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
passwd
logout

Back on the host:

sudo mkdir -p /etc/systemd/nspawn
cat << EOF | sudo tee /etc/systemd/nspawn/$MACHINE.nspawn > /dev/null
[Exec]
PrivateUsers=pick
ResolvConf=bind-static

[Network]
VirtualEthernet=yes
# Forward port 80 in the host to port 80 in the container so it is accessible externally
Port=tcp:80

[Files]
PrivateUsersChown=yes
EOF

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:

[Exec]
...
LimitNOFILE=infinity

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:

curl http://127.0.0.1

and on the host you can do (but 127.0.0.1 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

Issues

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.

Comments

Be the first to comment.

Add Comment





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