Systemd services and timers
Posted .
These are some notes on systemd services. Once in a blue moon I have to add or modify a service on my machine and every single time I have to look up how this works. So I decided to write up some basic notes for future reference.
Here are the docs on [Unit], [Install] and [Service].
Creating a new service
Create a new service using:
sudo systemctl edit --force --full $name
Here’s a basic service configuration
[Unit]
Description= #A short description of the service.
Requires= #Some unit
[Service]
Type= #A type
Exec= #Command that starts the service
ExecStart= #Optional start only command
ExecStop= #Optional stop only command
PIDFile= #Optional pidfile
User= #Optional user to execute command as
[Install]
RequiredBy= #Some unit, often multi-user.target
Targets
Targets can be either Requires
or Wanted
by a unit.
You can list targets using:
systemctl list-units --type=target
Some commonly used targets.
- basic.target
- loaded active active Basic System
- cryptsetup.target
- loaded active active Local Encrypted
- graphical.target
- loaded active active Graphical Interface
local-fs .target- loaded active active Local File Systems
- multi-user.target
- loaded active active Multi-User System
- network.target
- loaded active active Network
Types
Commonly used service types.
- simple
- default type. Assumes the process itself does not fork and that it will be available immediately to services that depend on it when forked by systemd.
- exec
- similar to
simple
except it waits with starting depending services until the main executable is started. - forking
- a service that forks itself, for executables that run in the background on their own. Provide
PIDFile=
. - oneshot
- a non-service that does not run in the background. For executables that do their thing and then stop. Provide
RemainAfterExit=yes
if systemd needs to consider it running after the main processes exits.
Example services
[Unit]
Description=ProtonVpn
Wants=network-online.target
After=network.target network-online.target
[Service]
Type=oneshot
ExecStart=/usr/bin/sudo /usr/bin/protonvpn c --p2p
ExecStop=/usr/bin/sudo /usr/bin/protonvpn d
RemainAfterExit=yes
User=$user
[Install]
RequiredBy=multi-user.target
[Unit]
Description=Pi-hole blacklist
Wants=pihole-FTL.service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/pihole -b example.com
ExecStop=/usr/local/bin/pihole -b -d example.com
RemainAfterExit=yes
[Install]
RequiredBy=multi-user.target
Timers
Docs for [Timer].
Create using, it should have the same name as the service it controls:
sudo systemctl edit --force --full $name.timer
Here’s a basic timer configuration
[Unit]
Description= #A short description of the timer.
[Timer]
OnCalendar= #Sets the time of execution
[Install]
RequiredBy=timers.target
The OnCalendar
has the following format:
DayOfWeek Year-Month-Day Hour:Minute:Second
Where Year, Month, etc can be replaced either by a value, a comma seperated list, a range using ..
and an asterisk *
.
In order to start a timer you need to enabled
and start
it.
sudo systemctl enable $name.timer
sudo systemctl start $name.timer
Example
[Unit]
Description=Start the blackslist
[Timer]
OnCalendar=*-*-* 9:00:00
[Install]
WantedBy=timers.target