systemd Units & Services

Core verbs

systemctl status <unit>            # is it alive? why not?
sudo systemctl start|stop|restart|reload <unit>
sudo systemctl enable|disable <unit>          # boot-time wiring (symlinks)
systemctl list-units --failed                 # what's unhappy
systemctl --user ...                          # per-user managers too

enablestart: enable = at boot; start = now. Often you want both: enable --now.

Unit anatomy (custom service)

/etc/systemd/system/myapp.service:

[Unit]
Description=My background app
After=network-online.target

[Service]
Type=simple
ExecStart=/usr/local/bin/myapp --config /etc/myapp.conf
Restart=on-failure
RestartSec=5
User=myapp
# hardening worth copying into everything:
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes
PrivateTmp=yes

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload && sudo systemctl enable --now myapp
journalctl -u myapp -f                      # live logs

Drop-in overrides (don’t edit shipped units)

sudo systemctl edit sshd
# opens editor on override.conf — add lines like:
[Service]
MemoryMax=512M

Survives package updates; inspect effective unit via systemctl cat sshd.

Triage flow for failed units

  1. systemctl status <u> → exit code + last log lines

  2. journalctl -u <u> -b --no-pager | tail -50

  3. Common exits: 203 = ExecStart path/perm wrong; 1 = app config error

  4. Dependency view: systemctl list-dependencies <u>

Targets cheat

  • Default boot target: systemctl get-default / set-default multi-user.target

  • Equivalent of old runlevel 3 vs 5: isolate targets (sudo systemctl isolate graphical.target)