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.