---
title: "How to create a systemd service on Linux to run any app | StreetHosting"
description: "Turn a Node, Python or Go app into a systemd service on your VPS: the .service file, auto restarts, environment variables, journalctl logs and common errors."
url: "https://streethosting.com.br/en/guides/vps/create-systemd-service-linux"
type: "page"
language: "en-US"
---

VPS · 9 min · Intermediate

Published on Nov 13, 2026 · Updated on Nov 13, 2026

# How to create a systemd service on Linux and keep your app always running

A systemd service starts your app with the server, restarts it when it crashes and keeps its logs. See the full .service file, the daily commands and the errors that trip up most first timers.

By [Equipe StreetHosting](https://streethosting.com.br/en/autores#equipe-streethosting) · StreetHosting infrastructure and support team

[Linux administration](https://streethosting.com.br/en/guides/topics/linux) [Deploying and running apps](https://streethosting.com.br/en/guides/topics/deploy) [Monitoring and alerts](https://streethosting.com.br/en/guides/topics/monitoring) [Costs, plans and billing](https://streethosting.com.br/en/guides/topics/costs)

Summarize with:

[](https://chat.openai.com/?q=Summarize%20the%20key%20points%20of%20this%20StreetHosting%20guide%3A%20https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fvps%2Fcreate-systemd-service-linux.%20Highlight%20the%20step-by-step%20instructions%2C%20the%20prerequisites%20and%20the%20most%20common%20mistakes. "ChatGPT") [](https://claude.ai/new?q=Summarize%20the%20key%20points%20of%20this%20StreetHosting%20guide%3A%20https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fvps%2Fcreate-systemd-service-linux.%20Highlight%20the%20step-by-step%20instructions%2C%20the%20prerequisites%20and%20the%20most%20common%20mistakes. "Claude") [](https://www.google.com/search?udm=50&aep=11&q=Summarize%20the%20key%20points%20of%20this%20StreetHosting%20guide%3A%20https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fvps%2Fcreate-systemd-service-linux.%20Highlight%20the%20step-by-step%20instructions%2C%20the%20prerequisites%20and%20the%20most%20common%20mistakes. "Google AI Mode") [](https://x.com/i/grok?text=Summarize%20the%20key%20points%20of%20this%20StreetHosting%20guide%3A%20https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fvps%2Fcreate-systemd-service-linux.%20Highlight%20the%20step-by-step%20instructions%2C%20the%20prerequisites%20and%20the%20most%20common%20mistakes. "Grok") [](https://www.perplexity.ai/search/new?q=Summarize%20the%20key%20points%20of%20this%20StreetHosting%20guide%3A%20https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fvps%2Fcreate-systemd-service-linux.%20Highlight%20the%20step-by-step%20instructions%2C%20the%20prerequisites%20and%20the%20most%20common%20mistakes. "Perplexity")

Share:

[](https://x.com/intent/tweet?text=How%20to%20create%20a%20systemd%20service%20on%20Linux%20to%20run%20any%20app&url=https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fvps%2Fcreate-systemd-service-linux "Share on X") [](https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fvps%2Fcreate-systemd-service-linux "Share on Facebook") [](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fvps%2Fcreate-systemd-service-linux "Share on LinkedIn") [](https://wa.me/?text=How%20to%20create%20a%20systemd%20service%20on%20Linux%20to%20run%20any%20app%20https%3A%2F%2Fstreethosting.com.br%2Fen%2Fguides%2Fvps%2Fcreate-systemd-service-linux "Share on WhatsApp")

For agents: Copy as Markdown [.md](https://streethosting.com.br/en/guides/vps/create-systemd-service-linux.md)

In this guide 7 sections

* [What systemd does for you](https://streethosting.com.br/en/guides/vps/create-systemd-service-linux#o-que-e)
* [The .service file](https://streethosting.com.br/en/guides/vps/create-systemd-service-linux#arquivo)
* [Enable and check](https://streethosting.com.br/en/guides/vps/create-systemd-service-linux#ativar)
* [Logs with journalctl](https://streethosting.com.br/en/guides/vps/create-systemd-service-linux#logs)
* [Environment variables](https://streethosting.com.br/en/guides/vps/create-systemd-service-linux#variaveis)
* [Common errors](https://streethosting.com.br/en/guides/vps/create-systemd-service-linux#erros)
* [Where to run it](https://streethosting.com.br/en/guides/vps/create-systemd-service-linux#onde-rodar)

Quick answer

To run an app as a service, create the file `/etc/systemd/system/app.service` with the Unit, Service and Install sections, point `ExecStart` at the absolute path of the command and use `Restart=on-failure`. Then run `sudo systemctl daemon-reload` and `sudo systemctl enable --now app`. The app starts at boot, restarts when it crashes and has its logs in `journalctl -u app -f`.

## What systemd does for you[](https://streethosting.com.br/en/guides/vps/create-systemd-service-linux#o-que-e)

When you run an app straight from an SSH terminal, it dies as soon as the session closes and does not come back if the VPS reboots. systemd is the Linux process manager: it starts everything in the right order during boot and keeps an eye on what is running. Turning your app into a service gives it that same treatment.

In practice, a service brings four advantages:

* **Automatic start:** the app comes up on its own when the VPS powers on or reboots, with nobody opening a terminal.
* **Restart after a crash:** if the process exits with an error, systemd starts it again after a few seconds.
* **Centralized logs:** everything the app writes to standard output and standard error goes to the journal, with no log file for you to create.
* **One set of commands:** start, stop, restart and status work the same for Node, Python, Go or any binary.

If your app is Node and you already use PM2, the guide on [PM2 with startup on systemd](https://streethosting.com.br/en/guides/vps/pm2-vs-systemd-nodejs) shows how the two work together. For everything else, a direct service is simpler and has one less piece that can break.

## The .service file[](https://streethosting.com.br/en/guides/vps/create-systemd-service-linux#arquivo)

Before the file, create a user just for the app, without administrator privileges. The steps are in [creating a user on your VPS](https://streethosting.com.br/en/guides/vps/create-sudo-user-linux-vps). Here we will assume a user called **app** and the code in **/home/app/meuapp**.

Create the file with `sudo nano /etc/systemd/system/app.service` and paste this content, adjusting the paths:

`[Unit] Description=Meu app em Node After=network-online.target Wants=network-online.target StartLimitIntervalSec=60 StartLimitBurst=5 [Service] Type=simple User=app Group=app WorkingDirectory=/home/app/meuapp EnvironmentFile=/etc/meuapp/app.env ExecStart=/usr/bin/node /home/app/meuapp/index.js Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target`

What each line does:

* **Description:** the text shown in the status and in the logs. Write something you will still recognize six months from now.
* **After and Wants with network-online.target:** systemd waits for the network to be up before starting the app. It matters if you connect to a database or an API right at launch.
* **StartLimitIntervalSec and StartLimitBurst:** if the service has to be started more than 5 times in 60 seconds, systemd gives up and marks it as failed instead of restarting it forever.
* **User and Group:** who runs the process. Never leave it as root without a reason.
* **WorkingDirectory:** the folder where the app runs, the same one you would `cd` into before starting it. Relative paths inside the app start from here.
* **EnvironmentFile:** a file with the environment variables, one per line. Details in the section on variables.
* **ExecStart:** the command that starts the app, always with the absolute path of the executable.
* **Restart=on-failure and RestartSec:** restarts when the process exits with an error or is killed by a signal, waiting 5 seconds between attempts. A clean stop, such as a manual stop, does not trigger a restart.
* **WantedBy=multi-user.target:**this is what the enable command uses to turn the service on in the server's normal boot.

For other languages only the ExecStart line changes. Find the real path of each executable with `command -v`:

`# Node installed through apt or NodeSource ExecStart=/usr/bin/node /home/app/meuapp/index.js # Python inside a virtual environment ExecStart=/home/app/meuapp/venv/bin/python /home/app/meuapp/main.py # Gunicorn or Uvicorn inside the venv ExecStart=/home/app/meuapp/venv/bin/gunicorn --bind 127.0.0.1:8000 projeto.wsgi # Go binary already compiled ExecStart=/home/app/meuapp/servidor --porta 8080`

In Python, point straight at the executable inside the venv. That way you do not need to activate the virtual environment: the venv interpreter already sees the libraries installed in it.

## Enable and check[](https://streethosting.com.br/en/guides/vps/create-systemd-service-linux#ativar)

With the file saved, tell systemd there is a new service, turn on start at boot and start it now:

`sudo systemctl daemon-reload sudo systemctl enable --now app sudo systemctl status app`

In the status, look for the line `Active: active (running)` in green. If you see `failed` or `activating (auto-restart)`, the app is crashing right after it starts and the answer is in the logs.

The daily commands:

1. `sudo systemctl restart app`: restarts after you update the code.
2. `sudo systemctl stop app` and `start`: stops and starts it manually.
3. `sudo systemctl disable app`: takes the service out of boot, without stopping what is running.
4. `systemctl cat app`: shows the file systemd is actually using.

Every time you edit the .service file, run `sudo systemctl daemon-reload` before the restart. Without it systemd keeps the old version in memory and it looks like your change did nothing.

## Logs with journalctl[](https://streethosting.com.br/en/guides/vps/create-systemd-service-linux#logs)

systemd captures everything the app prints and stores it in the journal. You read it with journalctl, filtering by the service name:

`# follow live journalctl -u app -f # last 100 lines journalctl -u app -n 100 --no-pager # only what happened since the last boot journalctl -u app -b # since one hour ago journalctl -u app --since "1 hour ago"`

If your regular user cannot see the logs, run it with `sudo` or add the user to the `systemd-journal` group. To dig into the server's other log files, the guide on [analyzing logs on your VPS](https://streethosting.com.br/en/guides/vps/analyze-linux-vps-logs) covers what journalctl does not reach.

## Environment variables[](https://streethosting.com.br/en/guides/vps/create-systemd-service-linux#variaveis)

Tokens, database passwords and API keys should not live in the code or in the .service file, which any user on the system can read. The right way is the `EnvironmentFile`, a plain file in the KEY=value format, with no required quotes and without the word export:

`sudo mkdir -p /etc/meuapp sudo nano /etc/meuapp/app.env # file content: NODE_ENV=production PORT=3000 DATABASE_URL=postgres://usuario:senha@127.0.0.1:5432/meuapp # only root reads and writes sudo chmod 600 /etc/meuapp/app.env sudo chown root:root /etc/meuapp/app.env`

systemd reads this file as root before switching to the service user, so the app receives the variables even though it cannot open the file. For small values with no secret you can use `Environment=PORT=3000` directly in the .service. After changing any variable, restart the service.

## Common errors[](https://streethosting.com.br/en/guides/vps/create-systemd-service-linux#erros)

Almost every service that fails the first time falls into one of these situations. The exit code shown by the status already says a lot.

* **Executable without a full path:** systemd does not use the PATH of your terminal. With a bare name, as in `ExecStart=node index.js`, it only looks in a few fixed system folders, such as /usr/bin and /usr/local/bin. Anything outside them, like a venv or the project folder, fails with `status=203/EXEC`. Always use the full path of the executable and the script.
* **Node installed with nvm:** nvm only exists inside your shell and systemd does not load your profile. ExecStart has to point at the exact binary, something like `/home/app/.nvm/versions/node/v22.11.0/bin/node`. Run `command -v node` logged in as the service user to see the real path. If you would rather not pin a version in the file, you can install Node through apt, as the guide on [Node and nvm on your VPS](https://streethosting.com.br/en/guides/vps/install-nodejs-nvm-vps) explains.
* **Permission denied:** the service user must be able to enter the folder and read the files. If you created the code as root, run `sudo chown -R app:app /home/app/meuapp`. Binaries also need execute permission, with `chmod +x`.
* **status=200/CHDIR:** the WorkingDirectory folder does not exist or the user cannot enter it.
* **status=217/USER:** the user written in User= does not exist on the system. Check the spelling.
* **Port already in use:** the app starts and crashes with an address in use error. There is probably still a copy running from a manual test. Find it with `sudo ss -tlnp` and stop it.
* **Port below 1024 without root:** a regular user cannot open 80 or 443. Keep the app on a high port, such as 3000, and put Nginx in front of it, as in the guide on [a reverse proxy with Nginx](https://streethosting.com.br/en/guides/vps/nginx-reverse-proxy-vps).

When the cause is not clear, run the same ExecStart command by hand, logged in as the service user, and read the full error message. If it works for your user and not for the service, the problem is almost always an environment variable or a permission.

## Where to run it[](https://streethosting.com.br/en/guides/vps/create-systemd-service-linux#onde-rodar)

Creating services takes root access to write into `/etc/systemd/system`, which shared hosting does not give you. On [StreetHosting VPS](https://streethosting.com.br/en/vps) the virtualization is KVM, with its own kernel and root access, so systemd works like on any Linux server.

* **Several small services:** the Xeon VPS, from R$ 26.00 per month, has 2 vCPU, 2 GB of RAM and 20 GB of NVMe, enough for an API, a bot and a worker running as services.
* **Heavier app:** the [Ryzen 9 9950X VPS](https://streethosting.com.br/en/vps/ryzen) starts at R$ 43.00 per month, with 1 vCPU and 2 GB of DDR5, and goes up to 64 GB of RAM.

All of them are in São Paulo, with AntiDDoS included, up to 5 TB of traffic per month and activation in about 60 seconds after Pix or card approval.

In this guide

* [What systemd does for you](https://streethosting.com.br/en/guides/vps/create-systemd-service-linux#o-que-e)
* [The .service file](https://streethosting.com.br/en/guides/vps/create-systemd-service-linux#arquivo)
* [Enable and check](https://streethosting.com.br/en/guides/vps/create-systemd-service-linux#ativar)
* [Logs with journalctl](https://streethosting.com.br/en/guides/vps/create-systemd-service-linux#logs)
* [Environment variables](https://streethosting.com.br/en/guides/vps/create-systemd-service-linux#variaveis)
* [Common errors](https://streethosting.com.br/en/guides/vps/create-systemd-service-linux#erros)
* [Where to run it](https://streethosting.com.br/en/guides/vps/create-systemd-service-linux#onde-rodar)

## Frequently asked questions

What is the difference between systemd and PM2?

systemd ships with Ubuntu and Debian, works for any language and is what starts everything at boot. PM2 was built for Node, depends on Node being installed and needs systemd itself to come back after a reboot. For a single app, plain systemd is usually enough.

Do I need to run the service as root?

No, and it is better to avoid it. Create a regular user just for the app and set User= in the file. If the app is ever compromised, the damage stays limited to what that user can see.

What does the status=203/EXEC error mean?

systemd could not execute the ExecStart command. The usual causes are a wrong path, an executable systemd cannot find on its own, a file without execute permission, or an interpreter that is not where you said it was. Check the exact path with ls -l.

How do I apply a change to the .service file?

Run sudo systemctl daemon-reload so systemd rereads the file, then sudo systemctl restart name. Without daemon-reload the service keeps running with the old settings.

Does the service come back after the VPS reboots?

It does if you ran systemctl enable. The enable command turns on start at boot and start turns it on right now. That is why the enable --now shortcut does both at once.

Next step

See VPS plans

Root VPS in Brazil with NVMe and Anti-DDoS.

[See VPS plans](https://streethosting.com.br/en/vps)

[See Ryzen VPS Ryzen 9 9950X VPS in São Paulo with root access, NVMe and gamer Anti-DDoS.](https://streethosting.com.br/en/vps/ryzen)

## Related guides

[VPS Intermediate PM2 vs systemd: keep your Node app always online on a VPS Your app needs to come back on its own after a crash and start together with the VPS. PM2 and systemd solve this in different ways. Here is how to set up each one and which to pick. 3 min Read guide](https://streethosting.com.br/en/guides/vps/pm2-vs-systemd-nodejs) [VPS Beginner tmux on a VPS: how to keep a process running after you close SSH Closing the terminal kills whatever was running in it. tmux keeps the session alive on the server, and you come back to it whenever you want. See the steps, the alternatives and the point where a service is the right answer. 7 min Read guide](https://streethosting.com.br/en/guides/vps/tmux-keep-process-running-ssh) [VPS Intermediate How to analyze Linux VPS logs with journalctl and grep Almost every server problem leaves a trace in some log. See where each record lives on Ubuntu, how to slice by service, time and severity, and how to keep logs from filling the disk. 9 min Read guide](https://streethosting.com.br/en/guides/vps/analyze-linux-vps-logs)

[← Back to the Guide Center](https://streethosting.com.br/en/guides)
