📜 Part of Pranav Kulkarni's technical portfolio Visit pranavkulkarni.org →
Lesson 2 · System Administration

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

Listing Services

$ systemctl list-units --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

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

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

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

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

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 -u to find the root cause.
  • Create an override with systemctl edit that adds an Environment= variable, then restart.