Some Linux based systems like Debian and Ubuntu are using systemd as init daemon. That means that initially after loading the kernel, systemd is the first program which is started on the system which in result starts all other components of the system. Such service can be compared with Windows Services, where a service can be defined to run at start, run at specified intervals and use a specific user when executed.
Systemd provides many ways how a service can be configured. I am addressing the most basic ones which are most used in my day-to-day work with Linux systems. Such services enable tasks to be executed at system startup and on a time-controlled basis. At the same time, each execution is logged, allowing the output of the program to be viewed at a later date. In the event of malfunctions such as program crashes or unsuccessful execution, tasks can be re-executed as often as required or stopped after the 5th restart until an administrator checks the malfunction.
Service File
A service usually contains 3 main parts named Unit, Service and Install and is mostly stored in /usr/lib/systemd/system/
, /etc/systemd/system/
or /lib/systemd/system/
. The file extension is .service
- for example /usr/lib/systemd/system/myservice.service
.
|
|
The service is divided into three parts: Unit, Service and Install.
Unit contains a main description of the service and contains dependencies to other services. Like the example above, After=network.target
describes that the service should be started after the network management stack was started. This does not mean that an internet connection is currently active.
It’s more important here that the service is stopped on shutdown before disconnecting network. This allows the application to close all open connections properly.
If you want to add additional dependencies, these can be added with space as separator. For example only start the service after MySQL/MariaDB because the application requires a database connection: After=network.target mysql.service
.
The directives Before=
and After=
are only for ordering startup/shutdown of the service. If network isn’t available, the service will be started regardless.
Service contains the configuration how the service is started. Most important here is ExecStart=
which describes which binary is started by the service.
Type=simple
is the most common type of service. It’s used for services which are started and stopped by systemd. If the service is a daemon which runs in the background, Type=forking
is the right choice. Type=oneshot
is used for services which are started and stopped immediately after the execution of the binary. Type=notify
is used for services which send a notification to systemd when the service is ready to accept connections. This is mostly used for services which are started and stopped by systemd.
Restart=always
describes that the service should be restarted if it crashes. RestartSec=10s
describes that the service should be restarted after 10 seconds if it crashes. This is useful to prevent a service from crashing and restarting in a loop.
User=
and Group=
can be used to specify which user and group the service should run as. This is useful to run the service as a non-root user.
WorkingDirectory=
can be used to specify the working directory of the service. This is useful if the service requires a specific directory to work properly.
EnvironmentFile=
can be used to specify a file which contains environment variables. This is useful if the service requires environment variables to work properly.
Install describes where the service is installed when it get’s enabled. multi-user.target
is mostly the right choice here. This means that the service is started when the system is in multi-user mode. This is the default mode of a Linux system.
An extended documentation is available at https://www.freedesktop.org/software/systemd/man/systemd.service.html.
Install and start service
After creating the service file, the service can be enabled and started using the following commands:
|
|
This command enables the service to start at boot and starts the service immediately.
Service state
The state of the service can be checked using the following command:
|
|
This command shows the current state of the service, the last log entries and the current process ID of the service.
|
|
If more information is required, the log entries can be viewed using the following command:
|
|
Additionally, most logs are written to the syslog which is most commonly located at /var/log/syslog
.
Systemd Timer
A systemd timer can be used as modern replacement for cronjobs. It’s more flexible and provides more options to configure the execution of a task. A timer is always linked to a service which is executed by the timer.
As timers most commonly are used to execute a service at a specific time, the service should be of type oneshot
. This means that the service is executed once and then stopped. If the service is of type simple
, the service will be executed and systemd will wait for the service to finish. This is not the desired behavior for a timer.
We assume that the previously created service myservice
is used in the following example and the type of the service is oneshot
. The service should be executed every 5 minutes.
Timer File
A timer usually contains 3 main parts named Unit, Timer and Install and is mostly stored in /usr/lib/systemd/system/
, /etc/systemd/system/
or /lib/systemd/system/
. The file extension is .timer
- for example /usr/lib/systemd/system/myservice.timer
.
|
|
The main difference to a service file is that the timer contains a Timer section instead of a Service section. The Unit section is the same as in a service file.
Timer contains the configuration how the timer is executed. Most important here is OnCalendar=*-*-* *:0/5:00
which describes that the service should be executed every 5 minutes. The format of the OnCalendar
directive is YYYY-MM-DD HH:MM:SS
where *
is a wildcard. The AccuracySec
directive can be used to specify the accuracy of the timer. This is useful if the timer should be executed at a specific time.
Timer state
The state of the timer can be checked using the following command:
|
|
This command shows the current state of the timer, the last log entries and the current process ID of the timer.
|
|
A detailed list of all timers can be viewed using the following command:
|
|
A systemd timer can be enabled, started and disabled the same way as a service:
|
|
Conclusion
Systemd is a powerful tool to manage services and timers on Linux systems. It provides a lot of options to configure services and timers. This article only covers the most basic options. For more advanced options, the official documentation is recommended.