EQVPS

How to create a systemd service to keep an app running

Turn any script or app into a managed service that starts on boot, restarts if it crashes, and logs to journalctl. Write a unit file, enable it, and check its status — the standard way to run something 24/7 on Linux.

Running an app with & or nohup is fine until the server reboots, the process crashes, or you want to find its logs — then it falls apart. systemd is the standard answer: it starts your app on boot, restarts it if it dies, and captures its logs. Turning a script or binary into a managed service is one small file.

1. Write a unit file

Create /etc/systemd/system/myapp.service:

[Unit]
Description=My application
After=network.target

[Service]
User=myapp
WorkingDirectory=/opt/myapp
ExecStart=/usr/bin/python3 /opt/myapp/run.py
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Adjust ExecStart, WorkingDirectory and User to your app. Restart=always is what keeps it alive.

sudo useradd --system --no-create-home --shell /usr/sbin/nologin myapp
sudo chown -R myapp:myapp /opt/myapp

Running as a non-root user limits the damage if the app is ever compromised.

3. Enable and start it

sudo systemctl daemon-reload
sudo systemctl enable --now myapp

enable makes it start on boot; --now starts it immediately.

4. Check status and logs

sudo systemctl status myapp
journalctl -u myapp -f       # follow live logs

Everyday commands

sudo systemctl restart myapp   # restart after a change
sudo systemctl stop myapp      # stop it
sudo systemctl disable myapp   # stop starting on boot

Honest cautions

Next steps

A systemd service is how you keep anything running 24/7 — for example an AI agent that runs around the clock or the relay behind a self-hosted RustDesk server. If your app is containerised instead, Docker's --restart unless-stopped plays the same role — see how to install Docker.

FAQ

Why use systemd instead of just running the app in the background?

A backgrounded process (with & or nohup) dies on reboot, doesn't come back if it crashes, and scatters its logs. A systemd service starts automatically on boot, restarts on failure, and sends its output to journalctl. It's the standard, reliable way to run something long-lived on Linux.

Where do unit files go?

Your own services go in /etc/systemd/system/, one file per service, named something.service. After creating or editing one, run 'systemctl daemon-reload' so systemd picks up the change, then enable and start it.

What does 'Restart=always' do, and are there downsides?

It tells systemd to restart the service whenever it exits, for any reason — the key to keeping something running. The one catch is a crash loop: if the app fails instantly on start, systemd keeps restarting it. Add 'RestartSec=5' to space attempts out, and check the logs to fix the underlying error.

How do I see the service's logs?

Use 'journalctl -u yourservice -f' to follow live output, or without -f to read history. systemd captures stdout and stderr automatically, so you don't need to wire up log files yourself.

Should the service run as root?

Prefer not to. Create a dedicated non-root user and set 'User=' in the unit, so a compromise of the app doesn't hand over the whole box. Run as root only when the service genuinely needs it.

Comments

No comments yet. Be the first.

Leave a comment

Comments are moderated before they appear.