What a systemd service does
systemd is the init system on almost every current Linux distribution. A service unit tells it how to start a program, which user to run it as, what it depends on and what to do when it exits. With Restart=on-failure and WantedBy=multi-user.target, the program starts at boot and comes back after a crash without anything else watching it.
The parts of the unit file
- [Unit] — the description and ordering.
After=network-online.targetwithWants=network-online.targetmakes it start once the network is actually up, which matters for anything that connects to a database or an API on start. - [Service] — the program.
ExecStartneeds an absolute path;Userkeeps it from running as root;WorkingDirectoryis where relative paths resolve;EnvironmentandEnvironmentFileset variables;RestartandRestartSecdecide what happens when it exits. - [Install] —
WantedBy=multi-user.targetis whatsystemctl enableuses to start it at boot.
Restart policies
on-failurerestarts after a crash or a non-zero exit, but not after a clean stop. Right for most apps.alwaysrestarts even after the program exits cleanly. Right for programs that should never stop.noleaves it stopped. Right for one-off jobs.
If a program keeps failing, systemd stops trying after a burst of restarts (by default five within ten seconds). RestartSec=5 spaces restarts out so that limit is rarely reached by a short outage.
Basic sandboxing
The sandboxing option adds four settings that limit the damage a compromised service can do: NoNewPrivileges stops it gaining privileges through setuid programs, PrivateTmp gives it its own /tmp, ProtectSystem=full makes /usr, /boot and /etc read-only to it, and ProtectHome=read-only makes home directories read-only. If the app writes into its own folder under /home — uploads, a SQLite file, logs — leave sandboxing off or move that data, or the writes will fail.
Install, start and read the logs
sudo systemctl daemon-reload # after creating or editing the unit
sudo systemctl enable --now api # start now and at every boot
systemctl status api # running? last log lines?
journalctl -u api -f # follow the logssystemd or PM2 for a Node.js app?
Both keep a process running. systemd is already on the server, logs to the journal and needs nothing installed. PM2 adds cluster mode, zero-downtime reloads, per-app memory limits and a familiar CLI for Node developers. Many servers use both: systemd starts PM2 at boot (that is what pm2 startup sets up), and PM2 runs the apps. See What is PM2? and the PM2 ecosystem generator.
Run Node apps with Shipown
Shipown deploys Node and Next.js apps under PM2 — with the port, health check and restart policy set — and shows their state live, so for those apps you do not write a unit file at all.
Frequently asked questions
Where do systemd service files go?
Units you write yourself go in /etc/systemd/system/<name>.service. Run sudo systemctl daemon-reload after creating or editing one.
How do I make a service start at boot?
Include WantedBy=multi-user.target in the [Install] section and run sudo systemctl enable <name>. Adding --now also starts it immediately.
How do I see a service's logs?
journalctl -u <name> shows them; add -f to follow new lines and -n 100 to show the last hundred.
Why does ExecStart need an absolute path?
systemd does not load your shell profile, so commands found through your PATH in a terminal, such as node installed by nvm, are not found. Use the full path, which which node prints.
Should I use Restart=always or Restart=on-failure?
on-failure for most apps, so a deliberate clean stop is respected. always when the program must run no matter how it exited.