Manage services with systemd

2 min read07 November 2026

On Debian 13, systemd starts services, supervises them and centralises their logs. Knowing how to drive it avoids rebooting the whole VPS just to restart Nginx or an application. These are the systemd commands on Debian 13.

Basic commands

Action Command
Detailed status systemctl status nginx
Start now sudo systemctl start nginx
Stop now sudo systemctl stop nginx
Restart sudo systemctl restart nginx
Reload configuration sudo systemctl reload nginx
Enable at boot sudo systemctl enable nginx
Disable at boot sudo systemctl disable nginx
List failures systemctl --failed

start acts immediately; enable creates the link that starts the service at boot. They are independent: a service can run without being enabled, and the reverse. reload is preferable to restart when the software re-reads its configuration without dropping connections; nginx -t must always come before a reload.

To list what is actually running:

Bash
systemctl list-units --type=service --state=running
systemctl is-enabled nginx

Create a unit for your application

An app started by hand dies when the terminal closes. A unit starts it at boot and restarts it after a crash. Create /etc/systemd/system/my-app.service:

INI
[Unit]
Description=My Node.js application
After=network.target

[Service]
Type=simple
User=app
WorkingDirectory=/srv/my-app
EnvironmentFile=/etc/my-app.env
ExecStart=/usr/bin/node /srv/my-app/index.js
Restart=on-failure
RestartSec=5
NoNewPrivileges=true

[Install]
WantedBy=multi-user.target

ExecStart requires an absolute path and does not go through a shell. EnvironmentFile must be readable by the service user, with 600 permissions if it holds secrets. Restart=on-failure avoids restarting a service that exits cleanly in a loop.

Then enable it:

Bash
sudo systemctl daemon-reload
sudo systemctl enable --now my-app
sudo systemctl status my-app

daemon-reload is mandatory after any unit change.

Read state and logs

Bash
systemctl status my-app --no-pager
journalctl -u my-app -f
journalctl -u my-app --since "30 min ago" -p err

status shows the exit code, main PID and last lines. An activating (auto-restart) state means a restart loop: read the lines just before the failure. After a fix, sudo systemctl reset-failed my-app clears the failure counter.

Best practices

  • Do not edit units shipped by packages. Use sudo systemctl edit nginx to create an override in /etc/systemd/system/nginx.service.d/.
  • Use systemctl mask instead of disable to prevent a service from starting, even as a dependency.
  • After a change, test a full VPS reboot and check systemctl --failed.

Verify

Bash
systemctl is-active my-app
systemctl is-enabled my-app
systemctl show -p MainPID -p Restart my-app

is-active must answer active, is-enabled must answer enabled, and the PID must change after a restart. If the service keeps restarting, look for the error in journalctl -u my-app -n 100 before changing the unit.

Advertisement

Was this article helpful?

Read next