ITcompressor IT — compressed and to the point
← Back to articles

Systemd

systemd is the init and service management system on Linux that displaced the traditional init in the 2010s. Its key feature is starting services in parallel during boot, so the system starts noticeably faster.

All the examples below revolve around a single service myapp — how to create your own is shown in the "Creating a service" section.

Basic concepts#

  • Unit — the base management unit of systemd: a configuration file describing a resource (a service, socket, device, mount point)
  • Service — a unit type for daemons and processes (*.service)
  • Target — a group of units activated together; the successor of the runlevel of traditional init
  • cgroup (control group) — a kernel mechanism: it groups processes for accounting and resource limits; systemd uses cgroups to track the processes of each service

The runlevel-to-target mapping:

Runlevel Target What it is
0 poweroff.target shutdown
1 rescue.target single-user mode (recovery)
3 multi-user.target multi-user without graphics (servers)
5 graphical.target multi-user with graphics
6 reboot.target reboot

Managing a service#

# Start
systemctl start myapp

# Stop
systemctl stop myapp

# Restart (stop + start)
systemctl restart myapp

# Reload the service config without a restart
systemctl reload myapp

# Check the status: state, process tree, fresh log lines
systemctl status myapp

The .service suffix is optional: systemctl start myapp and systemctl start myapp.service are the same thing. This article omits it.

Startup#

# Enable autostart and start the service right away
systemctl enable --now myapp

# Enable autostart only
systemctl enable myapp

# Remove from autostart
systemctl disable myapp

# Block completely (mask: it won't start even manually)
systemctl mask myapp

# Undo
systemctl unmask myapp

enable does not start the service itself — it starts on the next boot. To enable autostart and bring the service up right away — enable --now.

Creating a service#

The unit file goes into /etc/systemd/system/ — here it is myapp.service:

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

[Service]
Type=simple
User=myuser
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/bin/myapp
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

Choosing Type= for the process behaviour:

Type When to use
simple the process runs in the foreground and does not daemonize itself (the default)
forking the process backgrounds itself in the classic Unix-daemon style
oneshot a one-off task: runs and exits
notify like simple, but the process reports readiness itself via sd_notify

Restart=on-failure restarts the service only on crash; always — also after a normal exit.

Accepted into service:

# Re-read units after changing files
sudo systemctl daemon-reload

# Enable autostart and start
sudo systemctl enable --now myapp

Working with targets#

# List available targets
systemctl list-units --type=target

# A target's dependency tree
systemctl list-dependencies graphical.target

# Switch the current session to no-graphics mode
sudo systemctl isolate multi-user.target

isolate stops everything that is not in the target target and its dependencies — including running graphical applications when leaving graphical.target.

The default target for future boots:

# Which target will be activated at boot
systemctl get-default

# Make the graphical mode the default
sudo systemctl set-default graphical.target

Reboot and shutdown#

# Reboot the system
systemctl reboot

# Shut down
systemctl poweroff

Both commands are thin wrappers over the corresponding targets (reboot.target, poweroff.target).

Service logs (journalctl)#

# All service logs
journalctl -u myapp

# Since the last system boot
journalctl -u myapp -b

# The last 100 lines, without a pager
journalctl -u myapp -n 100 --no-pager

# In real time
journalctl -u myapp -f

# Over a time interval
journalctl -u myapp --since "2026-06-30 10:00" --until "2026-06-30 12:00"

For existing services it is handy to view their unit with drop-ins: systemctl cat myapp, and edit it with sudo systemctl edit myapp.

← Back to articles