Systemd Basics
Introduction to systemd service management
Section titled “Introduction to systemd service management”0. Specs
Section titled “0. Specs”0.1. The What
Section titled “0.1. The What”systemd is a suite of basic building blocks for a Linux system. It provides a system and service manager that runs as PID 1 and starts the rest of the system (from systemd.io).
systemd is a software suite that provides an array of system components for Linux operating systems (from Wikipedia).
systemd is an init system for Linux that replaces SysV init. Many distributions use it as their init system, including Debian, Ubuntu, and RHEL. However, several distributions do not use systemd, such as Slackware, Devuan, Alpine, and Gentoo.
A strong alternative to systemd is OpenRC.
0.2. Definitions
Section titled “0.2. Definitions”D-Bus (Desktop Bus): A message-oriented middleware mechanism that allows communication between multiple processes running concurrently on the same machine (from Wikipedia).
cgroups (Control Groups): A kernel feature that allows setting resource utilization limits for processes, such as CPU shares, memory usage, and block I/O per process. Originally developed by Google.
0.3. Sources
Section titled “0.3. Sources”- wiki.debian.org
- www.digitalocean.com
- www.digitalocean.com
- www.digitalocean.com
- www.redhat.com
- wikipedia.org
- wikipedia.org
- access.redhat.com
- www.howtogeek.com
- systemd.io
- The Debian Administrator’s Handbook by Raphaël Hertzog and Roland Mas
- Linux Service Management Made Easy with systemd by Donald A. Tevault
1. systemd Units
Section titled “1. systemd Units”Units are the resources that systemd knows how to manage and to operate.
1.1. Unit Locations
Section titled “1.1. Unit Locations”Unit files are located in the following directories (listed in increasing order of precedence):
/lib/systemd/system//run/systemd/system//etc/systemd/system/
1.2. Unit Types:
Section titled “1.2. Unit Types:”.service: Contains information for managing a service or application, including starting, stopping, automatic startup, and dependencies..socket: Describes a socket for systemd’s socket-based activation. Must have an associated.servicefile..device: Describes a device that requires systemd management. Not all devices have a.devicefile..mount: Describes mountpoints that need to be managed by systemd..automount: Configures a mountpoint to be automatically mounted. Must have a corresponding.mountunit..swap: Describes swap space on the system..target: Used to synchronize with other units (similar to runlevels in SysV init)..path: Defines a path for path-based activation. A matching unit is started based on the path’s existence or state..timer: Defines a timer managed by systemd. A matching unit is started when the timer elapses..snapshot: Created with thesystemctl snapshotcommand. Saves the current system state but does not persist across reboots..slice: Associated with cgroups (Linux Control Group nodes), allowing resource restrictions to be applied..scope: Created automatically by systemd from information received via its bus interfaces. Manages sets of system processes created externally.
1.3. Example Unit Files
Section titled “1.3. Example Unit Files”Contents of /lib/systemd/system/apache2.service:
[Unit]Description=The Apache HTTP ServerAfter=network.target remote-fs.target nss-lookup.targetDocumentation=https://httpd.apache.org/docs/2.4/
[Service]Type=forkingEnvironment=APACHE_STARTED_BY_SYSTEMD=trueExecStart=/usr/sbin/apachectl startExecStop=/usr/sbin/apachectl graceful-stopExecReload=/usr/sbin/apachectl gracefulKillMode=mixedPrivateTmp=trueRestart=on-abortOOMPolicy=continue
[Install]WantedBy=multi-user.targetContents of /lib/systemd/system/ssh.service:
[Unit]Description=OpenBSD Secure Shell serverDocumentation=man:sshd(8) man:sshd_config(5)After=network.target nss-user-lookup.target auditd.serviceConditionPathExists=!/etc/ssh/sshd_not_to_be_run
[Service]EnvironmentFile=-/etc/default/sshExecStartPre=/usr/sbin/sshd -tExecStart=/usr/sbin/sshd -D $SSHD_OPTSExecReload=/usr/sbin/sshd -tExecReload=/bin/kill -HUP $MAINPIDKillMode=processRestart=on-failureRestartPreventExitStatus=255Type=notifyRuntimeDirectory=sshdRuntimeDirectoryMode=0755
[Install]WantedBy=multi-user.targetAlias=sshd.serviceContents of /lib/systemd/system/ssh.socket:
[Unit]Description=OpenBSD Secure Shell server socketBefore=sockets.targetConditionPathExists=!/etc/ssh/sshd_not_to_be_run
[Socket]ListenStream=22Accept=no
[Install]WantedBy=sockets.targetContents of /etc/systemd/system/snap-firefox-2356.mount:
[Unit]Description=Mount unit for firefox, revision 2356After=snapd.mounts-pre.targetBefore=snapd.mounts.targetBefore=local-fs.target[Mount]What=/var/lib/snapd/snaps/firefox_2356.snapWhere=/snap/firefox/2356Type=squashfsOptions=nodev,ro,x-gdu.hide,x-gvfs-hideLazyUnmount=yes[Install]WantedBy=snapd.mounts.targetWantedBy=multi-user.target1.4. Unit File Structure
Section titled “1.4. Unit File Structure”Unit files consist of sections. The [Unit] and [Install] sections can exist in all unit types. Additional sections exist for specific unit types: [Socket], [Mount], [Automount], [Swap], [Path], [Timer], and [Slice].
Sections contain directives, which can be general or specific to certain unit types.
For a complete list of directives, see:
https://www.freedesktop.org/software/systemd/man/systemd.directives.html
1.4.1. [Unit] Section Directives (Applies to all unit types)
Section titled “1.4.1. [Unit] Section Directives (Applies to all unit types)”Description: A brief description of the unit.Documentation: Location of documentation.Requires: Units this unit depends on. All must be activated for this unit to activate.Wants: Similar toRequiresbut less strict. Systemd attempts to activate listed units before this unit.BindsTo: Similar toRequires; also stops this unit when the listed unit stops.Before: This unit must start before listed units (does not imply dependency).After: Listed units must start before this unit (does not imply dependency).Conflicts: This unit cannot run simultaneously with listed units. Starting this unit stops others.Condition: Unit starts only if conditions are met; otherwise, it is skipped.Assert: Similar toCondition, but unmet conditions cause a failure.ConditionPathExists: Unit starts if the specified path exists. Prefix with!to negate.
1.4.2. [Install] Section Directives (Applies to all unit types)
Section titled “1.4.2. [Install] Section Directives (Applies to all unit types)”WantedBy: Similar to theWantsdirective; commonly used with targets.RequiredBy: Similar toWantedBybut stricter; failure occurs if dependency is unmet.Alias: Allows the unit to have an alias name (e.g.,sshforsshd).Also: Additional units to install/uninstall alongside this unit.DefaultInstance: Used only with template units; specifies the default instance name.
1.4.3. [Service] Section Directives (Applies to service units)
Section titled “1.4.3. [Service] Section Directives (Applies to service units)”Type: Defines the service type:simple: Systemd assumes the service starts immediately.exec: Similar tosimple, but systemd waits for the binary to execute.forking: The service forks a child process and exits.oneshot: The service runs briefly and exits.dbus: The service acquires a name on the D-Bus.notify: The service notifies systemd when startup is complete.idle: The service runs only after all other jobs are dispatched.
RemainAfterExit: Commonly used withoneshot; indicates the service remains active after the process exits.PIDFile: Forforkingtype; specifies the file containing the child process PID.BusName: Fordbustype; the D-Bus name to acquire.NotifyAccess: Controls which service status messages are notified (main,exec, ornone).Environment: Environment variables to set.EnvironmentFile: File containing environment variables. Prefix with-to ignore if the file is missing.KillMode: How to stop the service:process(kill main process only),mixed(kill main and child processes),none(only runExecStop).ExecStart: Command to start the service. Prefix with-to ignore failures.ExecStartPre: Commands to run before the main process.ExecStartPost: Commands to run after the main process starts.ExecReload: Command to reload the service.ExecStop: Command to stop the service.ExecStopPost: Commands to run after stopping the service.RestartSec: Time to wait before restarting.Restart: Conditions for automatic restart (always,on-success,on-failure,on-abnormal,on-abort,on-watchdog).RestartPreventExitStatus: Prevents restart if the specified exit code is received.RuntimeDirectory: Directory under/runfor the service.RuntimeDirectoryMode: Permissions for the runtime directory (default:0755).TimeoutSec: Time to wait before marking start/stop as failed (or killing).TimeoutStartSec: Time to wait before marking start as failed.TimeoutStopSec: Time to wait before marking stop as failed.
1.4.4. [Socket] Section Directives (Applies to socket units)
Section titled “1.4.4. [Socket] Section Directives (Applies to socket units)”ListenStream: Address to listen on for a TCP stream.ListenDatagram: Address to listen on for a UDP datagram.ListenSequentialPacket: Address to listen on for a Unix socket stream.ListenFIFO: Filesystem FIFO to listen on.Accept: Ifyes, a service instance is spawned for each connection; ifno, all sockets are passed to the service unit.SocketUser: Unix username for the socket (default:root).SocketGroup: Unix group name for the socket (default:root).SocketMode: Filesystem permissions for the socket (default:0666).Service: Name of the connected service (if different from the socket name).
1.4.5. [Mount] Section Directives (Applies to mount units)
Section titled “1.4.5. [Mount] Section Directives (Applies to mount units)”What: Path to mount.Where: Mountpoint path.Type: Filesystem type.Options: Comma-separated mount options.SloppyOptions: Boolean; iftrue, unrecognized mount options are ignored.DirectoryMode: Permissions for parent directories of the mountpoint.TimeoutSec: Time to wait before marking the operation as failed.
1.4.6. [Automount] Section Directives (Applies to automount units)
Section titled “1.4.6. [Automount] Section Directives (Applies to automount units)”Where: Mountpoint path.DirectoryMode: Permissions for parent directories.
1.4.7. [Swap] Section Directives (Applies to swap units)
Section titled “1.4.7. [Swap] Section Directives (Applies to swap units)”What: Path to the swap file or device.Priority: Swap priority (integer).Options: Comma-separated options for/etc/fstab.TimeoutSec: Time to wait before marking the operation as failed.
1.4.8. [Path] Section Directives (Applies to path units)
Section titled “1.4.8. [Path] Section Directives (Applies to path units)”PathExists: Activates the associated unit if the path exists.PathExistsGlob: Similar toPathExistsbut supports glob patterns.PathChanged: Activates the unit when the file at the path is saved and closed.PathModified: Similar toPathChangedbut also triggers on file modifications.DirectoryNotEmpty: Activates the unit if the specified directory is not empty.Unit: Name of the connected unit (if different from the path name).MakeDirectory: Iftrue, creates directories before watching.DirectoryMode: Permissions for created directories (default:0755).
1.4.9. [Timer] Section Directives (Applies to timer units)
Section titled “1.4.9. [Timer] Section Directives (Applies to timer units)”OnActiveSec: Activates the associated unit after this duration from timer activation.OnBootSec: Activates the unit after this duration from boot.OnStartupSec: Activates the unit after this duration from systemd startup.OnUnitActiveSec: Activates the unit after this duration from the last activation.OnUnitInactiveSec: Activates the unit after this duration from the last inactivation.OnCalendar: Absolute time to activate the unit.AccuracySec: Timer accuracy level.Unit: Name of the associated unit (if different from the timer name).Persistent: Iftrue, stores the last trigger time on disk; triggers immediately if missed while inactive.
2. Targets
Section titled “2. Targets”2.1. Definition and List
Section titled “2.1. Definition and List”Targets are similar to SysV init runlevels. Their purpose is to group other systemd units through chains of dependencies.
A fresh Debian 13 server installation includes the following targets:
systemctl list-unit-files --type=targetUNIT FILE STATE PRESETbasic.target static -blockdev@.target static -bluetooth.target static -boot-complete.target static -ctrl-alt-del.target alias -default.target alias -emergency.target static -exit.target disabled disabledfactory-reset.target static -final.target static -first-boot-complete.target static -getty-pre.target static -getty.target static -graphical.target static -halt.target disabled disabledhibernate.target static -hybrid-sleep.target static -initrd-fs.target static -initrd-root-device.target static -initrd-root-fs.target static -initrd-switch-root.target static -initrd-usr-fs.target static -initrd.target static -kexec.target disabled disabledlocal-fs-pre.target static -local-fs.target static -multi-user.target static -network-online.target static -network-pre.target static -network.target static -nss-lookup.target static -nss-user-lookup.target static -paths.target static -poweroff.target disabled disabledprinter.target static -reboot.target disabled enabledremote-fs-pre.target static -remote-fs.target enabled enabledrescue-ssh.target static -rescue.target static -rpcbind.target static -runlevel0.target alias -runlevel1.target alias -runlevel2.target alias -runlevel3.target alias -runlevel4.target alias -runlevel5.target alias -runlevel6.target alias -shutdown.target static -sigpwr.target static -sleep.target static -slices.target static -smartcard.target static -sockets.target static -soft-reboot.target static -sound.target static -ssh-access.target static -storage-target-mode.target static -suspend-then-hibernate.target static -suspend.target static -swap.target static -sysinit.target static -system-update-pre.target static -system-update.target static -time-set.target static -time-sync.target static -timers.target static -tpm2.target static -sigpwr.target static -sleep.target static -slices.target static -smartcard.target static -sockets.target static -soft-reboot.target static -sound.target static -ssh-access.target static -storage-target-mode.target static -suspend-then-hibernate.target static -suspend.target static -swap.target static -sysinit.target static -system-update-pre.target static -system-update.target static -time-set.target static -time-sync.target static -timers.target static -tpm2.target static -umount.target static -usb-gadget.target static -Target configuration files are located in /lib/systemd/system/.
2.2. Example Target Files
Section titled “2.2. Example Target Files”network.target:
[Unit]Description=NetworkDocumentation=man:systemd.special(7)Documentation=https://systemd.io/NETWORK_ONLINEAfter=network-pre.targetRefuseManualStart=yesmulti-user.target:
[Unit]Description=Multi-User SystemDocumentation=man:systemd.special(7)Requires=basic.targetConflicts=rescue.service rescue.targetAfter=basic.target rescue.service rescue.targetAllowIsolate=yesgraphical.target:
[Unit]Description=Graphical InterfaceDocumentation=man:systemd.special(7)Requires=multi-user.targetWants=display-manager.serviceConflicts=rescue.service rescue.targetAfter=multi-user.target rescue.service rescue.target display-manager.serviceAllowIsolate=yes3. Unit Management: systemctl Command
Section titled “3. Unit Management: systemctl Command”Start a service:
sudo systemctl start apache2.serviceStop a service:
sudo systemctl stop apache2.serviceReload a service (reloads configuration without restarting):
sudo systemctl reload apache2.serviceRestart a service:
sudo systemctl restart apache2.serviceReload if possible, otherwise restart:
sudo systemctl reload-or-restart apache2.serviceEnable a service (starts automatically at boot):
sudo systemctl enable apache2.serviceDisable a service (does not start at boot):
sudo systemctl disable apache2.serviceShow status of a service:
sudo systemctl status apache2.serviceCheck if a service is active:
systemctl is-active apache2.serviceCheck if a service is enabled:
systemctl is-enabled apache2.serviceCheck if a service has failed:
systemctl is-failed apache2.serviceMask a service (prevents it from being started, even manually):
sudo systemctl mask apache2.serviceUnmask a service:
sudo systemctl unmask apache2.serviceList all active units:
sudo systemctl list-unitsList all units (including loaded and attempted):
sudo systemctl list-units --allList all installed unit files:
sudo systemctl list-unit-filesList services only:
systemctl list-units --type=serviceView the contents of a unit file:
systemctl cat apache2.serviceView dependencies of a unit:
systemctl list-dependencies apache2.serviceView dependencies recursively:
systemctl list-dependencies apache2.service --allView low-level details of a unit:
systemctl show apache2.serviceCreate an override or modify settings (creates/edit a drop-in file):
sudo systemctl edit apache2.serviceEdit the entire unit file:
sudo systemctl edit --full apache2.serviceReload systemd (after modifying unit files):
sudo systemctl daemon-reloadShow the default target (equivalent to runlevel):
systemctl get-defaultSet the default target:
sudo systemctl set-default graphical.targetsudo systemctl set-default multi-user.targetList available targets:
systemctl list-unit-files --type=targetList units associated with a target:
systemctl list-dependencies multi-user.targetPower off and reboot the system:
sudo systemctl poweroffsudo systemctl rebootBoot into rescue mode:
sudo systemctl rescueHalt the system (does not power off the machine):
sudo systemctl haltControl systemd on a remote system:
systemctl --host user_name@host_name command4. Log Management: journalctl Command
Section titled “4. Log Management: journalctl Command”View all log entries:
journalctlView all log entries for the current boot:
journalctl -bView only kernel entries:
journalctl -kView only kernel entries for the current boot:
journalctl -k -bView log entries for a specific unit (e.g., Apache):
journalctl -u apache2.serviceView unit logs for the current boot:
journalctl -b -u apache2.serviceView logs from the previous boot:
journalctl -b -1View the list of the boots boots:
journalctl --list-bootsView logs within a time interval:
journalctl --since "2023-01-10 17:15:00"journalctl --since "2023-01-10" --until "2023-01-11 03:00"journalctl --since yesterdayjournalctl --since 09:00 --until "1 hour ago"journalctl -u apache2.service --since todayView log entries for a specific executable:
journalctl /usr/bin/bashOutput logs in JSON format:
journalctl -b -u apache2 -o jsonjournalctl -b -u apache2 -o json-prettyShow the most recent 10 entries:
journalctl -nShow the most recent 20 entries:
journalctl -n 20Follow logs in real-time (similar to tail -f; press Ctrl+C to exit):
journalctl -fShow disk usage of journal logs:
journalctl --disk-usageDelete old logs to reduce size to a specified limit:
sudo journalctl --vacuum-size=1GDelete logs older than a specified time:
sudo journalctl --vacuum-time=1years5. Other systemd Components
Section titled “5. Other systemd Components”systemd includes several additional components. Some notable ones are:
-
systemd-boot: A UEFI boot manager with basic configuration support. Integrates with
systemctland includes thebootctlcommand. -
systemd-cat: Adds records to the systemd journal via a pipeline.
echo "Test" | systemd-cat -p info -
systemd-localed: Manages system locale settings. Controlled via the
localectlcommand. -
systemd-logind: Manages user logins, tracks users and sessions, and handles device access for users.
-
systemd-machined: Detects and monitors virtual machines and containers. Includes the
machinectlcommand. -
systemd-mount: Manages
.mountand.automountunits. -
systemd-networkd: Handles network configuration. Configuration files are located in (in order of precedence):
/lib/systemd/network/run/systemd/network/etc/systemd/network
-
systemd-nspawn: Runs commands or operating systems in lightweight namespace containers, similar to
chrootin many respects. -
systemd-resolved: Provides network name resolution. Includes the
resolvectlcommand. -
systemd-sysusers: Creates system users and groups.
-
systemd-timesyncd: Synchronizes system time over the network with NTP servers. Includes the
timedatectlcommand. -
systemd-tmpfiles: Manages volatile and temporary files and directories (creates, deletes, cleans up).
-
systemd-udevd: Manages physical devices.
6. Creating a Custom Service
Section titled “6. Creating a Custom Service”We will create a simple custom service that pings an IP address every 10 minutes. It logs an informational message if the ping succeeds, and an error message if it fails.
The service consists of a shell script placed in /usr/local/bin, a systemd unit file, and will be enabled, started, and tested.
6.1. Create the Shell Script
Section titled “6.1. Create the Shell Script”Create a script named ipcheck.sh:
nano ipcheck.shAdd the following content:
#!/bin/bashecho "ipcheck.service: Start. $(date)" | systemd-cat -p infowhile true ; do ping -q -w 1 192.168.1.1 > /dev/null if [ $? = 0 ] ; then echo "ipcheck.service: Ping to IP is OK. $(date)" | systemd-cat -p info else echo "ipcheck.service: Error cannot ping IP. $(date)" | systemd-cat -p err fi sleep 600done6.2. Copy the Script to /usr/local/bin
Section titled “6.2. Copy the Script to /usr/local/bin”Make the script executable and copy it:
chmod +x ipcheck.shsudo cp ipcheck.sh /usr/local/bin6.3. Create the Unit File
Section titled “6.3. Create the Unit File”Use systemctl edit to create the service unit:
sudo systemctl edit --force --full ipcheck.serviceThis command opens an editor. Add the following configuration:
[Unit]Description=IPCheck Demo ServiceWants=network.targetAfter=syslog.target network-online.target
[Service]ExecStart=/usr/local/bin/ipcheck.shRestart=on-failureRestartSec=20KillMode=process
[Install]WantedBy=multi-user.targetSave and exit the editor.
6.4. Enable and Start The Service
Section titled “6.4. Enable and Start The Service”sudo systemctl enable ipcheck.servicesudo systemctl start ipcheck.service6.5. Test the Service
Section titled “6.5. Test the Service”Check the recent logs to verify the service is working:
sudo journalctl -n 20