Developing using a systemd-nspawn container (Linux host only)
/docs/developers/setup/systemd-nspawn/
Prerequisites
This should work on all x86_64 Linux systems that run
systemd
– that’s most of them at this point –
and most (all?) ARM Linux systems that run systemd
. We have tested this
setup on Arch Linux on x86_64 and with Ubuntu on x86_64.
If you use ARM, replace all occurrences of x86_64
in URLs and filenames
in this document with the appropriate ARM architecture, such as armh6h',
armh7h, or
aarch64`.
An alternative setup is Developing using Docker (all Intel platforms).
Here are the steps:
Make sure systemd-nspawn
is installed
Some Linux distros keep this systemd
executable in a separate package that
you need to first install. For example, on Ubuntu, install it with:
% sudo apt-get install systemd-container
Optional: btrfs filesystem
systemd-nspawn
has built-in extra features when you use the
btrfs
filesystem.
This can make container management much faster and take up less disk space. If you
can, we recommend a btrfs
partition; if not, that’s fine, too, it will work just
fine on other filesystems as well.
Make sure your host allows Linux containers to access the internet
How to do this highly dependent on your networking setup. Here is a setup
that works for us on Arch Linux, using systemd-networkd
for network
management. There are two steps:
-
Run both IPv4 and IPv6 based
iptables
on your host, otherwise the UBOS container cannot set up its own firewall and UBOS containers will boot into adegraded
state. (That’s not fatal, it just looks ugly and you might not see other problems as easily.) If you aren’t already doing this, on the host:% [[ -e /etc/iptables/iptables.rules ]] || sudo cp /etc/iptables/empty.rules /etc/iptables/iptables.rules % [[ -e /etc/iptables/ip6tables.rules ]] || sudo cp /etc/iptables/empty.rules /etc/iptables/ip6tables.rules % sudo systemctl enable --now iptables ip6tables
This will not actually perform any firewall functionality (the ruleset is empty, unless you set some yourself), but it will allow the UBOS container to set up its own firewall.
-
Make sure your host network interface forwards traffic from the the containers. Add
IPForward=1
to the relevant.network
file. For example,/etc/systemd/networkd/wired.network
should read as follows:[Match] Name=en* [Network] DHCP=ipv4 IPForward=1
After you make a change to a
.network
file:% sudo systemctl daemon-reload % sudo systemctl restart systemd-networkd systemd-resolved
Pick a project directory
We recommend you do all your UBOS-related development below a certain directory.
Let’s say that directory is ~/ubosdev-nspawn
. Create that directory and enter
it:
% mkdir ~/ubosdev-nspawn
% cd ~/ubosdev-nspawn
Then create a sub-directory for your project files:
% mkdir projects
Pick a release channel to work on
By default, this setup uses the yellow
Release Channel.
This is the recommended Release Channel for most application development.
Note
If you want to develop on a Release Channel other than yellow
,
set the release channel as an environment variable for the setup command,
and replace the string yellow
with the name of the alternate Release Channel
in all other commands.
Download a container image
Download a container image. Go to http://depot.ubos.net/yellow/x86_64/images/
and look for the file ubos-develop_yellow_x86_64-container_LATEST.tar.xz
.
If you chose a ${CHANNEL}
other than yellow
, replace the yellow
in the above URL,
and then the yellow
in the filename with the name of the ${CHANNEL}
you chose.
We will call the name of the downloaded image file ${IMAGE}
. Download it into your
working directory.
Unpack the container image
If your filesystem is btrfs
, create a subvolume that becomes the filesystem
for your container:
% sudo btrfs subvol create ubos-develop-yellow
For all other filesystems, simply create a directory that becomes the filesystem for your container:
% mkdir ubos-develop-yellow
Then unpack:
% ( cd ubos-develop-yellow; sudo tar xfJ ../ubos-develop_yellow_x86_64-container_LATEST.tar.xz )
Start the container
In the project directory, run:
% sudo systemd-nspawn -b -n -M ubos-develop-yellow -D ubos-develop-yellow \
--bind $(pwd)/projects:/home/ubosdev/projects --bind $HOME/.m2:/home/ubosdev/.m2 --bind /dev/fuse \
--network-zone ubos-yellow
Note
This is a mouthful. You can create yourself a shortcut of you like:
% echo sudo systemd-nspawn -b -n -M ubos-develop-yellow -D ubos-develop-yellow \
--bind $(pwd)/projects:/home/ubosdev/projects --bind $HOME/.m2:/home/ubosdev/.m2 --bind /dev/fuse \
--network-zone ubos-yellow \
> start-container-yellow
% chmod 755 start-container-yellow
and run it as:
% ./start-container-yellow
If your filesystem is btrfs
, you can also add flag -x
to this invocation.
When you do, systemd-nspawn
will make all changes in a temporary filesystem instead,
and when you quit your container, your unpacked “directory” will still be unchanged.
Open a shell in the container
The shell in which you ran the systemd-nspawn
command now shows a login prompt.
You can login there as root
(with this password,
but if you do, we recommend you only use this shell to follow the system
log (e.g. with journalctl -f
).
To do your development, open up a separate shell and execute:
% sudo machinectl shell ubosdev@ubos-develop-yellow
This gives you a shell in your container. You will execute your build commands in this shell. You can open up as many shells on the container as you like.
Note that your projects directory on the host that you created earlier, is mounted into your container right where you are. You can see the same files there on the host and in the container:
% ls -al projects
That makes sharing files between the host (where you can edit them with the editor of your choice) and the container (where you build and run your code) quite easy.
Shut down the container
When you are done developing, shut down the container with:
^]^]^]
(three control-]
’s, in a rapid sequence) in the shell that you ran systemd-nspawn
in.