This post shares my experience in replacing systemd by openrc on my debian.
Why OpenRC
There are a few reasons. First, I’m not perfectly happy with systemd
. It’s OK if you do nothing with it, but at some point, I had to write a specific service, and the fact that systemd does everything on your machine (hostnamed
, resolvd
, etc) makes it hard to just tweak just a few things. Also I don’t like journald
, and I hate socket activations.
Now I decided between OpenRC
and runit
by looking at their features, and I like the fact that OpenRC
uses dependencies for init scripts. It doesn’t come with user services, more on that later.
Installation
To make the installation as easy as possible, I booted from a rescue usb stick, chrooted into my system, and typed
aptitude install openrc
that’s it ! I tried before on virtual machines to update inside a running machine, it proved to be a mistake. Booting from a rescue CD/usb stick is much easier
The end result
Even without systemd, you will still see some systemd files and applications:
the
udev
binary is actually calledsystemd-udevd
, because udev is now part of systemd. I have nothing against udev, and replacing it seems a bit cumbersome, so I’ll keep it for nowthe
libsystemd0
package is still installed. A few years ago it was possible to replace it withlibelogind0
(ABI compatible) but the newelogind
depends onlibsystemd0
and conflicts withlibelogind0
.
An important thing to note is that getting rid of systemd does not get rid of code written in conjunction with systemd. Typically, udev
is part of systemd, elogind
is a fork of part of systemd
…
A few commands
To know the list of services that are currently run:
rc-status
Start/Stop a service
/etc/init.d/NAME [start|stop]
rc-service NAME [start|stop]
Remove a service from startup
rc-update del NAME
User services
systemd
does not only manage system services, but also user services. openrc
doesn’t. It turns out that there are a ton of user services that are run when someone logs on a machine: Typically, on my main desktop, 15 services (!) are launched. Some of them are pretty important and almost mandatory. Typically, I suspect that users that have a bad experience with openrc typically didn’t realize they’d need to add some users services.
A big one is pipewire, if you want to have sound. Other services are largely irrelevant, with the exception of dbus
Pipewire
To launch pipewire, 3 applications should be run: pipewire
, pipewire-pulse
and wireplumber
If you use a desktop environment (like KDE or gnome), an easy way to have these programs launched at startup is to create a few XDG files:
root% cat /etc/xdg/autostart/pipewire.desktop
[Desktop Entry]
Name=PipeWire
Comment=Start PipeWire
Icon=pipewire
Exec=pipewire
Terminal=false
Type=Application
NoDisplay=true
root% cat /etc/xdg/autostart/pipewire-pulse.desktop
[Desktop Entry]
Name=PipeWire pulse
Comment=Start PipeWire pulse
Icon=pipewire
Exec=pipewire-pulse
Terminal=false
Type=Application
NoDisplay=true
root% cat /etc/xdg/autostart/wireplumber.desktop
[Desktop Entry]
Name=Wireplumber
Comment=Start Wireplumber
Icon=pipewire
Exec=wireplumber
Terminal=false
Type=Application
NoDisplay=true
The systemd services also include launching pipewire -c filter-chain.conf
. I’m not sure it’s important, but if it makes a difference for you, you may add that service as well.
dbus
dbus
integrates with the login daemon from systemd
, which makes it so that each connection to the computer uses the same bus.
So if you launch the graphical interface, then ssh to the machine, ssh will see the bus.
This is not true with openrc, and some work needs to be done for this work.
Here are some lines to add to your shell configuration:
if [ -n "$SSH_CLIENT" ]; then
bus_id=$(cat /etc/machine-id)-0
dbus_file="$HOME/.dbus/session-bus/${bus_id}"
if [ -r "$dbus_file" ]; then
source "$dbus_file"
export DBUS_SESSION_BUS_ADDRESS
export DBUS_SESSION_BUS_PID
export DBUS_SESSION_BUS_WINDOWID
fi
fi
The -0
is because I’m using display :0
, you can change this if relevant.
You can change all of this into export DISPLAY=:0
of course but I prefer for the variable DISPLAY
to not be set.