This how-to uses mybox as container name, mkosi
in order to create containers (it works for multiple distributions and has more features compared to dnf --installroot
), and crudini
for configurations file (you can use your preferred text editor instead).
# mkosi --cache /var/cache/mkosi -d fedora -t directory -o /var/lib/machines/mybox
mkosi
can do much more! https://github.com/systemd/mkosi
# machinectl start mybox
# machinectl shell mybox
machinectl
calls systemd-nspawn
with different network connection defaults. The first creates a new virtual ethernet interface, while the second uses the loopback interface.
This little how-to uses nspawn configuration files in order to setup containers instead of calling systemd-nspawn
directly (this is necessary in order to boot containers with machinectl
with custom settings). The configuration files can be stored under /etc/systemd/nspawn
(not created by default), /run/systemd/nspawn
and /var/lib/machines/
, but only the first two paths are considered as trusted, so this how-to uses the second directory (source: nspawn.c source code). machinectl
defaults are overridden by specific nspawn configuration files.
In order to see machinectl
defaults:
$ crudini --get /usr/lib/systemd/system/[email protected] Service ExecStart
More information about nspawn configuration files: man systemd.nspawn
If you want to use the loopback interface:
# crudini --set /run/systemd/nspawn/mybox.nspawn Network VirtualEthernet no
# machinectl stop mybox
# machinectl start mybox
# crudini --set /run/systemd/nspawn/mybox.nspawn Network VirtualEthernet yes
# systemctl start systemd-networkd
# systemctl enable systemd-networkd
# systemctl -M mybox enable systemd-networkd
# machinectl stop mybox
# machinectl start mybox
Test your connection with ping -c 1 mybox
Unable to ping your container? Have a look at https://www.freedesktop.org/software/systemd/man/nss-mymachines.html
Still have problems? Try machinectl status mybox
and networkctl
If libvirt-daemon-config-network
is installed and libvirtd.service
is running, you could use the existing bridge for your containers:
# crudini --set /run/systemd/nspawn/mybox.nspawn Network Bridge=virbr0
# systemctl start systemd-networkd
# systemctl enable systemd-networkd
# systemctl -M mybox enable systemd-networkd
# machinectl stop mybox
# machinectl start mybox
If you need to create a network bridge, please follow https://major.io/2015/03/26/creating-a-bridge-for-virtual-machines-using-systemd-networkd/
# systemctl set-property --runtime [email protected] MemoryMax=500M
# systemctl set-property --runtime [email protected] CPUShares=500
Configuration files are stored in /etc/systemd/system.control/[email protected]/
More information about resource control: man systemd.resource-control
# machinectl enable mybox
# mkosi --cache /var/cache/mkosi -d fedora -t directory -o /var/lib/machines/wordpress -p wordpress,mariadb-server
# crudini --set /run/systemd/nspawn/wordpress.nspawn Network VirtualEthernet no
Adjust port=8080
as you like (first line).
$ port=8080; password=$(openssl rand -base64 18)
$ curl https://api.wordpress.org/secret-key/1.1/salt/ > /tmp/salt
$ cat > /tmp/wordpress.sh <<EOF
#!/bin/sh
set -x
echo -e '\nn\n\n\n\n\n' | mysql_secure_installation
mysql <<END
CREATE DATABASE wordpress;
GRANT ALL PRIVILEGES ON wordpress.* TO 'wordpress'@'%' IDENTIFIED BY '$password';
FLUSH PRIVILEGES;
END
sed -i "s/Listen 80/Listen $port/" /etc/httpd/conf/httpd.conf
sed -i "s/Require local/Require all granted/" /etc/httpd/conf.d/wordpress.conf
multisite="define( 'WP_ALLOW_MULTISITE', true );"
sed -i \
-e "s:database_name_here:wordpress:" \\
-e "s:username_here:wordpress:" \\
-e "s:password_here:$password:" \\
-e "s:/\* That's all, stop editing! Happy blogging. \*/:$multisite\n&:" \\
-e "/put your unique phrase here/d" \\
/etc/wordpress/wp-config.php
cd /tmp
csplit /etc/wordpress/wp-config.php "/\/\*\*#@-\*\//"
cat xx00 salt xx01 > /etc/wordpress/wp-config.php
rm xx00 salt xx01 wordpress.sh
EOF
# machinectl start wordpress
# systemctl -M wordpress start mariadb
# machinectl copy-to wordpress /tmp/wordpress.sh
# machinectl copy-to wordpress /tmp/salt
# machinectl shell wordpress /bin/sh /tmp/wordpress.sh
# systemctl -M wordpress enable mariadb httpd
# systemctl -M wordpress start httpd
$ rm /tmp/wordpress.sh /tmp/salt
Visit http://localhost:8080 and follow the procedure.
This gist contains the best systemd containers use case example of the entire internet