Ripping Out Systemd: A Practical Guide to OpenRC on Debian
Replacing Debian's default init system is viable for minimal builds, but it requires navigating packaging landmines and service translations.
Systemd is no longer just an init system. Over the last decade, it has evolved into a comprehensive user-space plumbing layer, absorbing responsibilities ranging from network management to DNS resolution. Recent developments, such as the introduction of the systemd-sysinstall system installer and controversial feature additions like built-in age verification fields, have intensified the debate over its scope creep.
For developers building minimal container images, embedded ARM systems, or lightweight virtual machines, systemd's massive footprint can be a liability. In these environments, OpenRC offers a compelling alternative. It is a modular, dependency-based init system that runs on top of the system's native shell and standard utilities, preserving the Unix philosophy of doing one thing well.
Swapping the init system on an active Debian installation is entirely possible, but it is not a trivial operation. It requires bypassing safety guards in the package manager and manually translating service files.
The Packaging Trap: Purging an Essential Package
Debian treats systemd as an essential component of the operating system. If you attempt a standard purge, the package manager will block the operation to prevent you from rendering the system unbootable.
To force the transition, you must explicitly instruct apt to override this protection. However, a naive execution can leave the system in a half-configured, unbootable state if the package manager purges systemd before successfully installing and configuring the new init system.
The core migration command sequence looks like this:
sudo apt purge --allow-remove-essential systemd && sudo apt install openrc sysvinit-core
Using sysvinit-core is necessary because OpenRC on Debian runs on top of the traditional SysV init daemon (PID 1), handling the execution and dependency management of the actual runlevels and services.
Handling the Mid-Flight Failure
During this swap, a common failure mode occurs when the package manager successfully purges systemd but fails to fully unpack or configure OpenRC and sysvinit-core due to broken dependencies or script errors. If this happens, the system will fail to boot normally on the next restart.
To recover from this state:
- Interrupt the bootloader (GRUB or systemd-boot) and append
init=/bin/shto the kernel parameters to drop directly into a shell. - Remount the root filesystem as read-write:
mount -o remount,rw /. - Bring up your network interface manually.
- Re-run the installation command to ensure both packages are fully configured:
apt install openrc sysvinit-core
flowchart TD
A[Initiate Purge & Install] --> B{Did APT complete successfully?}
B -- Yes --> C[Reboot into OpenRC]
B -- No --> D[System Unbootable / Boot to Recovery]
D --> E[Mount Root FS Read-Write]
E --> F[Bring Up Network]
F --> G[Run: apt install openrc sysvinit-core]
G --> C
Translating Services: Systemd Units to OpenRC Runscripts
Once OpenRC is active, systemd unit files (.service) will no longer function. You must translate any custom or third-party services into OpenRC runscripts, which are executable shell scripts located in /etc/init.d/.
Consider a systemd unit file used to initialize hardware on an ARM-based laptop (such as starting Qualcomm remoteprocs on a Snapdragon-based Thinkpad):
[Unit]
Description=Start Qualcomm remoteprocs (SLPI/ADSP/CDSP)
DefaultDependencies=no
After=initrd-root-fs.target local-fs.target
Before=sysinit.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/sh -c 'echo start > /sys/class/remoteproc/remoteproc0/state; echo start > /sys/class/remoteproc/remoteproc1/state; echo start > /sys/class/remoteproc/remoteproc2/state'
[Install]
WantedBy=sysinit.target
To replicate this behavior in OpenRC, you write a runscript. Unlike systemd's declarative INI format, OpenRC uses shell scripting combined with a dedicated API. A proper translation of the above service looks like this:
#!/sbin/openrc-run
description="Start Qualcomm remoteprocs"
depend() {
provide remoteproc
need localmount
before bootmisc
}
start() {
ebegin "Starting Qualcomm remoteprocs"
echo start > /sys/class/remoteproc/remoteproc0/state
echo start > /sys/class/remoteproc/remoteproc1/state
echo start > /sys/class/remoteproc/remoteproc2/state
eend $?
}
After saving this file to /etc/init.d/remoteproc, make it executable and add it to the boot runlevel:
sudo chmod +x /etc/init.d/remoteproc
sudo rc-update add remoteproc boot
The Desktop Tax: What Breaks
While OpenRC is highly efficient for headless servers, containers, and embedded targets, deploying it on a modern desktop or laptop introduces significant integration challenges.
Modern Linux desktop environments (such as GNOME and KDE Plasma) are tightly coupled with systemd APIs. Specifically, they rely on systemd-logind for session tracking, seat management, power management (suspend/resume), and inhibiting sleep.
Without systemd, you must install elogind (a standalone extraction of logind) to handle console kit duties, and manually configure tools like PipeWire and WirePlumber to launch via user login scripts rather than systemd user services. If your workflow depends on complex desktop environments, the maintenance overhead of managing these loose integrations often outweighs the resource savings of OpenRC.
For minimal servers, embedded devices, and containerized microservices, however, stripping out systemd in favor of OpenRC results in faster boot times, lower memory consumption, and a highly predictable initialization sequence that is easy to debug using standard shell tools.
Sources & further reading
- Replacing Systemd with OpenRC in Debian — danielcordova.me
Lenn writes about cloud platforms, Kubernetes internals, and the infrastructure decisions that quietly make or break engineering organizations. Based in Berlin's vibrant tech scene, they have a talent for turning dense platform-engineering topics into prose that people actually finish reading.
Discussion 0
No comments yet
Be the first to weigh in.