RStudio in systemd Nspawn Container

Linux
R
RStudio
systemd
Containers
Sysadmin
Author

Tyler Clark

Published

March 7, 2023

For some time now, I have been running RStudio Server at home via some sort of Docker configuration. The Rocker Project makes this relatively easy to set up, but there are some downsides I have been struggling with, namely library management. Restarting the docker image means re-installing all my additional libraries, system fonts, etc. There is always the option of building a docker image that installs that stuff, but then I have to make sure it’s up to date too. I also don’t really like the idea of saving the account password as plain-text in the docker-compose.yml file, even if it’s only for that docker app.

The first alternative I tried was a virtual machine, but that was a bit clunkier than I really wanted. I access my server almost exclusively from my Chromebook via SSH or web interfaces, so I had to setup Cockpit to access the VM via a web browser for the initial setup, and use the browser to setup network bridges, set RAM and CPU, etc., etc. As with the Docker image, this can definitely work, but wasn’t really what I wanted.

Linux Containers

Linux containers are somewhere between a Docker image and a full-blown virtual machine. There are multiple options, LXC being probably the most popular and full-blown, but I decided to use systemd-nspawn. It required no extra software to be installed, and is managed through systemd.

Initial Setup

As the Arch Wiki puts it, systemd-nspawn is chroot on steroids. That means that it is pretty simple to setup. I used debootstrap to bootstrap a very minimal Debian Bullseye system in /var/lib/machines/debian-rstudio:

sudo debootstrap --include=systemd,dbus bullseye /var/lib/machines/debian-rstudio

Continuing to follow the Wiki, I entered the chroot

sudo systemd-nspawn -D /var/lib/machines/debian-rstudio

and setup a root password, a user account, and installed R and RStudio Server.

That mostly sets up the chroot, but the container doesn’t have networking yet.

Networking

I struggled with this a little, but networks are not my strong suit. Eventually I wound up with the following .nspawn configuration:

[Network]
VirtualEthernet=yes
Port=tcp:8787:8787

This sets up a virtual ethernet link between the host and guest, sort of like a tunnel between the host0 interface in the guest to the ve-debian-rstudio interface on the host machine. Systemd automagically makes this connection since I use systemd-networkd. The Port line creates an iptables rule to forward traffic from port 8787 (Rstudio’s default port) on the host to 8787 on the guest. The Debian Wiki points out that I cannot access the Rstudio web interface from the host directly, but I don’t need to do that so I can live with that limitation.

The Arch Wiki then showed me that I had to manually add 2 more iptables rules to the host:

# iptables -A FORWARD -i ve-+ -o internet0 -j ACCEPT
# iptables -A INPUT -i ve-+ -p udp -m udp --dport 67 -j ACCEPT

After that, it was just a matter of logging in to the chroot again and enabling systemd-networkd. Presto!

Post-Install

Now that I had a connection, I just had to install various R libraries, tinytex, etc. This entire post was written using the new installation. All that’s left to do now is keep using it and see how it does.