Prepare base image

pacman -S arch-install-scripts
btrfs subvol create /var/lib/container/archlinux-base
mkdir /etc/systemd/nspawn
pacstrap /var/lib/container/archlinux-base base
systemctl enable --now systemd-networkd systemd-resolved

Prepare child image

Setting UID range for container: Using a multiple of 65536, e.g. 65536 * 70 for this machine as. To match the user http (always uid 33) on the container, a user on the host with the same permissions should therefore have the UID: 65536 * 70 + 33.

useradd -m -u $((65536 * 70 + 33)) archlinux-dokuwiki
mkdir /home/archlinux-dokuwiki/data
chown -R archlinux-dokuwiki:archlinux-dokuwiki /home/archlinux-dokuwiki/data

PrivateUsers parameter is here equal to 65536 * 70

systemd-nspawn -nD /var/lib/machines/archlinux-dokuwiki --template=/var/lib/container/archlinux-base --private-users-chown --private-users=4587520 --boot &
pacman -S ansible
wget "https://github.com/BaxterStockman/ansible-connection-machinectl/raw/master/connection_plugins/machinectl.py" -O /usr/lib/python2.7/site-packages/ansible/plugins/connection/machinectl.py
machinectl shell root@archlinux-dokuwiki /bin/bash -c "systemctl enable --now systemd-networkd systemd-resolved" 
machinectl shell root@archlinux-dokuwiki /bin/bash -c "pacman -Sy python2 --noconfirm"
git clone ...
cd ...
ansible-galaxy install -r requirements.yml
sudo -E ansible-playbook -c machinectl -i inventory -v archlinux-dokuwiki.yml

After bootstrapping we can enable our mount:

/etc/systemd/nspawn/archlinux-dokuwiki.nspawn
[Exec]
PrivateUsers=4587520

[Files]
PrivateUsersChown=true
Bind=/home/archlinux-dokuwiki/data:/var/lib/dokuwiki/data

[Network]
Private=yes
VirtualEthernet=yes
machinectl terminate archlinux-dokuwiki
systemctl enable systemd-nspawn@archlinux-dokuwiki.service
systemctl restart systemd-nspawn@archlinux-dokuwiki

Maintainance

Reset child

systemctl stop systemd-nspawn@archlinux-dokuwiki
btrfs subvolume delete /var/lib/machines/archlinux-dokuwiki/var/lib/machines 
btrfs subvolume delete /var/lib/machines/archlinux-dokuwiki

Todo

  • auto update base image, auto reboot childs
  • private ethernet
  • bind data

Bugs

~/.ansible/roles/geerlingguy.nginx/templates/nginx.conf.j2
#pid        {{ nginx_pidfile }};
  • machine not starting automatically (systemctl enable systemd-nspawn@machine-dokuwiki)

Tips

Iptables forward host port to container

iptables -t nat -A PREROUTING -i ens3 -p tcp --dport 80 -j DNAT --to 10.0.0.10:80 

Container ip and port can be checked with nmap

nmap -p 80 archlinux-dokuwiki