Skip to content
← System engineer foundations

Learning bite

systemd units and lifecycle

Separate service configuration, startup, readiness, and boot enablement.

Documentation reviewed2026-10-01 · 3 min read
On this page

Put a process under a manager

A service manager starts work, tracks its exit, and can restart it according to a policy. On many Linux distributions that manager is systemd. A unit is its named configuration for a service, timer, socket, mount, or another managed object. A service unit explains what to run and under which conditions.

Inside the Ubuntu machine, check ps -p 1 -o comm=. The system-level commands below assume PID 1 is systemd; they do not apply to macOS or to a minimal application container. A user service uses a separate per-user manager through systemctl --user.

Ask four separate questions

QuestionRelevant operationWhat it does not establish
Is it running now?start, stop, statusWhether it starts after the next boot
Is future activation configured?enable, disable, is-enabledCurrent success or failure
Has the unit definition been reread?daemon-reloadApplication configuration has reloaded
Can it serve the intended request?Application-level checkThis cannot be inferred from enablement

restart stops then starts a service. reload asks the application to reread its own configuration when supported. enable --now combines activation configuration with immediate start. Repeating enable cannot fix an invalid ExecStart command.

Inspect existing units without restarting them:

bash
systemctl --failed --type=service
systemctl list-units --type=service --state=running

Choose one actual listed name and substitute it for SERVICE.service:

bash
systemctl status SERVICE.service --no-pager
systemctl cat SERVICE.service
systemctl show SERVICE.service -p MainPID -p ActiveState -p SubState
systemctl is-enabled SERVICE.service

The status display's Loaded line describes the definition and enablement; Active describes current state. MainPID identifies the main process when one exists. A disabled unit may be running because someone started it, while an enabled unit may have failed. is-enabled can report other states such as static; not every unit is designed for direct enablement.

Read a unit as instructions

This is a complete small oneshot unit, used as a reading example here and installed as a separate user fixture in the lab:

ini
[Unit]
Description=Study one-shot check

[Service]
Type=oneshot
ExecStart=/usr/bin/true

[Unit] contains general description/dependencies. [Service] defines service execution. true performs no work and exits 0. A successful oneshot normally becomes inactive when done unless configured to remain active, so “inactive” is not sufficient evidence of failure. A long-running foreground web server uses a different lifecycle; Type=exec, simple, or notify have different startup/readiness semantics.

For a system service, User= and Group= choose credentials; WorkingDirectory= defines relative-path context; EnvironmentFile= can supply environment values; and ExecStart= chooses the program and arguments. ExecStart is not an arbitrary shell command line: shell pipes and > need an explicitly invoked shell. A per-user unit already runs under that user; do not copy a system unit's root assumptions into it.

After= orders units but does not itself pull them in or prove a dependency is ready to answer application requests. Restart=on-failure can help with an unexpected exit, but a consistently invalid configuration may simply fail repeatedly. Start-rate controls belong to [Unit]. Understand the first failure before adding more retries.

Change definitions without losing the original

Packaged definitions typically live in distribution-managed locations. Local drop-ins can override selected settings without editing a vendor file; systemctl cat includes them for inspection. After a unit edit, use daemon-reload, then perform the appropriate start/restart. List-valued directives such as ExecStart can require clearing the old value in an override before setting the replacement.

A timer can trigger a service on a schedule; it does not require an always-running loop in your script. Timer/calendar configuration and advanced service sandbox settings are optional extensions after this module.

Predict the lab: if ExecStart=/usr/bin/false, will enabling the unit repair it? No: false deliberately exits unsuccessfully. If changed to true, must a PID remain afterward? No: successful oneshot completion is the desired result. Next, use the journal to inspect that result over time.

Sources

Primary references: systemd service units↗; systemctl↗.

Your notes and evidence

Record observations, questions, or links to your work. Keep credentials out of your notes.

Loading saved progress…

Back up or restore this path

Progress and notes stay in this browser. A backup contains only this learning path.