Systemd — The Init System
Most modern Linux distributions use Systemd as their init system. It's the first process that starts after the kernel (PID 1) and manages all services, daemons, and system processes.
Systemd uses units — configuration files that describe services, sockets, devices, or mount points. The most common unit type is the service unit.
# Systemd is PID 1
$ ps -p 1 -o comm=
systemdsystemctl — The Primary Interface
Viewing Service Status
# Check if a service is running
$ systemctl status nginx
● nginx.service - A high performance web server and reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2026-04-10 09:05:00 UTC; 2h 15min ago
Docs: man:nginx(8)
Process: 1234 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
Main PID: 1256 (nginx)
Tasks: 5 (limit: 4915)
Memory: 5.2M
CPU: 245ms
CGroup: /system.slice/nginx.service
└─1256 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
├─1257 nginx: worker process
├─1258 nginx: worker process
└─1259 nginx: worker processStatus indicators:
| Indicator | Meaning |
|---|---|
● (green) | Service is active/running |
● (red) | Service failed |
● (white) | Service is inactive |
● (dim) | Service not found |
# Check if service is enabled (starts on boot)
$ systemctl is-enabled nginx
enabled
# Check if service is active (currently running)
$ systemctl is-active nginx
activeStarting and Stopping Services
# Start a service immediately
$ sudo systemctl start nginx
# Stop a running service
$ sudo systemctl stop nginx
# Restart a service (stop + start)
$ sudo systemctl restart nginx
# Reload configuration without interrupting connections
$ sudo systemctl reload nginx
# Reload or restart (restarts if reload isn't supported)
$ sudo systemctl reload-or-restart nginxWhen to use reload vs restart:
reload— Keep the service running, reload config files. Use for NGINX, Apache config changes.restart— Stop and start completely. Use when the binary itself changes.
Enabling and Disabling at Boot
# Enable service to start on boot
$ sudo systemctl enable nginx
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /lib/systemd/system/nginx.service.
# Disable service from starting on boot
$ sudo systemctl disable nginx
Removed /etc/systemd/system/multi-user.target.wants/nginx.service.
# Enable AND start immediately
$ sudo systemctl enable --now nginx
# Disable AND stop immediately
$ sudo systemctl disable --now nginxListing Services
# List all active services
$ systemctl list-units --type=service
UNIT LOAD ACTIVE SUB DESCRIPTION
nginx.service loaded active running A high performance web server
ssh.service loaded active running OpenSSH server daemon
docker.service loaded active running Docker Application Container
postgresql.service loaded active running PostgreSQL database server
# List only failed services
$ systemctl list-units --type=service --state=failed
UNIT LOAD ACTIVE SUB DESCRIPTION
backup.service loaded failed failed Backup Service
# List enabled services that are NOT currently active
$ systemctl list-unit-files --type=service --state=enabledViewing Logs for Services — journalctl
Systemd stores service logs in the journal (binary format). Use journalctl to read them.
# View all logs for a service
$ journalctl -u nginx.service
-- Journal begins at Thu 2026-04-10 08:00:00 UTC, ends at Thu 2026-04-10 11:30:00 UTC. --
Apr 10 09:05:00 server systemd[1]: Starting A high performance web server...
Apr 10 09:05:00 server nginx[1234]: 2026/04/10 09:05:00 [notice] 1234#1234: using inherited sockets...
Apr 10 09:05:00 server systemd[1]: Started A high performance web server.
# Follow logs in real-time (-f = follow)
$ journalctl -u nginx.service -f
# View last 50 lines
$ journalctl -u nginx.service -n 50
# View since last boot
$ journalctl -u nginx.service -b
# View logs from specific time range
$ journalctl -u nginx.service --since "2026-04-10 09:00:00"
$ journalctl -u nginx.service --since "1 hour ago"
$ journalctl -u nginx.service --since "today"
# View only error-level and worse
$ journalctl -p err -u nginx.serviceCreating a Systemd Service
Service Unit File Structure
# /etc/systemd/system/myapp.service
[Unit]
Description=My Application
Documentation=https://myapp.dev/docs
After=network.target # Start after network is up
Wants=network.target
[Service]
Type=simple # simple = one process; forking = spawns children
User=myapp # Run as this user
Group=myapp
WorkingDirectory=/opt/myapp
ExecStart=/opt/myapp/bin/myapp --config /opt/myapp/config.yaml
ExecReload=/bin/kill -HUP $MAINPID # Graceful reload signal
ExecStop=/bin/kill -TERM $MAINPID # Graceful stop signal
Restart=on-failure # Restart on crash
RestartSec=5 # Wait 5s before restarting
StandardOutput=journal # Log to systemd journal
StandardError=journal
# Environment
EnvironmentFile=/opt/myapp/.env
[Install]
WantedBy=multi-user.target # Start at boot (if enabled)Managing Your Service
# Reload systemd to recognize new/changed unit files
$ sudo systemctl daemon-reload
# Start the service
$ sudo systemctl start myapp
# Enable at boot
$ sudo systemctl enable myapp
# Check status
$ systemctl status myapp
# View logs
$ journalctl -u myapp -fService Types
| Type | Meaning | Use Case |
|---|---|---|
simple | Main process doesn't fork | Most services |
forking | Process forks child, parent exits | Daemonized programs |
oneshot | Runs once and exits | One-time scripts |
exec | Service is the main process | Container-like services |
Troubleshooting Services
Service Won't Start
# Always check status first — it shows the error
$ sudo systemctl status nginx
● nginx.service - A high performance web server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled)
Active: failed (Result: exit-code) since Thu 2026-04-10 09:10:00 UTC; 5s ago
Process: 5678 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=1/FAILURE)
Main PID: 5678 (code=exited, status=1/FAILURE)
Apr 10 09:10:00 server nginx[5678]: 2026/04/10 09:10:00 [emerg] 5678#5678: directCommon issues and fixes:
# 1. Configuration error — test before starting
$ sudo nginx -t
nginx: [emerg] directive "worker_processes" is unexpected in /etc/nginx/nginx.conf:15
nginx: configuration file /etc/nginx/nginx.conf test failed
# 2. Port already in use
$ sudo systemctl start nginx
Job for nginx.service failed because the control process exited with error code.
See "systemctl status nginx.service" and "journalctl -xe" for details.
$ journalctl -u nginx | tail -20
Apr 10 09:10:00 server nginx[5678]: [emerg] 5678#5678: bind() to 0.0.0.0:80 failed (98: Address already in use)
# Check what's using the port
$ ss -tlnp | grep :80
# 3. Permission denied
$ journalctl -u nginx | grep "Permission denied"Viewing Full Logs with Context
# -xe shows logs with additional context around the error
$ journalctl -xe -u nginx
# Check kernel messages (sometimes hardware-related)
$ dmesg | tail -50Quick Reference
| Task | Command |
|---|---|
| Check status | systemctl status <service> |
| Start service | sudo systemctl start <service> |
| Stop service | sudo systemctl stop <service> |
| Restart service | sudo systemctl restart <service> |
| Reload config | sudo systemctl reload <service> |
| Enable at boot | sudo systemctl enable <service> |
| Disable at boot | sudo systemctl disable <service> |
| Enable and start | sudo systemctl enable --now <service> |
| View logs | journalctl -u <service> |
| Follow logs | journalctl -u <service> -f |
| View since boot | journalctl -b -u <service> |
| Check if enabled | systemctl is-enabled <service> |
| List active services | systemctl list-units --type=service |
| List failed services | systemctl list-units --type=service --state=failed |
| Reload systemd config | sudo systemctl daemon-reload |
Practice Challenge
- Run
systemctl status ssh— is SSH active and enabled? - Check which services are running with
systemctl list-units --type=service --state=running - View the last 20 lines of SSH logs with
journalctl -u ssh -n 20 - Find any failed services with
systemctl list-units --type=service --state=failed - Create a simple systemd service unit for a script (or read an existing one in
/etc/systemd/system/)