Back to home

Unit Files for the systemd User Instance

Systemd manages different types of units. The service unit being the most common one, representing a service or daemon. A unit file contains the configuration regarding a single unit. In case of a service unit, how to start and stop the service, how to check if the service and its dependencies are running.

In this Article, we show and explain some examples which can help as a starting point to write your own systemd units. For more complex requirements, we show some examples which you may like to extend your unit with.

The unit files for the user instance are usually stored in ~/.config/systemd/user. The name of the file defines the name and type of the unit. The file ~/.config/systemd/user/myredis.service defines a service unit named myredis.

The Unit files are commonly split into three parts. The Unit section contains some meta-data about the unit. The second section is named after the unit type, where Service is the most common. In this section, you can define what the unit does and how. The Install Section contains information about how to activate/deactivate a unit.

Information about how to manage units can be found in the following article: Manage daemons as user with systemd

Service Types

Simple Service

This example starts a Redis server on port 7777. The Unit section only defines the description and an (optional) url as documentation. The Service section defines the start and stop commands. The stop command is optional. If systemd stops a service, it will first execute the stop command and then kill all leftover processes of this unit.

# ~/.config/systemd/user/myredis.service
[Unit]
Description=Custom Redis on Port 7777
Documentation=https://support.nine.ch/a/2xNbpLp-SpQ

[Service]
ExecStart=/usr/bin/redis-server --port 7777
ExecStop=/usr/bin/redis-cli -p 7777 shutdown

[Install]
WantedBy=default.target

Forking Service

Systemd prefers services which do not daemonize themselves. If your application does daemonize, you need to tell systemd about it. This is done by setting the Service Type to forking. Further, it is recommended to define the PIDFile option to tell systemd which process is the main process.

%h is replaced with the user home directory and %pwith the name of the unit. Specifiers like this can help creating more robust and portable unit files. More specifiers can be found in the systemd.unit man-page.

# ~/.config/systemd/user/myredis.service
[Unit]
Description=Custom Redis on Port 7777
Documentation=https://support.nine.ch/a/2xNbpLp-SpQ

[Service]
Type=forking
ExecStart=/usr/bin/redis-server --port 7777 --daemonize yes --pidfile %h/.%p.pid
ExecStop=/usr/bin/redis-cli -p 7777 shutdown
PIDFile=%h/.%p.pid

[Install]
WantedBy=default.target

Template Service

Templates are a powerful tool of systemd. Units with names ending in @ are considered a template. This enables you to launch multiple similar instances of the same service. If you paste the following example into a file named myredis@.service, you can launch multiple instances of it like myredis@7777 and myredis@7778. The part behind the @ is then factored in to the %i specifier.

# ~/.config/systemd/user/myredis@.service
[Unit]
Description=Custom Redis on Port %i
Documentation=https://support.nine.ch/a/2xNbpLp-SpQ

[Service]
ExecStart=/usr/bin/redis-server --port %i
ExecStop=/usr/bin/redis-cli -p %i shutdown

[Install]
WantedBy=default.target

Advanced Configurations Snippets

Hooks

If you need some extra steps to setup or teardown your service, you can use the Pre/Post Start/Stop actions. You can add the same parameter multiple times if you need to. By prefixing your command with a -, you can tell systemd to ignore errors of this command. Otherwise, the service is not started if the Pre-Start command fails.

[Service]
ExecStartPre=/bin/mkdir -p /tmp/mytempdir
ExecStartPre=-/bin/false
ExecStartPost=/usr/bin/touch /tmp/mytempdir/started
ExecStopPost=/bin/rm -rf /tmp/mytempdir

Reload

If your service is capable of reloading its configuration, you can use the ExecReload parameter to specify how to trigger the reload. The $MAINPID variable is set to the main process of the daemon.

[Service]
ExecReload=/bin/kill -HUP $MAINPID

Restart

With the Restart parameter, you can specify whether systemd should restart the unit if it exits unexpectedly. The default is no, but always could save you some trouble:

[Service]
Restart=always

Setup the Environment

Sometimes, it is required to setup the environment for a service. With systemd, you can setup the working directory and additional environment variables quite easily.

The files specified with EnvironmentFile does override variables set with Environment. The file needs to exist unless it is prefixed with a -. The syntax for the EnvironmentFile is a shell-like KEY=VALUE.

[Service]
WorkingDirectory=/home/www-data/servicedir
Environment=ENV=production
EnvironmentFile=-/home/www-data/servicedir/.env

Links

More information about units can be found in the systemd.unit man page. For Service units, the systemd.service and systemd.exec man pages are a good starting point.

Didn't find what you were looking for?

Contact our support:

+41 44 637 40 40 Support Portal support@nine.ch