diff options
author | Julio Capote <6135+capotej@users.noreply.github.com> | 2024-08-19 02:17:33 +0000 |
---|---|---|
committer | Julio Capote <6135+capotej@users.noreply.github.com> | 2024-08-19 02:17:33 +0000 |
commit | 9555acc417a668e791aa5758b0863d08786c28ce (patch) | |
tree | 483ed949358db93aec690c19c9f7212488b16083 /content | |
parent | 307304e1955c7e9a396a89683bf4e3ed42d04fc8 (diff) | |
download | capotej.com-9555acc417a668e791aa5758b0863d08786c28ce.tar.gz |
blog post
Diffstat (limited to '')
-rw-r--r-- | content/blog/2024-08-18-user-services-with-systemd.md | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/content/blog/2024-08-18-user-services-with-systemd.md b/content/blog/2024-08-18-user-services-with-systemd.md new file mode 100644 index 0000000..0486919 --- /dev/null +++ b/content/blog/2024-08-18-user-services-with-systemd.md @@ -0,0 +1,96 @@ ++++ +title = "User Services With Systemd" +date = "2024-08-18T19:05:10-04:00" + +tags = ["systemd","selfhosting"] ++++ + +# Your very own `systemd` + +Recently, I've started using `systemd` order to manage personal services on my servers. + +Before that, I had either set up 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 `systemd` instead is way better, since you get stuff like `journalctl` to view logs and `RestartAlways` keep things running. Also, all configuration 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: + +* User units **cannot** depend on system-wide units, or vice versa. For example, your user service cannot depend on system-wide `redis-server`. To specify dependencies between your services, you'll need to run all of those dependencies as user services. + +* User units are run without privileges so naturally they can't do `root` things like edit files outside of `$HOME` and listen below port `1024`. + +* Environment variables set in `~/.zshrc`, `~/.bashrc`, etc are not inherited. See the [environment variables section](https://wiki.archlinux.org/title/Systemd/User#Environment_variables) for more information on how to set/import environment variables for user units. + +# 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](https://www.freedesktop.org/software/systemd/man/latest/systemd.unit.html) 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 +``` + +### 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](https://wiki.archlinux.org/title/Systemd/User). + + |