@capotej website

User Services With Systemd

Your very own systemd

Recently, I’ve started using systemd order to manage personal services on my servers.

Before that, I had set up classic system-wide unit files or, for more ad-hoc services, started the process inside of a screen session, then detaching, hoping the process didn’t crash overnight.

Using a user instance of systemd is way better, since you get stuff like journalctl to view logs and RestartAlways keep things running after random crashes. Plus, all configuration now lives in $HOME making it easy to edit and back up.

In this post, I will show you how to set this up on any modern Debian-based system (or any distro that uses systemd, really).

Debian 12.6 (bookworm) was used at the time of writing this post.

Caveats

There are a few things to note with this approach:

Getting Started

Enable linger for your user

By default, systemd user instances are only started after the first login of that user then killed once their last session is closed. This behavior makes sense in a desktop environment but not so much for a server environment where you typically want your daemons running at all times.

In order to change this behavior, you have to enable linger for your user by running the following:

$ loginctl enable-linger

You can verify if lingering is enabled by ensuring the column for LINGER says yes for your user when running:

$ loginctl list-users

Create configuration directory

The unit files for our services will live in $HOME/.config/systemd/user/. Ensure it’s created using by using mkdir -p, like so:

$ mkdir -p $HOME/.config/systemd/user/

Setting up an example service

We can now place this example.service unit in $HOME/.config/systemd/user/:

[Unit]
Description=Example Service

[Service]
Restart=always
RestartSec=1s
WorkingDirectory=/home/me/my-service-dir
ExecStart=racket hello-world-server.rkt

[Install]
WantedBy=default.target

Reload unit files

Just like system-wide systemd, if you edit or create new unit files for your user, you’ll need to reload your copy of systemd by running systemctl daemon-reload, like so:

$ systemctl --user daemon-reload

Start service on boot

This starts example as soon as your copy systemd is launched (which should be at boot, since we enabled lingering):

$ systemctl --user enable example

Starting, Stopping and Status

You can now run the same systemctl commands you are used to, except they are run as your user (instead of root) and now require the --user argument:

$ systemctl --user start example

$ systemctl --user stop example

$ systemctl --user status example

$ systemctl --user restart example

Logs

Similar to systemctl, you’ll need to pass --user to journalctl:

$ journalctl --user --unit=example

More information

You can read more about this feature on the Arch Linux Wiki: systemd/User.

#systemd #selfhosting