Systemd is the init system and service manager on most modern Linux distributions. It manages the boot process and system services.
Systemd Basics
What Systemd Manages
- Services: Daemons and background processes
- Mounts: Filesystem mounting
- Devices: Hardware devices
- Sockets: Network and IPC sockets
- Timers: Scheduled tasks (cron replacement)
- Targets: Groups of units (like runlevels)
Unit Files
Systemd uses “unit files” to define how to manage resources. Located in:
| Path |
Purpose |
/lib/systemd/system/ |
Distribution-provided |
/etc/systemd/system/ |
Administrator overrides |
~/.config/systemd/user/ |
User services |
Managing Services
systemctl Basics
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
# Start service
sudo systemctl start nginx
# Stop service
sudo systemctl stop nginx
# Restart service
sudo systemctl restart nginx
# Reload configuration (no downtime)
sudo systemctl reload nginx
# Check status
systemctl status nginx
# Enable at boot
sudo systemctl enable nginx
# Disable at boot
sudo systemctl disable nginx
# Enable and start
sudo systemctl enable --now nginx
|
Service Status
Output explained:
● nginx.service - A high performance web server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2026-01-04 10:00:00 UTC; 2h ago
Process: 1234 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)
Main PID: 1235 (nginx)
Tasks: 2 (limit: 4915)
Memory: 3.5M
CPU: 123ms
CGroup: /system.slice/nginx.service
├─1235 nginx: master process /usr/sbin/nginx
└─1236 nginx: worker process
Listing Services
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
# All loaded units
systemctl list-units
# All service units
systemctl list-units --type=service
# Failed units
systemctl --failed
# All installed unit files
systemctl list-unit-files
# Enabled services
systemctl list-unit-files --state=enabled
|
Creating Service Files
Basic Service Structure
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
# /etc/systemd/system/myapp.service
[Unit]
Description=My Application
After=network.target
[Service]
Type=simple
User=myapp
Group=myapp
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/bin/start.sh
ExecStop=/opt/myapp/bin/stop.sh
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
|
Sections Explained
[Unit]
Description: Human-readable description
After: Start after these units
Before: Start before these units
Requires: Hard dependencies
Wants: Soft dependencies
[Service]
Type: simple, forking, oneshot, notify, dbus
User/Group: Run as this user
WorkingDirectory: Working directory
ExecStart: Command to start
ExecStop: Command to stop
ExecReload: Command to reload
Restart: always, on-failure, on-abnormal
RestartSec: Delay before restart
Environment: Set environment variables
EnvironmentFile: Load from file
[Install]
WantedBy: Target to enable under
Service Types
| Type |
Description |
simple |
Process started is the main process |
forking |
Process forks, parent exits |
oneshot |
Process exits after completion |
notify |
Like simple, but notifies when ready |
dbus |
Acquires D-Bus name when ready |
Example: Node.js Application
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
[Unit]
Description=Node.js Application
After=network.target
[Service]
Type=simple
User=node
WorkingDirectory=/var/www/app
ExecStart=/usr/bin/node /var/www/app/index.js
Restart=on-failure
RestartSec=10
StandardOutput=journal
StandardError=journal
Environment=NODE_ENV=production
Environment=PORT=3000
[Install]
WantedBy=multi-user.target
|
Example: Python Application with Virtual Environment
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
[Unit]
Description=Python Application
After=network.target
[Service]
Type=simple
User=appuser
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/venv/bin/python /opt/myapp/app.py
Restart=always
RestartSec=5
EnvironmentFile=/opt/myapp/.env
[Install]
WantedBy=multi-user.target
|
After Creating/Modifying
1
2
3
4
5
6
7
8
|
# Reload systemd to see new units
sudo systemctl daemon-reload
# Enable and start
sudo systemctl enable --now myapp
# Check status
systemctl status myapp
|
Viewing Logs
Systemd uses journald for logging.
journalctl Basics
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
# All logs
journalctl
# For specific unit
journalctl -u nginx
# Follow logs (like tail -f)
journalctl -u nginx -f
# Since boot
journalctl -b
# Last 100 lines
journalctl -u nginx -n 100
# Since time
journalctl --since "1 hour ago"
journalctl --since "2026-01-04 10:00:00"
# Priority (error and above)
journalctl -p err
# Kernel messages
journalctl -k
# JSON output
journalctl -u nginx -o json-pretty
|
Log Priorities
| Priority |
Keyword |
| 0 |
emerg |
| 1 |
alert |
| 2 |
crit |
| 3 |
err |
| 4 |
warning |
| 5 |
notice |
| 6 |
info |
| 7 |
debug |
Targets (Runlevels)
Targets group units together.
Common Targets
| Target |
Equivalent |
Description |
| poweroff.target |
0 |
Halt system |
| rescue.target |
1 |
Single-user mode |
| multi-user.target |
3 |
Multi-user, no GUI |
| graphical.target |
5 |
Multi-user with GUI |
| reboot.target |
6 |
Reboot |
Managing Targets
1
2
3
4
5
6
7
8
|
# Check current target
systemctl get-default
# Set default target
sudo systemctl set-default multi-user.target
# Switch target
sudo systemctl isolate multi-user.target
|
Timers (Cron Replacement)
Timer Unit
1
2
3
4
5
6
7
8
9
10
11
|
# /etc/systemd/system/backup.timer
[Unit]
Description=Run backup daily
[Timer]
OnCalendar=daily
# Or: OnCalendar=*-*-* 02:00:00
Persistent=true
[Install]
WantedBy=timers.target
|
Service Unit (same name)
1
2
3
4
5
6
7
|
# /etc/systemd/system/backup.service
[Unit]
Description=Backup Service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
|
Timer Commands
1
2
3
4
5
6
7
8
|
# Enable timer
sudo systemctl enable --now backup.timer
# List timers
systemctl list-timers
# Check timer status
systemctl status backup.timer
|
OnCalendar Syntax
# Daily at midnight
OnCalendar=daily
# Every Monday at 3am
OnCalendar=Mon *-*-* 03:00:00
# Every 15 minutes
OnCalendar=*:0/15
# Hourly
OnCalendar=hourly
# Every 6 hours
OnCalendar=0/6:00:00
Overriding Units
Drop-in Files
Override without editing original:
1
2
3
|
# Create override directory
sudo systemctl edit nginx
# Opens editor for /etc/systemd/system/nginx.service.d/override.conf
|
1
2
3
|
# Override specific settings
[Service]
MemoryLimit=512M
|
Full Override
1
2
3
|
# Copy and modify
sudo cp /lib/systemd/system/nginx.service /etc/systemd/system/
sudo vim /etc/systemd/system/nginx.service
|
Analysis and Debugging
1
2
3
4
5
6
7
8
9
10
11
12
13
|
# Boot time analysis
systemd-analyze
systemd-analyze blame
systemd-analyze critical-chain
# Check unit file syntax
systemd-analyze verify /etc/systemd/system/myapp.service
# Show unit dependencies
systemctl list-dependencies nginx
# Show what depends on a unit
systemctl list-dependencies --reverse nginx
|
Quick Reference
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
# Service management
systemctl start|stop|restart|reload SERVICE
systemctl enable|disable SERVICE
systemctl status SERVICE
# Listing
systemctl list-units --type=service
systemctl --failed
# Logs
journalctl -u SERVICE -f
journalctl --since "1 hour ago"
# Unit files
sudo systemctl daemon-reload # After changes
systemctl cat SERVICE # View unit file
sudo systemctl edit SERVICE # Override
# Timers
systemctl list-timers
|
Systemd is powerful and ubiquitous. Master it to effectively manage modern Linux systems.
Comments