LUNAROPS · OPERATIONAL UPLINK 100% UPTIME 1,247d POSTS 893 JEFF.MOON@LUNAROPS.DEV UTC --:--:--

Systemd: Managing Services and the Init System

linuxsystemdservicesinitadministration

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

1
systemctl status nginx

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