Presuming that one could very hypothetically use something like MicroOS for immutable servers, development machines and regular desktops for non-technical users, let’s see how that dream would look in practice.

The hypothetical containers are already ubiquitous

My hypothetical is obviously tongue-in-cheek. I do this already. Containers are not a fancy, new thing anymore that you probably don’t need. Most likely you’re using them even if you didn’t think you did. And it may not seem feasible to everyone how real the all-container system is.

All your base are read-only

Installing the base system works very much like a regular openSUSE image, or installing most linux distros really. Use your favorite tool to prepare a USB stick, double-check that all of your files are backed up and boot into the new system. Installation will get you into the installer, where you’re asked what role you want. Each role maps to a pattern that pulls in packages needed for that scenario. We’ll get to differences in a bit, let’s cover what’s the same first.

openSUSE MicroOS installer showing role selection

Transactions, transactions, transactions

MicroOS is what you call a transactional system. The root filesystem is read-only and only changes between reboots, which gives you certain guarantees that you don’t have on Tumbleweed or Leap. If something changes it’s part of a transaction. And there’s no chance that the system breaks because of package installations because it’s run independent of the running system. Since the root filesystem isn’t a moving target anymore investigating an issue can always be tied to a revision. All of this is based on btrfs btw, which natively supports Copy-on-Write snapshots.

As a side effect, zypper can’t be used directly:

zypper in rust
This is a transactional-server, please use transactional-update to update or modify the system.

Fret not, we can still use zypper, just not to modify the current root. Instead we use transactional-update which opens a container on a new revision. The -c flag can be used to re-enter the last snapshot, which is handy if you make further changes. Otherwise you create independent, new snapshots. And -d means the snapshot is discarded if you didn’t make any changes to the root.

sudo transactional-update -d [-c] shell

And if something goes wrong, you roll back. No need to track down, re-download and install old versions of what’s installed. If you don’t specify anything, you’ll go back to the previous one. This is what makes me less concerned a big upgrade causes me problems for days.

sudo transactional-update rollback [SNAPSHOT]

And if what you wanna do is upgrade everything, the equivalent of zypper dup is available as a shortcut:

sudo transactional-update dup

By default you get a generous /var partition. And there’s a mechanism to perform regular updates and reboots, which is transactional-update.timer which you want to change to your liking.

Just let me install my packages

Alright, let’s forget about transactions. All you want is maintain your list of packages and let your system figure it out behind the scenes:

pkcon install rust
pkcon remove docker
pkcon update
pkcon upgrade-system

Curiously this is managed via dnf and doesn’t require any knowledge of snapshots. Whatever changes you make will be prepared so that next time you reboot you’ll see the changes live. As a user you don’t need to know if you’re creating or updating a snapshot.

For now this only works fully on the command-line. Support via GNOME Software is in the works, though.

I rely on a host of features

What’s necessary to have on the host for development and maintenance? You may find yourself typing man date and wonder why you get an error telling you the command man isn’t installed. And the question to ask yourself is, how lean can the host be? Do man pages take up a lot of space? How do they affect the reliability of upgrades? What do they provide on a host with a minimum of packages installed? I’d like you to entertain the thought that the host doesn’t contain anything needed for non-trivial maintenance or development tasks that isn’t necessary to keep the system running. Maybe it shouldn’t live on the host if it’s only needed on a case-by-case basis?

I like my user interface graphical

The MicroOS Desktop (GNOME) role, analogous to the patterns-microos-desktop-gnome pattern makes all the difference if your use case is either a development machine or a regular desktop. You get everything needed for a fully functional GNOME desktop, including flatpak, system apps and fonts. Also, as part of the firstboot experience a flatpak’ed browser is installed, which is Firefox. This is especially interesting in that there’s no browser in the system image. If you find this confusing: Any system apps are unconfined. A web browser is one of the biggest risks on your system, and it should be as easy as possible to update and tightly sandboxed. By running it as a flatpak you can update your browser any time without changing anything else in the system and reduce what a malicious website could try to access.

Installing apps on a user level

I don’t have any apps installed system-wide, not counting the included system apps. My user has everything in their home. No need for extra priviledges and no chance the system breaks due to an app that was just installed.

flatpak search telegram
Telegra… Telegram Desktop messe… org.telegram   3.1   stable flathub

What’s really neat is that you don’t have to spell out the full name of an app:

flatpak install vim
   1) app/io.neovim.nvim/x86_64/stable
   2) app/net.mediaarea.AVIMetaEdit/x86_64/stable
   3) app/org.vim.Vim/x86_64/stable

Of course there’s the flathub-beta flatpak which you might want. Add it via one command, and from then on new packages will turn up in app lookups.

flatpak remote-add --user flathub-beta https://flathub.org/beta-repo/flathub-beta.flatpakrepo

For some more advanced points you may wanna check out my article on looking after your flatpaks.

Running virtual machines

Let’s be very lazy on this one since we’ve really gotten to the point where there’s a multitude of options to run a VM. And if you’re a user who simply needs to run another system with no specific needs, Boxes is your friend. Install it, run it, pick a disk image and get going. Windowed and fullscreen options available. Snapshots are available in the settings so you can copy the state before and after you make some bigger changes. That’s basically it, no array of options.

Running containers

Out of the box you get support for podman, meaning you get to run containers as your user. No need for extra priviledges and no need to touch system-wide files:

podman search opensuse
docker.io     docker.io/opensuse/tumbleweed
podman run -dit docker.io/opensuse/tumbleweed

If you’re familiar with Docker the commands will feel very familiar and you’re up and running very quickly.

Getting out the toolbox

Very often when you’re thinking to use a full shell, it is to install a particular tool and investigate an issue you were seeing, building something with certain dependencies or running a script. There’s no need for a fully separate environment that requires setting up, though. I wrote about developing in toolbox containers before. What this does is open a shell in a Tumbleweed image while mounting your home and devices into the container. Since it’s a container It can be used on non-transactional systems, too, by the way so you can use Tumbleweed tools on a Leap host or Fedora on Tumbleweed and other fun combinations. And you can have multiple environments and re-create them as needed since this is just running podman containers behind the scenes. Best of all you can install whatever you need on a server without even being root!