Service Management
Master systemd and service management to control daemons and background services.
systemctl Commands
$ systemctl start nginx # Start service
$ systemctl stop nginx # Stop service
$ systemctl restart nginx # Restart service
$ systemctl reload nginx # Reload config
$ systemctl status nginx # Check status
$ systemctl enable nginx # Start at boot
$ systemctl disable nginx # Don't start at boot
$ systemctl is-active nginx # Check if running
$ systemctl stop nginx # Stop service
$ systemctl restart nginx # Restart service
$ systemctl reload nginx # Reload config
$ systemctl status nginx # Check status
$ systemctl enable nginx # Start at boot
$ systemctl disable nginx # Don't start at boot
$ systemctl is-active nginx # Check if running
Listing Services
$ systemctl list-units --type=service
$ systemctl list-units --type=service --state=running
$ systemctl list-unit-files --type=service
$ systemctl list-units --type=service --state=running
$ systemctl list-unit-files --type=service
Service Unit Files
Service files are located in /etc/systemd/system/ or /lib/systemd/system/:
# /etc/systemd/system/myapp.service
[Unit]
Description=My Application
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/myapp
Restart=always
[Install]
WantedBy=multi-user.target
[Unit]
Description=My Application
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/myapp
Restart=always
[Install]
WantedBy=multi-user.target
enable vs start (common confusion)
- •
start: starts the service now (runtime) - •
enable: makes it start automatically at boot (persistent)
$ systemctl enable --now nginx # enable + start in one step
$ systemctl disable --now nginx # disable + stop
$ systemctl disable --now nginx # disable + stop
Debugging a failing service
When a service won’t start, you want logs + exit codes + dependency context.
$ systemctl status nginx --no-pager
$ journalctl -u nginx -n 200 --no-pager
$ systemctl show nginx -p ExecStart -p FragmentPath -p User -p Group
$ systemctl list-dependencies nginx | head
$ journalctl -u nginx -n 200 --no-pager
$ systemctl show nginx -p ExecStart -p FragmentPath -p User -p Group
$ systemctl list-dependencies nginx | head
Pro tip
If the service runs fine manually but fails in systemd, compare environment variables, working directory, and permissions.
Overrides and Drop-ins (the safe way to customize)
Avoid editing vendor unit files in /lib/systemd/system. Instead, create an override drop‑in.
$ systemctl edit nginx
# This opens an editor and creates /etc/systemd/system/nginx.service.d/override.conf
# After changes:
$ systemctl daemon-reload
$ systemctl restart nginx
# This opens an editor and creates /etc/systemd/system/nginx.service.d/override.conf
# After changes:
$ systemctl daemon-reload
$ systemctl restart nginx
Timers (cron, but better)
systemd timers are a modern alternative to cron: they have logs, dependency awareness, and flexible schedules.
$ systemctl list-timers --all | head
$ systemctl status logrotate.timer --no-pager
$ systemctl status logrotate.timer --no-pager
Hardening Services (production)
systemd can sandbox services. You don’t need containers for basic isolation.
- •Run as a dedicated non-root user (
User=,Group=) - •Lock down filesystem access (
ReadOnlyPaths=,ReadWritePaths=) - •Reduce privileges (
NoNewPrivileges=true,CapabilityBoundingSet=)
✅ Practice (15 minutes)
- Pick a running service and inspect its unit file path using
systemctl show -p FragmentPath. - Force a service to fail (e.g., invalid config) and use
journalctl -uto find the root cause. - Create an override with
systemctl editthat adds anEnvironment=variable, then restart.