Chapter 11Lesson 02~50 minutes

Managing Services with systemctl

Operate systemd units deliberately: inspect effective definitions, distinguish runtime state from boot enablement, perform controlled transitions, and verify every result.

systemctlService operationsUser-unit lab

Learning objectives

By the end of this lesson

  • Distinguish unit load state, active state, substate, enablement, preset, and failure result.
  • Inspect effective unit definitions, properties, dependencies, and recent logs before changing state.
  • Use start, stop, restart, reload, try-restart, enable, disable, mask, and unmask correctly.
  • Explain the difference between system and user service managers.
  • Create and operate a safe user service without root privileges.

1. “Is the service running?” is several different questions

systemd manages many unit types: services, sockets, timers, mounts, automounts, paths, targets, devices, and scopes. For a service, loaded means systemd found and parsed a definition. active is a high-level runtime state, while the substate may be running, exited, listening, dead, or failed. Enablement describes whether dependency links will pull the unit into future boot or user-manager transactions. It does not describe the current process.

The service-management state model
flowchart TD
  A["Unit file and drop-ins"] --> B["Loaded configuration"]
  B --> C["Enablement links or preset policy"]
  B --> D["Runtime transaction"]
  D --> E["Active, inactive, activating, failed"]
  E --> F["Process, exit result, restart policy"]
  F --> G["Journal and dependency evidence"]
QuestionCommandMeaning
Loaded?systemctl statusDefinition parsed and available
Running now?systemctl is-activeCurrent runtime state
Starts automatically?systemctl is-enabledDependency links or static/indirect state
Failed?systemctl is-failedFailure state recorded by manager
Why?systemctl showDetailed properties and result fields

2. Inspect configuration and evidence before transitions

unit=ssh.service   # On some systems the unit is sshd.service

systemctl status "$unit" --no-pager
systemctl cat "$unit"
systemctl show "$unit" \
  -p LoadState -p ActiveState -p SubState -p UnitFileState \
  -p MainPID -p ExecMainStatus -p Result -p FragmentPath -p DropInPaths

systemctl list-dependencies "$unit"
systemctl list-dependencies --reverse "$unit"
journalctl -u "$unit" -b --no-pager -n 100

systemctl cat shows the main fragment and drop-ins in precedence order. show exposes machine-readable properties and is better than parsing human-oriented status output in automation. Reverse dependencies answer which units may be affected by a stop or failure.

3. Choose the least disruptive transition

01reload

Ask the service to re-read supported configuration without replacing the main process.

02restart

Stop and start the unit; expect an interruption unless architecture provides redundancy.

03try-restart

Restart only if already active; useful when applying optional changes.

04reload-or-restart

Reload when supported, otherwise restart.

05stop

Deactivate the unit and dependent behavior according to relationships.

# Validate application configuration first when a native checker exists
sudo nginx -t

# Then choose the smallest operation that applies the change
sudo systemctl reload nginx.service

# Verify state, result, PID continuity, and recent messages
systemctl is-active nginx.service
systemctl show nginx.service -p MainPID -p ActiveEnterTimestamp -p Result
journalctl -u nginx.service --since "5 minutes ago" --no-pager
Restart is not verification

A command can return successfully while the workload remains unhealthy, bound to the wrong address, unable to reach dependencies, or serving stale configuration. Verify the service and the user-facing outcome.

4. Runtime state and boot enablement are independent

enable creates links described by the unit's [Install] section. It does not normally start the unit unless combined with --now. disable removes enablement links but does not stop a running unit. Static units have no independent enablement instructions and are pulled in by dependencies. Masking links the unit to /dev/null, preventing manual and dependency-based activation until unmasked.

# Read-only enablement inspection
systemctl is-enabled cron.service 2>/dev/null || systemctl is-enabled crond.service
systemctl list-unit-files --type=service --state=enabled

# Intentional combined operations
sudo systemctl enable --now example.service
sudo systemctl disable --now example.service

# Mask only with a documented reason and recovery path
sudo systemctl mask example.service
sudo systemctl unmask example.service

Preset policy is a distribution or organization rule applied by systemctl preset. It can differ from an administrator's current choice. Avoid running preset-all casually on an established host.

5. User units provide per-user lifecycle management

systemctl --user communicates with the user's service manager. User units live under paths such as ~/.config/systemd/user. They do not automatically gain root privileges. Their environment, login lifecycle, and availability differ from system units. Lingering can keep a user manager alive without an active login, but should be enabled only intentionally.

systemctl --user status --no-pager
systemctl --user list-units --type=service
systemctl --user show-environment | sort | head -n 40
loginctl show-user "$USER" -p Linger -p State 2>/dev/null || true

6. Hands-on lab: create and operate a user service

This service writes a timestamped record inside your course directory. It uses no sudo and can be removed completely after the lab.

lab="$HOME/devops-academy/linux/chapter11/lesson02"
unit_dir="$HOME/.config/systemd/user"
mkdir -p "$lab" "$unit_dir"

cat > "$unit_dir/devops-academy-demo.service" <<'UNIT'
[Unit]
Description=DevOps Academy user-service demonstration

[Service]
Type=oneshot
ExecStart=/usr/bin/bash -c 'printf "started=%s user=%s\n" "$(date --iso-8601=seconds)" "$USER" >> %h/devops-academy/linux/chapter11/lesson02/service.log'
RemainAfterExit=yes

[Install]
WantedBy=default.target
UNIT

systemctl --user daemon-reload
systemctl --user start devops-academy-demo.service
systemctl --user status devops-academy-demo.service --no-pager
systemctl --user show devops-academy-demo.service -p ActiveState -p SubState -p Result
cat "$lab/service.log"

# Optional enablement exercise, then return to the original disabled state
systemctl --user enable devops-academy-demo.service
systemctl --user is-enabled devops-academy-demo.service
systemctl --user disable devops-academy-demo.service

systemctl --user stop devops-academy-demo.service
rm -f "$unit_dir/devops-academy-demo.service"
systemctl --user daemon-reload
systemctl --user reset-failed

Verification checklist

7. Common systemctl mistakes

“Enabled means running.”

Enablement affects future activation relationships; active state describes the current manager transaction.

“Restart is the safest way to apply every change.”

Reload may avoid interruption, and some configuration should be validated before either action.

“disable prevents all starts.”

A disabled unit can still be started manually or pulled in by another dependency. Masking is stronger.

“status contains everything.”

Use cat, show, dependency inspection, and the journal for complete evidence.

8. Knowledge check

Question 1. What is the difference between enable and start?

Question 2. When is reload preferable to restart?

Question 3. Why inspect reverse dependencies before stopping a unit?

9. Summary

systemctl operates a stateful dependency manager. Reliable service work distinguishes configuration, runtime state, enablement, and failure result; inspects effective definitions and dependencies; chooses the least disruptive transition; and verifies both manager state and workload behavior.

10. Further reading

  • systemctl(1), systemd.unit(5), and systemd.service(5).
  • systemd.preset(5), loginctl(1), and user-manager documentation.
  • Service-specific configuration-validation and graceful-reload documentation.
Next lesson

Writing and Hardening systemd Unit Files

Turn service requirements into explicit unit lifecycle, dependency, resource, and sandbox policy.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.