systemd allows you to create and manage services in extremely powerful and flexible ways. This page will only cover the most basic uses; for full details, please see the systemd manual pages.

As a modern service manager, systemd builds on the concepts, knowledge and experience of previous and contemporary service managers such as daemontools, runit and nosh. If you've ever used any of these, you will probably find systemd's service management features to be easy and comfortable.

If your only experience is with System V init.d scripts, you may be confused at first. Init.d scripts use many ugly hacks (for example, PID files, and all of the infrastructure surrounding PID files) to work around the fundamental brokenness of sysv-rc. If you have grown accustomed to these hacks, you may first need to unlearn some bad habits.

Unit files

If you're creating a brand new unit file for your service, you must first come up with a name. The name you select must not collide with any existing service name, because your unit file will take precedence over any Debian default unit file with the same name. For the purposes of this page, we'll use the name myservice.

Create your service's unit file with the ".service" suffix in the /etc/systemd/system directory. In our example, we will be creating a /etc/systemd/system/myservice.service file.

Unit files use the ".INI" syntax, with section headers in square brackets, followed by variable declarations within that section, one per line. We'll need three sections: Unit, Service and Install. For now, don't worry about the separate meaning of each section. Just follow the examples to see which variables go in which section.

Service type

The first thing you must identify is what type of service you will be managing. systemd.service(5) lists the types: simple, forking, oneshot, dbus, notify or idle.

Most services should use the simple type, which means a program that runs in the foreground. If your service normally runs itself in the background, search the documentation to see if it has an option to disable that. Running in the foreground is preferred.

If you can't prevent the daemon from forking itself into the background, then you must use the forking type.

Also, decide whether you want systemd to restart (Restart=) your service when it exits. The default is no (which is different from daemontools). The other choices are always, on-success, on-failure, on-abnormal, on-watchdog or on-abort. You can even set a delay before systemd restarts it (with RestartSec=).

Environment setup

Some services require configuration of their environment, such as which user they run as (if not root), which directory they start in (if not /), environment variables, resource limits, etc. These variables are documented in systemd.exec(5).

Logging may also be configured here, if you need to use something other than systemd's native logging (accessible through journalctl(1)).

Service dependencies

For the purposes of this page, we'll assume that you want your service to start at boot time, and that you need it to wait for the network to be brought up first. The variables that control inter-service dependencies are documented in systemd.unit(5).

Putting it together

For our basic service, which uses the network, and should be run every time we boot into "multi-user.target" or higher (i.e. all normal system boots, with or without a graphical Display Manager), we end up with a service unit file like this:

[Unit]
Description=My Service
After=network.target

[Service]
Type=simple
Restart=always
ExecStart=/usr/local/bin/myservice

[Install]
WantedBy=multi-user.target

Making it go

After creating or modifying any unit files, we must tell systemd that we want it to look for new things:

systemctl daemon-reload

Our new service should be recognized at this point, but it won't run yet. We need to do two more things. First, tell systemd to enable it, so that it will start every time we boot:

systemctl enable myservice.service

Second, start it now:

systemctl start myservice.service

Note that you don't get feedback from this command, because all it does it send a message to systemd telling it to start your service. The command you typed doesn't hang around to see what happens next. You may use systemctl status myservice.service (or systemctl status myservice) to check on your service, to make sure it seems OK.

Also note that systemctl status myservice gives more information if you run it as root, compared to running it as a normal user.


CategoryBootProcess | CategorySystemAdministration