Systemd: Managing Services on Linux
Systemd is the init system and service manager used by virtually every modern Linux distribution — responsible for booting the system, managing services, handling logging, and orchestrating the entire lifecycle of processes from power-on to shutdown.
What You’ll Learn
- Managing services with systemctl: start, stop, enable, disable, status
- Creating custom service units for your applications
- Viewing logs with journalctl
- Using timers as a modern replacement for cron
- Understanding targets (runlevels)
- Troubleshooting failed services
Why Systemd Matters
Systemd is the foundation of modern Linux administration. Every service on a Linux system — from SSH and Docker to your custom application — is managed by systemd. Understanding systemd means you can deploy, monitor, and troubleshoot services confidently.
Durga Antivirus Pro runs as a systemd service with automatic restart on failure, logging to journald, and a hardened service configuration.
Learning Path
flowchart LR
A[Linux Basics] --> B[Process Management]
B --> C[Systemd Services<br/>You are here]
C --> D[Service Units]
D --> E[Timers & Targets]
style C fill:#f90,color:#fff
Systemctl Basics
# Service management
sudo systemctl start nginx # Start a service
sudo systemctl stop nginx # Stop a service
sudo systemctl restart nginx # Restart a service
sudo systemctl reload nginx # Reload config without restarting
sudo systemctl status nginx # Show detailed status
# Enable/disable at boot
sudo systemctl enable nginx # Start on boot
sudo systemctl disable nginx # Don't start on boot
sudo systemctl is-enabled nginx # Check if enabled
sudo systemctl enable --now nginx # Enable and start in one commandExpected systemctl status nginx output:
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2026-06-19 10:30:00 UTC
Main PID: 12345 (nginx)
Tasks: 3 (limit: 1137)
Memory: 5.2M
CGroup: /system.slice/nginx.service
├─12345 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
└─12346 nginx: worker processCreating a Service Unit
Create a service file for your application:
# /etc/systemd/system/myapp.service
[Unit]
Description=My Application Service
After=network.target postgresql.service
Wants=postgresql.service
[Service]
Type=simple
User=myapp
Group=myapp
WorkingDirectory=/opt/myapp
Environment=NODE_ENV=production
EnvironmentFile=-/etc/myapp/env.conf
ExecStart=/usr/bin/node /opt/myapp/server.js
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal
LimitNOFILE=65536
[Install]
WantedBy=multi-user.targetKey Directives Explained
| Directive | Purpose |
|---|---|
After= | Ordering — start after these units |
Wants= | Weak dependency (not required) |
Requires= | Strong dependency (unit fails if dependency fails) |
Type=simple | Default — process forks once |
Type=forking | Process forks (daemonizes) — wait for PID file |
Type=oneshot | Runs once and exits (for scripts) |
User=/Group= | Run as a specific user (security best practice) |
Restart=on-failure | Auto-restart on crash |
RestartSec=5 | Wait 5 seconds before restart |
LimitNOFILE= | Max open file descriptors |
Enable and Start
sudo systemctl daemon-reload # Reload unit files
sudo systemctl enable myapp # Enable at boot
sudo systemctl start myapp # Start now
sudo systemctl status myapp # Verify it's runningJournalctl (Logging)
Systemd collects all service logs via journald:
# View logs for a specific service
sudo journalctl -u myapp
# Follow logs in real time (like tail -f)
sudo journalctl -u myapp -f
# Last 50 lines
sudo journalctl -u myapp -n 50
# Logs for a specific time range
sudo journalctl -u myapp --since "1 hour ago"
sudo journalctl -u myapp --since "2026-06-19" --until "2026-06-20"
# Show only errors
sudo journalctl -u myapp -p err
# Follow all services
sudo journalctl -f
# Show boot logs
sudo journalctl -b
# Show previous boot logs
sudo journalctl -b -1
# Limit output size
sudo journalctl -u myapp --no-pager -n 100
# Export logs to file
sudo journalctl -u myapp > /tmp/myapp.logExpected journalctl output:
Jun 19 10:30:01 server myapp[12345]: Server started on port 3000
Jun 19 10:30:01 server myapp[12345]: Connecting to database...
Jun 19 10:30:02 server myapp[12345]: Database connectedSystemd Timers
Timers are the systemd equivalent of cron, with better logging and dependency support:
# /etc/systemd/system/backup.service
[Unit]
Description=Daily backup service
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
User=backup# /etc/systemd/system/backup.timer
[Unit]
Description=Run backup daily at 2 AM
[Timer]
OnCalendar=daily
Persistent=true # Run if system was off during scheduled time
RandomizedDelaySec=300 # Random delay to avoid thundering herd
[Install]
WantedBy=timers.targetsudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
sudo systemctl list-timersExpected list-timers output:
NEXT LEFT LAST PASSED UNIT ACTIVATES
Fri 2026-06-20 02:00:00 15h Fri 2026-06-19 02:00:01 23h backup.timer backup.serviceTargets (Runlevels)
Targets group services into boot configurations:
| Target | Purpose | Old Runlevel |
|---|---|---|
poweroff.target | System shutdown | 0 |
rescue.target | Single-user mode | 1 |
multi-user.target | Multi-user, no GUI | 3 |
graphical.target | Multi-user with GUI | 5 |
reboot.target | Reboot | 6 |
# Check current target
systemctl get-default
# Change default (boot to CLI)
sudo systemctl set-default multi-user.target
# Switch to rescue mode
sudo systemctl rescue
# List all services in a target
systemctl list-dependencies multi-user.targetTroubleshooting Failed Services
# List failed services
systemctl --failed
# Check detailed status
sudo systemctl status failed-service
# View recent logs for a failed service
sudo journalctl -u failed-service -n 50 --no-pager
# Common checks:
# 1. Permission denied → check ExecStart path and User/Group
# 2. Port in use → check if another service is on the same port
# 3. Missing executable → verify binary exists
# 4. Environment variable not set → check Environment directives
# Reset a failed service
sudo systemctl reset-failed failed-serviceCommon Errors
1. Service Fails with “Permission Denied”
The User= in the service unit doesn’t have execute permission on the binary or script. Check ls -l /path/to/binary and sudo -u user /path/to/binary.
2. Service Starts but Immediately Stops
The ExecStart process exits. For services that should stay running, ensure the process doesn’t fork incorrectly. Check Type= matches your process behavior.
3. Port Already in Use
Check with sudo ss -tlnp | grep PORT. Stop the conflicting service or change your app’s port.
4. Environment Variables Not Set
EnvironmentFile=-/etc/myapp/env.conf (note the - prefix) — the - means “ignore if file doesn’t exist.” Double-check the path.
5. Service Not Starting at Boot
Run sudo systemctl enable myservice to create the symlink. Verify with systemctl is-enabled myservice.
6. Journalctl Shows No Logs
Ensure StandardOutput=journal and StandardError=journal are set in the service unit.
7. Service Hangs During Stop
Set TimeoutStopSec= in the service unit (default is 90 seconds). Add ExecStop= to send a proper shutdown signal.
Practice Questions
What command checks if a service is running?
sudo systemctl status servicenameWhat directive auto-restarts a service when it crashes?
Restart=on-failurein the[Service]section.How do you view real-time logs for a service?
sudo journalctl -u servicename -fWhat is the difference between
enableandstart?enableconfigures the service to start at boot.startstarts it immediately.What target should services use for non-GUI servers?
multi-user.target— it runs the system without a graphical interface.
Challenge: Create a systemd service for a Python/Node.js web application. Include: (1) a dedicated system user, (2) auto-restart on failure, (3) environment file for configuration, (4) logging to journald, (5) a timer for a companion cleanup script. Test the service starts, stops, restarts, and survives a crash.
FAQ
What’s Next
| Tutorial | What You’ll Learn |
|---|---|
| Cron Job Scheduling | Alternative task scheduling with cron |
| Linux Administration Basics | Foundational server management |
| Bash Scripting Guide | Writing scripts that run as systemd services |
Built by the developers of Doda Browser, DodaZIP, and Durga Antivirus Pro. Updated 2026-06-19.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro