systemd is the init system on every mainstream Linux distro since 2015 — Ubuntu, Debian, Fedora, RHEL/Rocky/Alma, openSUSE, Arch. Knowing the eight commands below covers 99 percent of daily ops.
Prerequisites
- A Linux box with systemd as PID 1.
sudofor any service control.
Step 1: Confirm systemd is PID 1
ps -p 1 -o comm=
# systemd
systemctl --version | head -1
If you see something else (init, openrc-init) you are on a non-systemd box — see Alpine apk for the OpenRC variant.
Step 2: Status, start, stop, restart, reload
sudo systemctl status nginx # current state + recent log lines
sudo systemctl start nginx # start (no-op if already running)
sudo systemctl stop nginx # stop
sudo systemctl restart nginx # stop + start
sudo systemctl reload nginx # SIGHUP, only if the unit supports it
sudo systemctl reload-or-restart nginx # reload if possible, restart otherwise
reload vs restart matters for production: reload preserves in-flight connections; restart drops them.
Step 3: Enable, disable, mask
sudo systemctl enable nginx # start on boot
sudo systemctl enable --now nginx # enable AND start right now
sudo systemctl disable nginx # don't start on boot
sudo systemctl mask nginx # make impossible to start; sym-linked to /dev/null
sudo systemctl unmask nginx
mask is what you reach for when a stubborn package keeps re-enabling something you do not want (Apache when you installed Nginx, for example).
Step 4: List and inspect
systemctl list-units --type=service # currently loaded
systemctl list-units --type=service --state=running
systemctl list-units --type=service --state=failed # what's broken
systemctl list-unit-files --type=service # all known units + state
systemctl is-active nginx # active / inactive / failed
systemctl is-enabled nginx # enabled / disabled
systemctl cat nginx # show the unit file(s)
systemctl show nginx | head -30 # all properties
Step 5: Logs — journalctl
sudo journalctl -u nginx -f # follow this unit's log live
sudo journalctl -u nginx --since '1 hour ago'
sudo journalctl -u nginx --since '2026-05-27' --until '2026-05-27 12:00'
sudo journalctl -p err -b # errors+ since last boot
sudo journalctl -p err --since today
sudo journalctl _PID=12345 # all logs from a PID
sudo journalctl -k # kernel ring buffer
For long-term retention, set Storage=persistent in /etc/systemd/journald.conf and create /var/log/journal/.
Step 6: Write your own unit
/etc/systemd/system/skyline-api.service:
[Unit]
Description=SKYLINE API service
After=network-online.target postgresql.service
Wants=network-online.target
[Service]
Type=simple
User=skyline
Group=skyline
WorkingDirectory=/opt/skyline-api
EnvironmentFile=/etc/skyline-api.env
ExecStart=/opt/skyline-api/bin/api
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5
TimeoutStopSec=30
# Hardening
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
ReadWritePaths=/var/log/skyline-api /var/lib/skyline-api
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
Apply:
sudo systemctl daemon-reload
sudo systemctl enable --now skyline-api
sudo systemctl status skyline-api
sudo journalctl -u skyline-api -f
daemon-reload is required after editing any unit file. Skipping it is the number-one "but I changed it!" mistake.
Step 7: Timers (the systemd cron)
/etc/systemd/system/backup.service:
[Unit]
Description=Nightly skyline backup
[Service]
Type=oneshot
ExecStart=/usr/local/bin/skyline-backup.sh
/etc/systemd/system/backup.timer:
[Unit]
Description=Run skyline backup nightly
[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true
RandomizedDelaySec=5min
[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timers
Persistent=true reruns missed timers if the host was off when they should have fired — something cron cannot do.
Step 8: Drop-in overrides
To tweak a packaged unit without editing the original:
sudo systemctl edit nginx
That opens an editor for /etc/systemd/system/nginx.service.d/override.conf. Add only the lines you want to override:
[Service]
LimitNOFILE=65536
Restart=on-failure
sudo systemctl restart nginx
sudo systemctl show nginx | grep -E '(LimitNOFILE|Restart)='
Updates to the package no longer wipe your customisations.
Verify
systemctl --failed
systemctl list-units --type=service --state=running | head -20
journalctl -p err -b | tail -20
systemctl list-timers | head -10
Conclusion
status, start, stop, restart, reload, enable, disable, list-units plus journalctl -u UNIT -f — eight commands and you are operational on any modern Linux distro.
Next steps
- Pair this with Linux file permissions when units fail because of file ownership.
- Schedule routine work via cron on Debian or systemd timers (Step 7 above).
- Write shell helpers via Bash scripting fundamentals.
Comments
0 total · 0 threads