iwakura.rip

:3 :3 :3 :3

Migrating all of my servers over to OpenSUSE MicroOS.

Why?

TL;DR: Grew tired of Debian, wanted something immutable and low-maintenance.

Every single server I have ever touched has always turned into a mess, because random packages with no use to me that held back updates and/or bloated my system (For context, my main server, which hosts my arr stack and some other services, has ~1700 packages installed, which is a lot, as I mainly only use Docker to deploy services), or even packages that have completely broken all kinds of libraries and required me to spend a Saturday reinstalling.

Furthermore, I do not have a lot of time anymore to maintain everything, as my real life is starting to take up more and more space. The fact that I use most of the things I host on a daily basis ment that I had to start finding alternatives.

And find an alternative I did. It's called OpenSUSE MicroOS. It has been developed by a reputable company called OpenSUSE, it targets container workloads, it is easy to deploy en masse using something like Combustion (although I won't be taking full advantage of this, I only have 2 nodes as of writing this) & minimal maintenance, as Micro OS auto-updates and can rollback automatically in the event of a failed update. This right here is the most crucial part.

The only downside I have found so far is... well... it uses systemd. However, even systemd haters like myself have to admit - it has the (financial) support of multiple big companies, it is the most widely used init system today, and the most secure. OpenRC or runit are not really viable alternatives on servers, as they just aren't popular enough. I will never use systemd on any of my desktop machines though - don't worry!

All of this combined makes MicroOS the perfect choice. So... how do we get started?

Installing MicroOS

Installing it is actually extremely simple. Download the iso pre-packaged with Podman (note: combustion and ignition are not enabled on the iso image provided by OpenSUSE), flash it to a usb stick and you're good to go.

You'll notice that MicroOS boots up pretty fast for a systemd distro. Took around 5-6 seconds to boot on my Dell Optiplex 3050 Micro. Once it has finished booting, it will ask you some simple questions and now you're done!

Once you have booted into the system, make sure you add your SSH key(s) and change the hostname, as is standard practice.

Deploying services using Podman

Something I found out later while trying to install MicroOS in a VM for the first time is that there was no option to pre-install Docker, only Podman was available! I thought this was a good excuse for me to try Podman as I had heard of it before but didn't exactly know why I should be using it.

Initially I started by installing Podman Compose, but quickly realized something while looking at blog posts others had made on deploying using Podman - they were all using Podman Quadlet. This looked pretty cool to me, so I decided to delve a little deeper.

Quadlet is, in short, a way to easily declare and deploy containers, like docker/podman compose. But instead of using docker compose, you let systemd do all the hard work for you.

Here's what a container deployment looks like using Quadlet:

# /etc/containers/systemd/caddy.container
[Unit]
Description=Caddy reverse proxy
After=local-fs.target

[Container]
Image=caddy:latest

PublishPort=80:80
PublishPort=443:443

Volume=/var/caddy:/etc/caddy
Volume=caddydata.volume:/data
Volume=caddyconfig.volume:/config

[Service]
Restart=always

[Install]
WantedBy=multi-user.target

...looks pretty similar to a systemd service right?

To get systemd to recognize these files, Podman uses a so called "systemd generator", called podman-systemd.unit. This generator dynamically translates those aforementioned .container files into fully working systemd services. Awesome!

So... how do we deploy this?

It's simple, really:

  1. Put the given container file into /etc/containers/systemd/caddy.container
  2. Create two files named caddydata.volume and caddyconfig.volume. You can compare these to named volumes in Docker.
  3. Reload systemd using systemd daemon-reload
  4. Start the container using systemctl start caddy

And now we have caddy up and running... right?

WARNING: Do not use this on special system directories like /home or /bin. It WILL break your system (according to the docker manual).

Well, It's not that simple. You see, MicroOS uses SELinux. In short, SELinux defines policies for every application, file, directory etc, and it doesn't play well with container volumes by default. Using this in its current state, caddy wouldn't be able to read or write anything. Fortunately, this is just a simple fix. Add a single z to any lines that define a volume, like so:

# /etc/containers/systemd/caddy.container
[Unit]
Description=Caddy reverse proxy
After=local-fs.target

[Container]
Image=caddy:latest

PublishPort=80:80
PublishPort=443:443

Volume=/var/caddy:/etc/caddy:z
Volume=caddydata.volume:/data:z
Volume=caddyconfig.volume:/config:z

[Service]
Restart=always

[Install]
WantedBy=multi-user.target

And now we have a working container! It's as simple as that.

Note on Libreboot

Something I've had to deal with is that Libreboot does not want to boot MicroOS. I have yet to find out why, but I found a simple workaround; just use SeaBIOS instead by pressing esc at boot, and select your boot medium.

-- hex⏎