I recently switched to Fedora Silverblue for my development machine. I want to document approximately how I do this (and why it’s awesome!).
Fedora Silverblue
This article is not an introduction to Fedora Silverblue, but a short summary is
well-placed: Fedora Silverblue is an immutable operating system that upgrades
atomically. Effectively, the root filesystem is mounted read-only, with the
exception of /var
, /home
, and /etc
. The system is upgraded by mounting a
new read-only snapshot as the root filesystem.
There are three methods of installing software on Fedora Silverblue:
-
Expanding the immutable base image using rpm-ostree. The base image is intended to be reserved for system components, but you can technically put anything in this image.
-
Installing graphical applications using Flatpak. This is sometimes-sandboxed, sometimes-not-so-sandboxed, but generally quite stable. If a layman were to install Fedora Silverblue, this would be the only installation method they would care about, aside from updating the base image when prompted.
-
Installing CLI tools using toolbox. This is a Podman (read: Docker) container of Fedora that mounts the user’s home directory. Because it’s a Podman image, you can install any RPM using Fedora’s package manager, DNF.
This article by Fedora Magazine goes into slightly more detail.
The basic development workflow
Instead of littering the base operating system with all means of development tools, development takes place within a toolbox. This looks a little like:
carmenbianca@thinkpad-x395 ~ $ ls
Elŝutoj Labortablo Nextcloud Projektoj Publike Ŝablonoj
carmenbianca@thinkpad-x395 ~ $ toolbox create my-project
Created container: my-project
Enter with: toolbox enter my-project
carmenbianca@thinkpad-x395 ~ $ toolbox enter my-project
⬢[carmenbianca@toolbox ~]$
⬢[carmenbianca@toolbox ~]$ ls
Elŝutoj Labortablo Nextcloud Projektoj Publike Ŝablonoj
⬢[carmenbianca@toolbox ~]$ # We're still in the same directory, which means
⬢[carmenbianca@toolbox ~]$ # that we still have our GPG and SSH keys, and
⬢[carmenbianca@toolbox ~]$ # other configuration files!
⬢[carmenbianca@toolbox ~]$
⬢[carmenbianca@toolbox ~]$ sudo dnf groupinstall "Development Tools"
[...]
The nice thing now is that you now have full freedom to mess with absolutely
anything, carefree. If your program touches some files in /etc
, you can mess
with those files without affecting your operating system. If you want to test
your program against a custom-built glibc, you can simply do that without fear
of breaking your computer. At worst you’ll break the toolbox, from which you can
easily recover by recreating it. And if you need more isolation from e.g. your
home directory, you can do that inside of a non-toolbox Podman container.
The editor problem
There is a slight problem with the above workflow, however. Unless you install your code editor inside of the toolbox, the editor has no access to the development tools you’ve installed. Instead, the editor only has access to the tools that are available in the base system image, or the editor only has access to the tools in its Flatpak runtime.
There are several ways to get around this, but they’re dependent on the editor you use. I’ll document how I circumvented this problem.
VSCodium in a Flatpak
I use the Flatpak version of VSCodium. VSCodium has an integrated terminal emulator. Unfortunately the Flatpak shell is rather extremely barebones—it doesn’t even have vi! Fortunately, we can tell VSCodium that we want to run a different program as our shell. Change settings.json to include:
[...]
"terminal.integrated.shell.linux": "/usr/bin/env",
"terminal.integrated.shellArgs.linux": [
"--",
"flatpak-spawn",
"--host",
"toolbox",
"enter",
"main-toolbox"
],
[...]
main-toolbox
here is an all-purpose toolbox that has heaps of tools installed.
You can adjust these settings on a per-workspace or per-project level, so a
given project might use a different toolbox than main-toolbox
.
The way the above command works is a little roundabout. It breaks out of the
flatpak and into the base installation using flatpak-spawn --host
, and then
enters a toolbox using toolbox enter
. The end result is that you have an
integrated terminal with a functional and feature-plenty shell.
This doesn’t solve everything, however. The editor itself also has some integration such as running tests. Because I mainly do Python development, it is fairly easy to bootstrap this functionality. The Flatpak runtime ships with Python 3.8. This means that I can create a Python 3.8 virtualenv and tell VSCodium to use this virtualenv for all of its Python stuff, which ends up working out just fine. The virtualenv is shared between the Flatpak and the toolbox, because both environments have access to the same file system.
For non-Python endeavours, Flatpak SDK extensions can be installed. This looks a little like:
$ flatpak install flathub org.freedesktop.Sdk.Extension.dotnet
$ flatpak install flathub org.freedesktop.Sdk.Extension.golang
$ FLATPAK_ENABLE_SDK_EXT=dotnet,golang flatpak run com.vscodium.codium
The final problem I ran into was using VSCodium to edit my Git commit messages.
VSCodium has a tiny box in the UI where you can write commit messages, but it’s
rather tiny and fiddly and not great. So instead I do
git config --global --add core.editor 'codium --wait'
. This should launch
codium --wait path/to/git/commit/message
when git commit
is run, allow
VSCodium to edit the message, and wait until the file is saved and exited to
evaluate the message.
The problem is that codium
only exists as an executable inside of the Flatpak.
It does not exist in the toolbox or the base operating system.
I circumvented this problem by creating a custom script in .local/bin/codium
.
It tries to detect its current environment by checking whether a certain file
exists, and tries to use that environment’s method of accessing the VSCodium
Flatpak. This looks like:
#!/bin/bash
# Will still need to pass "--wait" to make it behave nicely.
# In order to get --wait to work in a Flatpak, run
# `flatpak override --user --env=TMPDIR=/var/tmp com.vscodium.codium`.
if [ -f /app/bin/codium ]
then
exec /app/bin/codium "$@"
elif [ -f /usr/bin/codium ]
then
exec /usr/bin/codium "$@"
elif [ -f /usr/bin/flatpak-spawn ]
then
exec /usr/bin/flatpak-spawn --host flatpak run com.vscodium.codium "$@"
elif [ -f /usr/bin/flatpak ]
then
exec /usr/bin/flatpak run com.vscodium.codium "$@"
else
for arg do
shift
[ "$arg" = "--wait" ] && continue
set -- "$@" "$arg"
done
exec vi "$@"
fi
This allows you to run codium [--wait]
from anywhere and expect a functional
editor to pop up. There’s a fallback to vi, which I’ve not yet hit.
I hope this helps anybody looking for solutions to these problems :) It’s more than a little bit of bother, but it’s incredibly reassuring to know that your operating system won’t ever break on you.