<aside> ⚙️
Module 11 — systemd and Services
Module 8 ended on a cliffhanger: nohup keeps a program alive, but nothing keeps it managed — restarted when it crashes, started at boot, logged, stopped cleanly. That job belongs to systemd, PID 1 on essentially every modern Linux server. This module teaches you to run, inspect, and write services — the single most common day-to-day task in operations, and a guaranteed interview topic.
Legend used throughout: 🧠 concept → 🧩 analogy → 🧪 exercise → ✅ expected result (hidden) → 🎯 interview questions (hidden)
</aside>
<aside> 🚦
Before you start
You need Modules Module 1 — What Linux Is–Module 10 — Bash Scripting — especially processes/daemons/signals (Module 8: systemd supervises processes and stops them with the exact TERM→KILL ladder you learned), the filesystem (unit files live in specific places), and scripting (a service usually runs a script). Tools: a systemd-based Ubuntu 24.04 machine — a normal cloud VM or WSL2. Two caveats that matter for the exercises: (1) some minimal containers don't run systemd as PID 1 — inside one, systemctl status prints System has not been booted with systemd as init system and the live commands won't work; use a real VM. (2) Where an exercise's output can't come from an un-booted machine, it's marked — but systemd-analyze verify and systemd-analyze calendar work anywhere systemd is installed, so those exercises run even in a container.
Goes deeper: the boot sequence that ends in systemd is the companion track's Module 05 — Boot & Init: Firmware to systemd — read it alongside this module.
</aside>
<aside> ℹ️
This page uses Mermaid diagram blocks. Notion shows them as code by default — click the block and set it to Preview to see the diagram. This reminder appears once per page.
</aside>
<aside> 📖
Official docs: systemd(1) · systemctl(1)
</aside>
🧠 Module 8 introduced PID 1 as the ancestor of all processes; now meet what it actually does. systemd is the first program the kernel starts at boot (PID 1) and the init system — the thing that brings the machine up and manages everything running on it. Its core job is running services: long-lived programs (Module 8's daemons) that it starts in the right order, restarts when they die, stops cleanly on shutdown, and captures the logs of. It replaced the older init/SysV scripts because doing all this reliably — with dependencies, parallelism, and supervision — needs a real manager, not a pile of shell scripts.
The command you drive it with is systemctl. Everything systemd manages is a unit (A2); a service is one kind of unit.
<aside> 🧩
Real-world analogy — the building operations manager
nohup was hiring a contractor and telling them "keep working after I leave" (Module 8) — nobody supervises them. systemd is the building's operations manager: it hires every service, starts them in the right order (heating before the offices open), notices when one collapses and restarts it, shuts them down cleanly at night, and keeps a logbook of everything. The building runs because one manager owns the whole lifecycle.
Where the analogy stops working. A building manager delegates and sleeps. systemd is PID 1 — it personally is the parent (or ancestor) of every managed process, never off-duty, and if it exits the whole machine panics (Module 8's "PID 1 cannot die"). It's less a manager who oversees staff than the building's own nervous system: remove it and there is no building, only hardware.
</aside>
🧪 Exercise A1.1 — Meet the manager (live commands need a booted systemd machine)
systemctl --version | head -1 # which systemd? (works even in a container)
ps -p 1 -o pid,comm # what IS pid 1 on this machine?
systemctl is-system-running # a one-word health summary (booted machines only)
<aside> 📖
Official docs: systemd.unit(5)
</aside>
🧠 systemd manages everything as units, each a plain-text INI-style file describing one manageable thing. The types you'll meet: .service (a program to run — the overwhelmingly common one), .timer (a schedule that triggers a service — the cron replacement, Part D), .socket (start a service on demand when its port is connected), .mount (a filesystem mount — Module 12), .target (a named group of units for reaching a system state, e.g. multi-user.target = "fully booted, multi-user, networked"). Unit files live in three places, in priority order: /etc/systemd/system/ (admin-created — yours), /run/systemd/system/ (runtime), and /usr/lib/systemd/system/ (package-provided — don't edit these directly). A file in /etc overrides one of the same name in /usr/lib — the mechanism for customizing a packaged service without touching its shipped file.
<aside> 🧩
Real-world analogy — index cards in a recipe box
Each unit is an index card in the ops manager's recipe box: one card per thing that can be run, each stating what it is, what it needs first, and how to start and stop it. .service cards are dishes; .target cards are whole menus ("dinner service" = these ten dishes together); .timer cards say "start this dish at this time".
Where the analogy stops working. Recipe cards are inert until a cook reads them. Unit files are live wiring: systemd holds them all in memory as a dependency graph, and changing a card means telling systemd to re-read the box (systemctl daemon-reload) — edit a unit file and forget the reload, and systemd keeps cooking from the old card, which is the single most common "why didn't my change take effect?" surprise in this whole module.
</aside>
🧪 Exercise A2.1 — Look at real units (list commands need a booted machine; the file inspection works anywhere)
ls /usr/lib/systemd/system/*.target | head -5 # some packaged targets (works anywhere)
cat /usr/lib/systemd/system/multi-user.target # what a target file looks like
systemctl list-units --type=service | head -8 # running services (booted machines only)