↑
Introduction to systemd
- What Is systemd?
systemd is the modern init system used by most Linux distributions (Fedora, Ubuntu, Debian, openSUSE, Arch, etc.).
- It is the first process started at boot (PID 1) and is responsible for:
- booting and shutting down the system,
- starting services,
- managing daemons,
- handling logs and timers.
- It replaces the older SysV init (
/etc/init.d/*) with a faster and more reliable parallel boot model.
- Systemd’s Core Concepts
- Units: the building blocks systemd manages. Types include:
.service — background daemons
.timer — scheduled tasks
.target — logical groups (similar to runlevels)
.mount — mount points
.socket — socket activation units
- Systemctl: the command-line tool you use to interact with systemd.
- Most Common systemctl Commands
- Start / Stop / Restart a service:
sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginx
- Enable or disable at boot:
sudo systemctl enable nginx
sudo systemctl disable nginx
systemctl status nginx
- View logs (via systemd-journald):
journalctl -u nginx
- A Minimal systemd Service Example
- Create a file:
/etc/systemd/system/myapp.service
[Unit]
Description=My Sample App
[Service]
ExecStart=/usr/bin/python3 /opt/myapp/app.py
Restart=always
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl start myapp
sudo systemctl enable myapp
Viewing Information in systemd
- Overview
systemd provides powerful tools to inspect:
- service status,
- logs,
- unit dependencies,
- boot performance,
- failed units,
- target states.
- Check the Status of a Service
systemctl status nginx
- Shows:
- active/inactive status,
- PID, memory, uptime,
- recent log lines,
- unit file path.
- List All Units
- Show every unit systemd knows about:
systemctl list-units
- Show all units including inactive ones:
systemctl list-units --all
- List All Services Only
- Filter only
.service units:
systemctl list-units --type=service
- You can also list:
--type=socket
--type=timer
--type=mount
--type=target
- List Failed Units
- To quickly see what crashed:
systemctl --failed
- Useful after boot or troubleshooting.
- View Logs of a Service
journalctl -u nginx
- Follow logs live (similar to
tail -f):
journalctl -u nginx -f
journalctl -u nginx --since today
- View logs since last boot:
journalctl -u nginx -b
- View System-Wide Logs
- All logs managed by
systemd-journald:
journalctl
journalctl -p warning
journalctl -p err
journalctl -p crit
journalctl --since "2024-01-01" --until "2024-01-02"
- Inspect Unit Configuration Files
- See the exact unit file systemd is using:
systemctl cat nginx.service
- List all property fields of a unit:
systemctl show nginx
- This reveals:
- Runtime paths
- CGroup config
- Environment variables
- Restart settings
- Unit metadata
- View Dependencies and Boot Order
- To understand dependencies around a service:
systemctl list-dependencies sshd
- Display reverse dependencies (what depends on this unit):
systemctl list-dependencies --reverse sshd
- Graphical view (ASCII tree):
systemctl list-dependencies --all
- Check Boot Time and Performance
- Use
systemd-analyze to inspect boot performance:
systemd-analyze
systemd-analyze blame
- View dependency graph (export as image):
systemd-analyze plot > boot.svg
- Check Current System Target (Runlevel)
- To see what systemd target (similar to old runlevel) is active:
systemctl get-default
- Examples:
graphical.target
multi-user.target
Working with Services in systemd
- Overview
- Services in
systemd are defined by .service unit files.
- They represent background processes or daemons such as:
- sshd
- nginx
- docker
- cron
- your own apps
- This chapter focuses on how to start, stop, enable, restart, and inspect systemd services.
- Starting and Stopping Services
- To immediately start a service:
sudo systemctl start nginx
- To stop a running service:
sudo systemctl stop nginx
- Restart a service (loads new config):
sudo systemctl restart nginx
- Reload configuration without restarting the entire service:
sudo systemctl reload nginx
- Enabling and Disabling Services at Boot
- Enable a service so it starts automatically at boot:
sudo systemctl enable nginx
sudo systemctl disable nginx
- Check if a service is enabled:
systemctl is-enabled nginx
- Checking Service Status
systemctl status nginx
- Displays:
- active / inactive / failed state
- process ID, CPU, memory
- recent logs
- unit file info
- Viewing Logs of a Service
- Logs are collected by
systemd-journald and viewed via journalctl:
journalctl -u nginx
- Follow logs in real time:
journalctl -u nginx -f
journalctl -u nginx -b
- Reloading systemd After Creating or Editing Unit Files
- After editing files in
/etc/systemd/system/ or creating new services, you must reload systemd:
sudo systemctl daemon-reload
- This updates systemd’s internal unit registry.
- Then restart or start the updated service:
sudo systemctl restart myapp.service
- Masking and Unmasking Services
- Mask a service to prevent it from starting even manually:
sudo systemctl mask nginx
sudo systemctl unmask nginx
- This is stronger than
disable and is used to stop dangerous or conflicting services.
- Viewing All Services
- List only services (not timers, sockets, etc.):
systemctl list-units --type=service
- Show services including inactive ones:
systemctl list-unit-files --type=service
- This shows installed service files regardless of running state.
- Autorestart and Service Recovery
- Services can be configured to restart automatically on crash.
- Inside a
.service file:
[Service]
Restart=on-failure
RestartSec=5
- Useful for long-running daemons or servers.
- Environments and Working Directory
- You can set environment variables:
[Service]
Environment="APP_ENV=production"
WorkingDirectory=/opt/myapp
ExecStart=/usr/bin/python3 app.py
- Or load them from a file:
EnvironmentFile=/etc/myapp/env.conf
- This is commonly used for secrets and configs.
Changing System States in systemd
- Overview
systemd manages the entire system state using targets.
- Targets replace the old SysV “runlevels”.
- Each target represents a specific operating mode such as:
- graphical UI
- multi-user server mode
- rescue mode
- shutdown / reboot
- Common systemd Targets
- The most frequently used systemd targets:
poweroff.target → Shut down the system
reboot.target → Restart the system
multi-user.target → Multi-user text mode (server mode)
graphical.target → GUI login mode
rescue.target → Single-user maintenance mode
emergency.target → Very minimal recovery shell
default.target → The system’s default boot mode
- These targets group services together to define what runs in each state.
- Check the Current System State
- To see what the system boots into by default:
systemctl get-default
graphical.target
multi-user.target
- Switching System States (Temporarily)
- You can change the current target without altering the boot default.
- Switch to multi-user (non-GUI) mode:
sudo systemctl isolate multi-user.target
- Switch to graphical mode (start GUI):
sudo systemctl isolate graphical.target
- Note:
isolate stops units not required by the new target.
- Changing the Default Boot Target
- To permanently change what the system boots into:
sudo systemctl set-default multi-user.target
sudo systemctl set-default graphical.target
- This creates a symlink for
/etc/systemd/system/default.target.
- Does not restart the system — only affects the next boot.
- Rebooting, Powering Off, and Suspending
- systemd provides direct system state-changing commands:
sudo systemctl reboot # Restart system
sudo systemctl poweroff # Shut down
sudo systemctl halt # Halt CPU (stop)
sudo systemctl suspend # Sleep mode
sudo systemctl hibernate # Hibernate
- These replace older commands like
shutdown -r now and halt.
- Recovery States (Rescue / Emergency)
- If something goes wrong, systemd provides minimal recovery targets.
- Rescue mode — basic system with root shell:
sudo systemctl rescue
- Emergency mode — minimal environment, no services, direct root shell:
sudo systemctl emergency
- Useful for repairing corrupted filesystems or broken configurations.
- Showing a Target’s Dependencies
- You can inspect which units a target pulls in:
systemctl list-dependencies graphical.target
- This shows the entire boot chain visually (ASCII tree).
Creating Custom Services in systemd
- Overview
- You can use
systemd to run your own scripts, servers, background jobs, or applications as managed services.
- Custom services:
- start automatically at boot,
- restart on failure,
- run in a clean environment,
- log output via
journalctl.
- This chapter shows how to create, install, and manage a fully custom
.service file.
- Where to Put Custom Service Files
- System-level services (global):
/etc/systemd/system/myapp.service
- User-level services (no root required):
~/.config/systemd/user/myapp.service
- System-level services run regardless of logged-in users.
- User-level services require
systemctl --user.
- Minimal Custom Service Example
- A simple service that runs a Python script:
[Unit]
Description=My Python App
[Service]
ExecStart=/usr/bin/python3 /opt/myapp/app.py
[Install]
WantedBy=multi-user.target
/etc/systemd/system/myapp.service
sudo systemctl daemon-reload
sudo systemctl enable myapp
sudo systemctl start myapp
- Using Working Directory and Environment Variables
- Many applications require a specific working directory or configuration values.
[Unit]
Description=Node.js Backend
[Service]
WorkingDirectory=/opt/backend
ExecStart=/usr/bin/node server.js
Environment="NODE_ENV=production"
Environment="API_KEY=12345"
[Install]
WantedBy=multi-user.target
- Environment variables can also come from a file:
EnvironmentFile=/etc/backend/env.conf
- Great for secrets (although better to use secret management solutions in production).
- Restart Policies
- To ensure your service recovers automatically:
[Service]
Restart=on-failure
RestartSec=3
- Common Restart options:
no — never restart
on-failure — restart on non-zero exit
always — always restart
on-abnormal
- Running Services as a Dedicated User
- Run your app under a restricted user for security:
[Service]
User=myapp
Group=myapp
ExecStart=/usr/bin/myapp
- Create the user if it doesn’t exist:
sudo useradd --system --no-create-home myapp
- Capturing Logs (journalctl)
- All output from your app (stdout + stderr) goes into systemd’s journal automatically.
journalctl -u myapp -f
- Log options can be customized:
StandardOutput=journal
StandardError=journal
- Creating Services That Wait for Other Units
- Use
After= and Requires=:
[Unit]
Description=Backend App
After=network.target
Requires=network.target
After controls ordering only.
Requires ensures the dependency must be started.
- Running a Script as a Service
#!/bin/bash
echo "Hello from my service!"
sleep 60
- Make it executable and place a service file:
[Unit]
Description=My Script Service
[Service]
ExecStart=/usr/local/bin/myscript.sh
[Install]
WantedBy=multi-user.target
- Reloading and Updating Services
- After changing any
.service file:
sudo systemctl daemon-reload
sudo systemctl restart myapp
- daemon-reload is required to make systemd notice changes.
- Disabling, Masking, and Removing
sudo systemctl disable myapp
- Stop permanently (block all starts):
sudo systemctl mask myapp
sudo rm /etc/systemd/system/myapp.service
sudo systemctl daemon-reload