Units and state

Dependencies and targets

Read requirement and ordering relationships without assuming that After also starts another unit.

8 minute lesson

~~~

systemd separates whether a unit is required from when it should start. This distinction prevents many confusing unit files, and misreading it causes many broken ones.

Requirement vs ordering

Requires= and Wants= express requirement relationships. Wants= is the soft version: start that other unit too, but carry on if it fails. Requires= is hard: if the required unit fails to start, this unit fails with it. Prefer Wants= unless the service genuinely cannot exist without the dependency.

After= and Before= express ordering only. After=postgresql.service means “if both of us are starting, let PostgreSQL go first”. It does not pull PostgreSQL in.

That leads to the classic bug: a unit with After=network-online.target but no Wants=. Nothing asked the target to be reached, so the ordering is meaningless. The two directives travel in pairs:

[Unit]
Description=Demo API server
Wants=network-online.target
After=network-online.target postgresql.service

This unit pulls in network-online.target, waits for it, and orders itself after PostgreSQL without demanding it exists.

Targets group units

A target is a unit with no process of its own. It exists to group other units around a boot or operational state. multi-user.target is the normal server boot state; when you write WantedBy=multi-user.target in an [Install] section, enabling the service creates a symlink in that target’s .wants/ directory.

Read the graph

You can walk relationships in both directions:

systemctl list-dependencies --reverse network-online.target
network-online.target
● ├─demo-api.service
● └─nginx.service

The --reverse flag answers “who depends on this” instead of “what does this depend on”.

To see ordering as systemd resolved it, query the unit’s effective properties:

systemctl show demo-api.service -p Wants -p After

Run the list-dependencies command on your server. Find one unit that wants the target, then confirm one ordering relationship in that unit’s effective configuration. If you find an After= with no matching Wants= or Requires=, you have found a latent bug.

Lesson completed

Take this course offline

Get every free book and course as PDF and EPUB files.

Get the download library →