Using Runit on Devuan

Everything Linux, A.I, IT News, DataOps, Open Source and more delivered right to you.
"The best Linux newsletter on the web"

Devuan and various systemd-free Linux distributions provide alternative init systems. runit is among the most barebones and lightest. Having a small code base makes it easier to maintain and also audit for bugs and security issues. It is able to run on other Unices like *BSD, MacOSX, etc., as well. In this article, I am going to cover the basics of the runit init scheme with Devuan as a base. However, most concepts and commands should be the same for other distributions. You may refer to the references at the end for learning in more detail.

Working Mechanism

According to the official documentaion, runit is an init scheme with service supervision. That means it handle automatic starting of services during boot, as well as monitoring and restarting them. Conforming to the UNIX philosophy, runit consists of various small tools and binaries (albeit not to the extent of being bloated *ahem* systemd *ahem*) for interacting with it and other daemons.
Like with most init systems, the kernel loads the first process – /sbin/init which is provided by the runit-init(8) program. It then replaces itself with runit(8). runit is what performs the system’s booting, running and shutting down and it does so in three stages:

  • Stage 1:
    The system performs the one-time initialization tasks through /etc/runit/1. We get an emergency shell if this stage fails.
  • Stage 2:
    runit starts /etc/runit/2 which handles the runlevels through runsvdir(8). This is the stage our system stays in when it’s running. We can also give the Ctrl+Alt+Delete reboot request at this stage.
  • Stage 3:
    If /etc/runit/2 returns without errors, which happens during system halt or reboot, runit starts /etc/runit/3. The shutdown tasks are performed in stage 3.
Bootup of a runit system


A standard installation of runit has 2 runlevels, default and single. A runlevel directory contains symlinks to other service directories. Most tasks are performed and most services are started in the default runlevel. But we can make our own runlevels by creating a new folder in/etc/runit/runsvdir/ and symlinking our desired services to that runlevel. My Devuan installation has two other runlevels created.

Inside runlevel directories

Runit changes the runlevels by switching the directory the runsvdir program is running in. This is handled by the runsvchdir command.

For example, to switch to the single user runlevel:
# runsvchdir single

Switching to single-user mode

We can also ask runit to start in a specific runlevel during bootup instead of the default. We can do so by appending the runitdir=name kernel parameter. Obviously, the runlevel name should exist i.e. a directory must be available at /etc/runit/runsvdir with that name.

For example, to directly boot to the single-user mode (i.e. the single runlevel), we can append runitdir=single to the kernel parameter.

In GRUB, we can do this by hitting the e key while highlighting an entry at the bootloader menu.

Modifying kernel parameters in GRUB menu

Hitting Ctrl+X will make the system boot with the given parameters, effectively getting us into single-user mode.

Booting directly into single runlevel

Managing Services

A service directory contains files and necessary scripts to manage the daemon. Service directories are located in the /etc/sv directory.

Service directories

These service directories must be symlinked to /etc/service otherwise runit won’t be able to access them.

runit knows only about services in /etc/service
we can manage services if the symlinks exist in /etc/service

Creating the symlink in /etc/service will essentially enable it so that it’s started at boot time. We can disable a service by creating a file named down inside the service directory.

Disabling the tor service

Although runit has several programs, we usually only need to interact with the sv command. The syntax is equivalent to systemd‘s systemctl command.

Starting a service:

# sv start <service_name>

Stopping it:

# sv stop <service_name>

Restarting or reloading a service:

# sv restart <service_name>

Check the status of a service:

# sv status <service_name>

There’s also rewrite of the sv command in Rust called rsv. However, I am not going to cover it in this article. Please check the link among the references below.


Everything Linux, A.I, IT News, DataOps, Open Source and more delivered right to you.
"The best Linux newsletter on the web"
Pratik Devkota
Pratik Devkota
Software engineering student interested in UNIX (GNU/Linux, *BSD, etc.), security as well as free and open-source software.


Please enter your comment!
Please enter your name here

Latest articles

Join us on Facebook