Topic 3.4
systemd & Services
In one line
systemd is the modern standard for running services on Linux — it starts them at boot, restarts them if they crash, and gives you one consistent set of commands (systemctl) to control anything, regardless of what the service actually is.
Think of it like this
A building's facilities manager, whose job is to make sure the heating, water, and elevators are always running, restart automatically if they fail, and can each be turned on or off independently through one consistent control panel — that's exactly systemd's role for services on a Linux machine.
Key ideas
- 01
systemd is PID 1 on virtually every modern Linux distribution — the very first process the kernel starts, responsible for starting everything else in the correct order, including all the SERVICES you'll manage directly.
- 02
A UNIT FILE (a plain text config file, typically under
/etc/systemd/system/) describes one service: what command to run, what user to run it as, whether to restart it automatically on failure, and what it depends on starting after. Writing one is genuinely straightforward once you've seen a real example — this topic's code block is one. - 03
systemctl start <service>starts it now.systemctl stop <service>stops it.systemctl enable <service>makes it start AUTOMATICALLY on every future boot (separate from starting it right now —enablealone doesn't start anything immediately, andstartalone doesn't survive a reboot).systemctl status <service>shows whether it's running, its recent log output, and its PID. - 04
journalctl -u <service>shows that service's own logs, collected centrally by systemd's own logging system (journald) — genuinely more convenient than hunting for a scattered log file, since it's the SAME command regardless of which service you're investigating.journalctl -u <service> -ffollows it live, the systemd-native equivalent oftail -f. - 05
Restart=on-failurein a unit file tells systemd to automatically restart the service if it exits with a failure code — this single line is a huge reliability win over a manually-runnohupprocess, which simply stays dead after any crash with nobody watching.
In your stack
- →
A real Spring Boot systemd unit typically sets
ExecStart=/usr/bin/java -jar /opt/myapp/app.jar,User=springapp(Phase 1's dedicated non-root user), andRestart=on-failure— this exact combination is how most Java services run in production outside of a container-orchestrated environment.
Code & diagrams
A realistic, minimal systemd unit file — the shape is nearly identical regardless of language.
# Save as /etc/systemd/system/myapp.service
[Unit]
Description=My Application
After=network.target
[Service]
Type=simple
User=myappuser
WorkingDirectory=/opt/myapp
ExecStart=/usr/bin/java -jar /opt/myapp/app.jar
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.targetThe standard control loop for any systemd-managed service.
# After creating/editing a unit file, reload systemd's own config
sudo systemctl daemon-reload
# Start it right now
sudo systemctl start myapp
# Make it start automatically on every future boot
sudo systemctl enable myapp
# Check its current status, recent logs, and PID
sudo systemctl status myapp
# Watch its logs live
sudo journalctl -u myapp -f
# Restart it (stop + start in one command) after deploying a new version
sudo systemctl restart myapp
# Stop it, and prevent it from starting on boot
sudo systemctl stop myapp
sudo systemctl disable myappExplain it without notes
What's the practical difference between systemctl start and systemctl enable, and why are they separate commands?
Why is a systemd-managed service generally more reliable in production than a process started manually with nohup?
Practice
Write a minimal systemd unit file for any simple command (even just ExecStart=/bin/sleep infinity as a harmless test), enable and start it, confirm it's running with systemctl status, then stop and disable it.
Deliberately make a test service crash (point ExecStart at a script that exits immediately with a failure code) and confirm systemd actually restarts it automatically when Restart=on-failure is set.
Trade-offs
- ↔
systemd's guarantees (auto-restart, boot-time startup, centralized logs) come with a real learning curve and a moderately verbose unit-file syntax compared to just typing a command — but for anything running in production that you actually need to stay up reliably, that upfront cost is well worth it compared to the alternative of manually noticing and restarting a crashed process by hand.
Done when you can
I can write a minimal systemd unit file for a simple service.
I understand the difference between systemctl start (now) and enable (on boot).
I know journalctl -u <service> -f is the systemd-native way to watch a service's logs live.