systemd and Services
systemd is the init system on most modern Linux distributions. It manages everything that runs on your system — services, timers, mounts and more. Understanding it is not optional for serious Linux work.
Series: Learning Linux from Scratch
- 1. Learning Linux from Scratch — After a Full IT Apprenticeship
- 2. What is Linux?
- 3. The Filesystem
- 4. Users and Permissions
- 5. Installing and Managing Software
- 6. Text Editors
- 7. Shell Scripting Basics
- 8. Process Management
- 9. Networking Fundamentals
- 10. SSH
- 11. systemd and Services
- 12. Disk Management
- 13. Users and Groups — In Depth
- 14. Cron and Scheduled Tasks
- 15. Firewall — iptables and ufw
- 16. Environment Variables and the Shell
- 17. Log Management
- 18. Kernel Module Management
- 19. The /proc Filesystem — In Depth
- 20. The /sys Filesystem and udev
- 21. Kernel Parameters and sysctl
- 22. Compiling and Installing a Custom Kernel
systemd is the init system used by the vast majority of modern Linux distributions. It is the first process that starts when your system boots (PID 1) and it is responsible for starting, stopping, and managing everything else — services, mounts, timers, sockets, and more.
Understanding systemd is not optional for serious Linux work. It is how you control what runs on your system.
Units
Everything in systemd is a unit. Units are configuration files that describe something systemd should manage. The most common types are:
.service— a background service (nginx, sshd, postgresql).timer— a scheduled task (like cron but managed by systemd).mount— a filesystem mount point.socket— a network socket that activates a service on demand.target— a group of units (like a runlevel)
Unit files live in:
/lib/systemd/system/— units provided by packages/etc/systemd/system/— units you create or override
systemctl
systemctl is the main tool for interacting with systemd.
Starting and stopping services
sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginx
sudo systemctl reload nginx # reload config without full restartEnabling and disabling services
Starting a service only runs it now. Enabling it makes it start automatically on boot.
sudo systemctl enable nginx
sudo systemctl disable nginxEnable and start at the same time:
sudo systemctl enable --now nginxChecking service status
systemctl status nginxThis shows whether the service is running, its PID, recent log output, and whether it is enabled. It is usually the first thing to run when a service is misbehaving.
● nginx.service - A high performance web server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled)
Active: active (running) since Fri 2026-05-02 09:00:00 UTC; 3h ago
Process: 1234 ExecStartPre=/usr/sbin/nginx -t
Main PID: 1235 (nginx)
Listing all services
systemctl list-units --type=serviceFilter to only failed units:
systemctl list-units --state=failedWriting a service unit file
This is where systemd gets powerful. You can define your own services.
Create a file at /etc/systemd/system/myapp.service:
[Unit]
Description=My Application
After=network.target
[Service]
Type=simple
User=jan
WorkingDirectory=/home/jan/myapp
ExecStart=/home/jan/myapp/start.sh
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.targetBreaking this down:
After=network.target— do not start until the network is upType=simple— the process started by ExecStart is the main processUser=jan— run as this user, not rootRestart=on-failure— restart automatically if it crashesRestartSec=5— wait 5 seconds before restartingWantedBy=multi-user.target— start this service when the system reaches normal multi-user mode
After creating the file, reload systemd so it picks it up:
sudo systemctl daemon-reload
sudo systemctl enable --now myappjournalctl
systemd collects logs from all services into a central journal. journalctl is how you read it.
View all logs (most recent last):
journalctlFollow logs in real time (like tail -f):
journalctl -fLogs for a specific service:
journalctl -u nginxLogs since the last boot:
journalctl -bLogs from a specific time period:
journalctl --since "2026-05-01 09:00:00" --until "2026-05-01 10:00:00"Show only errors:
journalctl -p errPriority levels from lowest to highest: debug, info, notice, warning, err, crit, alert, emerg.
systemd timers
Timers are systemd's replacement for cron. They are more flexible and their logs go into the journal like any other service.
A timer requires two unit files — a .timer and a matching .service.
/etc/systemd/system/backup.service:
[Unit]
Description=Run backup script
[Service]
Type=oneshot
ExecStart=/home/jan/scripts/backup.sh
User=jan/etc/systemd/system/backup.timer:
[Unit]
Description=Run backup daily
[Timer]
OnCalendar=daily
Persistent=true
[Install]
WantedBy=timers.targetOnCalendar=daily runs at midnight. Persistent=true means if the system was off at midnight, run the job when it next starts.
Enable and start the timer:
sudo systemctl enable --now backup.timerList all active timers:
systemctl list-timerssystemd is comprehensive and the learning curve is real. But once you understand units, systemctl, and journalctl, you have a complete picture of what is running on your system, why, and what it is logging. That is a significant capability.
Next up: disk management — partitions, filesystems, mounting, and fstab.