A minimal guide for running user‑level services with runit without systemd.
This setup allows you to supervise background services in your user session (similar to systemd --user units) using a lightweight runit service tree.
Overview
runit can supervise services from any directory.
For user services we create a dedicated service directory and run a user instance of runsvdir.
Example layout:
~/.local/service/
pipewire/
run
wireplumber/
run
dunst/
run
Each directory represents one service.
Starting the Supervisor
Run a user service tree with:
runsvdir -P ~/.local/service
This should be started inside your graphical/session environment so services inherit variables like:
DBUS_SESSION_BUS_ADDRESS
WAYLAND_DISPLAY
XDG_RUNTIME_DIR
Example (niri config):
spawn runsvdir ~/.local/service
Creating a Service
A runit service only needs a run script.
Example:
% kak ~/.local/service/dunst/run # Or easily you can use `./csrv dunst` for creating this staff
#!/bin/sh
exec dunst
Rules:
- always use
exec
- do not daemonize programs
- do not use
&
Make it executable:
The service will start automatically when runsvdir sees it.
Managing Services
Use sv to control services.
sv status ~/.local/service/*
sv restart ~/.local/service/dunst # Yeah, we also have ./sv-user script for this
sv down ~/.local/service/dunst
sv up ~/.local/service/dunst
Logging (optional)
Add a logging service:
Example:
#!/bin/sh
exec svlogd -tt ./main
Logs will appear in:
service/foo/log/main/current
One‑Shot Services
For tasks that should not automatically restart, create a down file:
touch service/wallpaper/down
Run manually:
Tips
- Keep
run scripts simple.
- Avoid running multiple instances of the same program.
- Separate core services (pipewire, portals) from session services (notifications, idle managers).
See Also:
- A few user-side services git
I am curious that how can I build build freebsd on my linux machine. I cloned Freebsd source code and I messed around with that. Then you know what i did... Yeah I ran make and i got this error:
Makefile:127: *** missing separator. Stop.
huh what? Like a cool guy I checked line 127 and you know what i got yeah...
.if make(*-jobs)
.include <jobs.mk>
.endif
And yeah... that's wrote for bmake(BSD make) not gmake(GNU make), lets install bmake and try again...
% sudo xbps-install bmake # For installing bmake on Voidlinux
% bmake
Explicit target required. Likely "buildworld" is wanted. See build(7).
*** Error code 1
Stop.
bmake: stopped making "_guard" in /home/mmdbalkhi/w/freebsd-src
# ok...
% bmake buildworld
bmake[1]: /home/mmdbalkhi/w/freebsd-src/Makefile.inc1:164: Unknown target x86_64:x86_64.
in .for loop from /home/mmdbalkhi/w/freebsd-src/Makefile.inc1:162 with _t = x86_64
in bmake[1] in directory "/home/mmdbalkhi/w/freebsd-src"
bmake[1]: stopped making "buildworld" in /home/mmdbalkhi/w/freebsd-src
*** Error code 1
Stop.
bmake: stopped making "buildworld" in /home/mmdbalkhi/w/freebsd-src
Ah... yeah we can't build freebsd easly on our linux machine so what can we do? And here we Are! cross-builds! According to wiki-Debain cross building is the act of compiling code for an architecture other than that of the computer doing the compiling, e.g. building an i386 package on an amd64 laptop. For more details I suggest you to read wiki-debain and Zoltan's Blog.
If you are lucky your linux machine has freebsd toolchain for your compiler(e.g. gcc, clangd), but if you live your life on void or other minimal distro, you should build gcc and bindutils for your own. First we need to prepare our workdir:
% mkdir -p ~/freebsd-cross/{src,build,tools}
% cd ~/freebsd-cross
- src is where we fetch gcc and bindutils source code
- build is where we build gcc and bindutils
- tools where we install toolchain bin files
Now lets fetch source code:
# binutils
% cd ~/freebsd-cross/src
% wget https://ftp.gnu.org/gnu/binutils/binutils-2.44.tar.xz
% tar -xf binutils-2.44.tar.xz
# gcc
% wget https://ftp.gnu.org/gnu/gcc/gcc-13.2.0/gcc-13.2.0.tar.xz
% tar -xf gcc-13.2.0.tar.xz
% cd gcc-13.2.0
% ./contrib/download_prerequisites # for downloding deps, mpc, etc.
- Consider that maybe newer version of gcc and maybe binutils might be not work in cross build and maybe you make disaster...
Lets build cross-binutils
% mkdir -p ~/freebsd-cross/build/binutils
% cd ~/freebsd-cross/build/binutils
% ../../src/binutils-2.44/configure \
--target=x86_64-unknown-freebsd13.2 \
--prefix=$HOME/freebsd-cross/tools/x86_64-freebsd \
--disable-nls \
--disable-werror
% make -j$(nproc)
% make install
Now you built a few tool like objdump, as, ld, etc.
Lets build gcc-13.2
% mkdir -p ~/freebsd-cross/build/gcc
% cd ~/freebsd-cross/build/gcc
% ../../src/gcc-13.2.0/configure \
--target=x86_64-unknown-freebsd13.2 \
--prefix=$HOME/freebsd-cross/tools/x86_64-freebsd \
--disable-nls \
--enable-languages=c,c++ \
--without-headers \
--disable-shared \
--disable-multilib \
--disable-threads \
--disable-libmudflap \
--disable-libssp \
--disable-libquadmath \
--disable-libgomp \
--disable-libatomic \
--disable-libvtv \
--disable-libstdcxx
make all-gcc -j$(nproc)
make install-gcc
Based on your cpu it might be took a little long to build. You build just compiler without libc or other shared libs. it's enough for our cross-building.
Just for checking all good, run ~/freebsd-cross/tools/x86_64-freebsd/bin/x86_64-unknown-freebsd13.2-gcc --version, If you got right output all good!