Frontier Software

Service

[Service]

systemd.service(5)

/usr/lib/systemd/system/nginx.service

[Service]
Type=forking
PIDFile=/run/nginx.pid
PrivateDevices=yes
PrivateTmp=true
SyslogLevel=err

ExecStart=/usr/bin/nginx
ExecReload=/usr/bin/nginx -s reload
Restart=on-failure
KillMode=mixed
KillSignal=SIGQUIT
TimeoutStopSec=5

/usr/lib/systemd/system/postgresql.service

[Service]
Type=notify
TimeoutSec=120
User=postgres
Group=postgres

Environment=PGROOT=/var/lib/postgres

SyslogIdentifier=postgres
PIDFile=/var/lib/postgres/data/postmaster.pid
RuntimeDirectory=postgresql
RuntimeDirectoryMode=755

ExecStartPre=/usr/bin/postgresql-check-db-dir ${PGROOT}/data
ExecStart=/usr/bin/postgres -D ${PGROOT}/data
ExecReload=/bin/kill -HUP ${MAINPID}
KillMode=mixed
KillSignal=SIGINT

# Due to PostgreSQL's use of shared memory, OOM killer is often overzealous in
# killing Postgres, so adjust it downward
OOMScoreAdjust=-200

# Additional security-related features
PrivateTmp=true
ProtectHome=true
ProtectSystem=full
NoNewPrivileges=true
ProtectControlGroups=true
ProtectKernelModules=true
ProtectKernelTunables=true
PrivateDevices=true
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
RestrictNamespaces=true
RestrictRealtime=true
SystemCallArchitectures=native

systemd.exec(5)

systemd.kill(5)

systemd.resource-control(5)

Type=

simple

Default if ExecStart= is provided without Type=.

Typically, Type=exec is the better choice… simple proceeds with further jobs right after fork() returns, while exec will not proceed before both fork() and execve() in the service process succeeded.

[Unit]
Description=Foo

[Service]
ExecStart=/usr/sbin/foo-daemon

[Install]
WantedBy=multi-user.target
grep -sl Type=simple /usr/lib/systemd/system/*
/usr/lib/systemd/system/alsa-state.service
/usr/lib/systemd/system/avahi-dnsconfd.service
/usr/lib/systemd/system/cxl-monitor.service
/usr/lib/systemd/system/dm-event.service
/usr/lib/systemd/system/fancontrol.service
/usr/lib/systemd/system/ipp-usb.service
/usr/lib/systemd/system/lvm2-lvmpolld.service
/usr/lib/systemd/system/ndctl-monitor.service
/usr/lib/systemd/system/systemd-sysupdate.service
/usr/lib/systemd/system/wpa_supplicant-nl80211@.service
/usr/lib/systemd/system/wpa_supplicant@.service
/usr/lib/systemd/system/wpa_supplicant-wired@.service

exec

It is recommended to use Type=exec for long-running services.

grep -sl Type=exec /usr/lib/systemd/system/*
/usr/lib/systemd/system/sudo_logsrvd.service

forking

The use of this type is discouraged, use notify, notify-reload, or dbus instead.

PIDFile= is recommended with Type=forking

Note that PID files should be avoided in modern projects. Use Type=notify, Type=notify-reload or Type=simple where possible, which does not require use of PID files to determine the main process of a service and avoids needless forking.

grep -sl Type=forking /usr/lib/systemd/system/*
/usr/lib/systemd/system/auditd.service
/usr/lib/systemd/system/daxdev-reconfigure@.service
/usr/lib/systemd/system/epmd.service
/usr/lib/systemd/system/ftpd.service
/usr/lib/systemd/system/gpm.service
/usr/lib/systemd/system/healthd.service
/usr/lib/systemd/system/nginx.service
/usr/lib/systemd/system/sensord.service
/usr/lib/systemd/system/snmpd.service
/usr/lib/systemd/system/snmptrapd.service

oneshot

Unless RemainAfterExit= is set, it will not show up as started afterwards, but as dead.

all /usr/lib/systemd/system/initrd-*, /usr/lib/systemd/system/systemd-*… lots of units.

[Unit]
Description=Cleanup old Foo data

[Service]
Type=oneshot
ExecStart=/usr/sbin/foo-cleanup

[Install]
WantedBy=multi-user.target

dbus

Must have BusName=

grep -sl Type=dbus /usr/lib/systemd/system/*
/usr/lib/systemd/system/accounts-daemon.service
/usr/lib/systemd/system/avahi-daemon.service
/usr/lib/systemd/system/colord.service
/usr/lib/systemd/system/geoclue.service
/usr/lib/systemd/system/NetworkManager-dispatcher.service
/usr/lib/systemd/system/NetworkManager.service
/usr/lib/systemd/system/nm-priv-helper.service
/usr/lib/systemd/system/polkit.service
/usr/lib/systemd/system/rtkit-daemon.service
/usr/lib/systemd/system/udisks2.service
/usr/lib/systemd/system/upower.service
/usr/lib/systemd/system/wpa_supplicant.service

notify

It is expected that the service sends a “READY=1” notification message via sd_notify(3) or an equivalent call when it has finished starting up.

/usr/lib/systemd/system/postgresql.service above among many others.

Works with NotifyAccess= which defaults to main if not set. In the provided files the only alternative to main is all.

grep -s NotifyAccess= /usr/lib/systemd/system/*
/usr/lib/systemd/system/avahi-daemon.service:NotifyAccess=main
/usr/lib/systemd/system/NetworkManager-dispatcher.service:NotifyAccess=main
/usr/lib/systemd/system/nm-priv-helper.service:NotifyAccess=main
/usr/lib/systemd/system/rtkit-daemon.service:NotifyAccess=main
/usr/lib/systemd/system/systemd-mountfsd.service:NotifyAccess=all
/usr/lib/systemd/system/systemd-nsresourced.service:NotifyAccess=all
/usr/lib/systemd/system/systemd-sysupdate.service:NotifyAccess=main

notify-reload

grep -sl Type=notify-reload /usr/lib/systemd/system/*
/usr/lib/systemd/system/capsule@.service
/usr/lib/systemd/system/dbus-org.freedesktop.login1.service
/usr/lib/systemd/system/sshd.service
/usr/lib/systemd/system/systemd-logind.service
/usr/lib/systemd/system/systemd-networkd.service
/usr/lib/systemd/system/systemd-resolved.service
/usr/lib/systemd/system/systemd-udevd.service
/usr/lib/systemd/system/user@.service

idle

Note that this type is useful only to improve console output, it is not useful as a general unit ordering tool, and the effect of this service type is subject to a 5s timeout, after which the service program is invoked anyway.

grep -sl Type=idle /usr/lib/systemd/system/*
/usr/lib/systemd/system/autovt@.service
/usr/lib/systemd/system/console-getty.service
/usr/lib/systemd/system/container-getty@.service
/usr/lib/systemd/system/emergency.service
/usr/lib/systemd/system/getty@.service
/usr/lib/systemd/system/rescue.service
/usr/lib/systemd/system/serial-getty@.service