Services & systemd
A service is a background daemon that does a defined job — sshd for SSH, nginx for HTTP, cron for scheduled tasks. On modern Linux, systemd is the init system running as PID 1 that supervises every service: starting it at boot, restarting it on failure, ordering dependencies and collecting logs. Learn the systemctl and journalctl commands that control it all.
What is this?
A service (or daemon) is a background process that runs without a terminal and does a well-defined job: sshd answers SSH, nginx answers HTTP, cron runs scheduled commands. On modern Linux, systemd is the init system that owns all services — it boots first as PID 1, starts services in dependency order, restarts them when they fail, and captures their logs. Two commands control all of it: systemctl for service life cycle and journalctl for logs.
Why do you need it?
- Services are what a server actually does — every web, database, SSH and observability workload is a supervised service.
- One mental model: systemctl start/stop/restart/status works identically for every service on the machine.
- Boot correctness: systemd starts nginx only after the networking and filesystems it depends on are ready.
- Self-healing and observability: Restart= policies bring crashed services back, and journalctl keeps every log line in one searchable place.
Mental model
A hotel front desk
systemd as PID 1
systemd is the front desk: it checks guests in at boot (start), handles complaints (restart), shows who is in-house (status, list-units) and logs every call (journal). Each guest is a service with a defined role. The front desk decides who is allowed to check in first and rings room service again when it drops the phone.
How it works
- The kernel spawns systemd as the very first process (PID 1); every other process is started by systemd, which also adopts and reaps orphaned processes.
- Each service has a unit file (/etc/systemd/system/<name>.service) declaring the command to run, its dependencies and its restart policy.
- systemctl start <name> tells systemd to read the unit, satisfy its dependencies and launch the ExecStart command as a supervised process.
- When a service exits, systemd applies its Restart= policy (always, on-failure, no) and can relaunch it automatically.
- systemd-journald captures each service's stdout/stderr into the journal, which journalctl queries with -u <name> or streams with -f.
How systemd supervises a service from boot to logs.
Key commands
systemctl status nginxShow state, enabled-at-boot flag, Main PID and the tail of the service's logs.
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: enabled)
Active: active (running) since Sat 2026-08-08 09:14:23 UTC; 2min 5s ago
Main PID: 4567 (nginx)
Tasks: 3 (limit: 4634)
CPU: 12ms
CGroup: /system.slice/nginx.service
├─4567 "nginx: master process /usr/sbin/nginx"
├─4568 "nginx: worker process"
└─4569 "nginx: worker process"systemctl start nginxStart the service now. Success prints no output.
systemctl stop nginxStop the service now.
systemctl restart nginxStop then start again — the classic way to apply config and recover from a bad state.
systemctl enable nginxRegister the service to start automatically at boot by creating symlinks.
systemctl disable nginxRemove the auto-start-at-boot registration. It does not stop a running service.
systemctl list-units --type=service --state=runningList every service unit that is currently running.
UNIT LOAD ACTIVE SUB DESCRIPTION cron.service loaded active running Regular background program processing daemon nginx.service loaded active running A high performance web server ssh.service loaded active running OpenBSD Secure Shell server
journalctl -u nginx -fFollow the nginx service's journal live, like tail -f.
journalctl -u nginx -bShow all nginx journal entries from the current boot.
Examples
Start, enable and inspect the nginx service
# 1. Confirm systemd really is PID 1ps -p 1 -o comm= # 2. Start nginx and check its statesystemctl start nginxsystemctl status nginx --no-pager | head -5 # 3. Make it start automatically at bootsystemctl enable nginx # 4. Ask systemd to pick it up and put it downsystemctl restart nginx # 5. Read only nginx's log linesjournalctl -u nginx --no-pager | tail -15systemctl status shows the unit's state (active/running), whether it is enabled at boot, its Main PID and the most recent log lines. enable creates symlinks so systemd starts nginx automatically. journalctl -u filters the whole journal down to a single unit — the modern replacement for hunting through /var/log files.
In production
- Every major distro — Ubuntu, Debian, RHEL, Fedora — runs systemd, so the same commands work across the whole fleet.
- systemctl status is the first command in most runbooks: it reports state, boot enablement, PID and the tail of the log in one shot.
- Restart=on-failure with a WatchdogSec keeps flaky workers alive without a human paging at 3am.
- Containers and Kubernetes pods are supervised processes under the hood — the PID 1 and logging concepts transfer directly.
- systemd timers replace cron for periodic jobs and get full journal integration for free.
Best practices
- Learn status/start/stop/restart first; enable/disable (boot behaviour) is a separate concern that is easy to confuse.
- Use systemctl restart instead of stop+start: it orders the transition and re-reads configuration.
- Prefer systemctl reload for services that support live reload (nginx) to avoid downtime.
- Scope log reads to a unit: journalctl -u <unit> -f, and -b to limit results to the current boot.
- After editing a unit file, run systemctl daemon-reload before restart so systemd sees your changes.
Common mistakes
- Editing a unit file and forgetting systemctl daemon-reload, then wondering why changes never apply.
- Using enable when you meant start: enable only configures boot behaviour, it does not launch the service now.
- Running stop then start instead of restart, leaving the service down between the two commands.
- Stopping at 'Active: failed' without reading the journal — status says the unit failed; the reason lives in journalctl.
Common issues
System has not been booted with systemd as init system (PID 1). Can't operate.You are inside a container that has no systemd (the usual case with a plain ubuntu image).
Use service nginx start or the daemon's binary directly, or run a systemd-enabled image (e.g. jrei/systemd-ubuntu).
Failed to connect to bus: No such file or directorysystemd's dbus is not running, typically because systemd is not PID 1 in the container.
Use a systemd-capable container image, or fall back to service <name> start and read /var/log/<service>/ logs.
Job for nginx.service failed because the control process exited with error code.The service binary failed at startup — often a config error or a port already in use.
Read the real error with journalctl -u nginx -b and check for a conflicting process with ss -tulpn.
Unit nginx.service could not be found.The package is not installed or you guessed the unit name wrong.
Install it (apt install nginx / dnf install nginx) and confirm the name with systemctl list-units.
Debugging tips
- systemctl status <unit> already shows the last few log lines — read those before anything else.
- journalctl -u <unit> -b --no-pager | grep -i error finds the smoking gun fast.
- systemctl --failed lists every unit that failed to start on this boot.
- An exit code in status (Result: exit-code) means the service process itself failed, not systemd.
Interview checkpoint
Hands-on lab
- Launch a container where systemd runs as PID 1
- Install and start nginx through systemd
- Make the service auto-start at boot and verify its status
- Generate traffic and follow the service's logs in journalctl
- Restart the service and confirm it returns with a fresh PID
Supervise a service with systemd and read its logs
20 min · intermediate
Quick quiz
Which process is PID 1 on a modern Linux system?
Which command stops a service from starting automatically at boot?
systemctl enable nginx starts the service immediately as well as at boot.
How do you follow the live logs of just the nginx service?
A unit shows Active: failed. Where do you look first for the reason?
nginx crashes every few minutes in production. Which unit setting makes systemd relaunch it automatically?
Cheat sheet
systemctl start nginxStart the service nowsystemctl stop nginxStop the service nowsystemctl restart nginxStop then start againsystemctl reload nginxReload config without downtimesystemctl status nginxState, PID and log tailsystemctl is-active nginxPrint active or inactivesystemctl enable nginxAuto-start at bootsystemctl enable --now nginxEnable and start at oncesystemctl disable nginxStop auto-starting at bootsystemctl is-enabled nginxPrint enabled or disabledsystemctl daemon-reloadRe-read unit files after editssystemctl list-unitsAll loaded unitssystemctl list-units --type=service --state=runningRunning services onlysystemctl list-unit-filesAll units and enable statesystemctl --failedUnits that failed this bootjournalctl -u nginxAll nginx entriesjournalctl -u nginx -fFollow nginx logs livejournalctl -u nginx -bOnly the current bootjournalctl -p err -bErrors and worse, this bootjournalctl --since '1 hour ago'Entries from the last hour