Unit Files — The Basic Building Block
systemd in Depth
Chapter 2 · Unit Files — The Basic Building Block
systemd1-1 established what systemd is and why it exists. This chapter gets concrete — the actual files systemd reads, and the real systemctl commands behind everything ws1 and ansible1-4 already used, unexplained.
What a Unit Is
A unit is systemd's own generic term for anything it manages — not just services, but sockets, timers, mounts, devices, and targets too (systemd1-3 covers .service in full depth, systemd1-7 covers .timer, systemd1-8 covers .socket). Every unit is described by a plain-text configuration file — its unit file.
Where Unit Files Actually Live — Location Precedence
- /usr/lib/systemd/system/ (or
/lib/systemd/system/) — units shipped by installed packages, the vendor default - /etc/systemd/system/ — local admin overrides and custom units, taking priority over the vendor copy
- /run/systemd/system/ — runtime-only, volatile, never survives a reboot; used by systemd itself and some tools for temporary units
If the same unit name exists in more than one location, /etc wins over /usr/lib — a real, useful override mechanism. Copying a vendor unit into /etc/systemd/system/ and editing it there lets you customize a service without touching the original package-provided file, which a future package update would otherwise silently overwrite.
Basic Unit File Syntax — A First Look
Just enough to recognize the shape — systemd1-3 does the real deep dive. [Unit] holds metadata (Description=); [Service] holds the actual execution details (ExecStart=, the command actually run); [Install] controls what happens when the unit is enabled — WantedBy=multi-user.target is exactly why this note matters back in systemd1-1's own boot-target material.
systemctl — The Real Command, In Depth
- systemctl start/stop/restart NAME — an immediate, one-time action; does not by itself survive a reboot
- systemctl status NAME — current state, recent log lines, whether it's enabled
- systemctl enable/disable NAME — a genuinely different axis: controls whether the unit starts automatically at the next boot, by creating or removing a symlink tied directly to the unit's own
[Install]/WantedBy=line — completely independent of whether it's running right now
The real, common beginner confusion: enabling a service does not start it immediately, and starting a service does not enable it. These are two separate actions, frequently needed together.
Revealing What ansible1-4's Own service Module Wraps
ansible1-4's own service: name: nginx state: started is, underneath, literally invoking systemctl start nginx. Ansible's own idempotency check — is it already running? — corresponds directly to systemctl status being checked first, with start only actually called if genuinely needed. state: started maps to systemctl start; the module's own enabled: true option maps directly to systemctl enable. This is precisely what systemd1-1 promised, and what ansible1-1/ansible1-4 left unexplained.
| Controls | Survives a reboot on its own? | |
|---|---|---|
| start / stop / restart | Whether the unit is running right now | No |
| enable / disable | Whether the unit starts automatically at boot | Yes — that's the whole point |
grub1-2's own warning against hand-editing grub.cfg — a package update can silently overwrite it. The correct place for a customization is /etc/systemd/system/, either as a full override copy, or, more surgically, via a drop-in override file — a lighter-weight option covered later in this course.
Hands-On Exercises
Explain the difference between running "systemctl start nginx" and "systemctl enable nginx" on a system where nginx is currently stopped and disabled, including what happens on the next reboot in each case.
📄 View solutionA unit named webapp.service exists in both /usr/lib/systemd/system/ and /etc/systemd/system/, with different ExecStart= values. Explain which one systemd actually uses, and why.
📄 View solutionExplain exactly what Ansible's service module is doing internally when it runs "service: name: nginx state: started enabled: true", in terms of the two systemctl actions this chapter describes.
📄 View solutionChapter 2 Quick Reference
- A unit is anything systemd manages, described by a plain-text unit file (.service, .timer, .socket, ...)
- Location precedence: /etc/systemd/system/ overrides /usr/lib/systemd/system/; /run/systemd/system/ is volatile
- Basic unit shape: [Unit] (metadata), [Service] (execution), [Install] (enable behavior)
- start/stop/restart — right now, doesn't survive reboot; enable/disable — automatic at boot, independent of current state
systemctl enable --now NAME— does both at once- ansible1-4's own service module is a thin wrapper: state: started → systemctl start; enabled: true → systemctl enable
- Never hand-edit a unit file in /usr/lib/systemd/system/ — customize via /etc/systemd/system/ instead