---
title: "Como criar um serviço systemd no Linux para rodar qualquer app"
description: "Transforme um app Node, Python ou Go em serviço systemd na VPS: arquivo .service, reinício sozinho, variáveis de ambiente, logs com journalctl e erros comuns."
url: "https://streethosting.com.br/guias/vps/criar-servico-systemd-linux"
category: "vps"
slug: "criar-servico-systemd-linux"
datePublished: "2026-11-13"
dateModified: "2026-11-13"
author: "Equipe StreetHosting"
difficulty: "intermediario"
language: "pt-BR"
keywords:
  - "criar servico systemd"
  - "systemd service linux"
  - "systemctl enable now"
  - "journalctl logs servico"
  - "rodar app em segundo plano vps"
  - "systemd node python"
---

# Como criar um serviço systemd no Linux e manter seu app sempre no ar

Um serviço systemd inicia seu app junto com o servidor, reinicia quando ele cai e guarda os logs. Veja o arquivo .service completo, os comandos do dia a dia e os erros que mais travam quem faz isso pela primeira vez.

> **Resposta rápida**
>
> Para rodar um app como serviço, crie o arquivo `/etc/systemd/system/app.service` com as seções Unit, Service e Install, aponte o `ExecStart` para o caminho absoluto do comando e use `Restart=on-failure`. Depois rode `sudo systemctl daemon-reload` e `sudo systemctl enable --now app`. O app passa a subir no boot, reinicia quando cai e tem logs em `journalctl -u app -f`.

## O que o systemd faz por você

Quando você roda um app direto no terminal SSH, ele morre assim que a sessão fecha e não volta se a VPS reiniciar. O systemd é o gerenciador de processos do Linux: ele inicia tudo na ordem certa durante o boot e fica de olho no que está rodando. Transformar seu app em um serviço dá a ele esse mesmo tratamento.

Na prática, um serviço traz quatro vantagens:

- **Início automático:** o app sobe sozinho quando a VPS liga ou reinicia, sem ninguém abrir o terminal.
- **Reinício em caso de queda:** se o processo encerra com erro, o systemd sobe de novo depois de alguns segundos.
- **Logs centralizados:** tudo o que o app escreve na saída padrão e na saída de erro vai para o journal, sem você criar arquivo de log.
- **Um comando só para controlar:** start, stop, restart e status funcionam igual para Node, Python, Go ou qualquer binário.

Se o seu app é Node e você já usa PM2, o guia de [PM2 com startup no systemd](https://streethosting.com.br/guias/vps/configurar-pm2-startup-systemd-vps) mostra como os dois trabalham juntos. Para os demais casos, o serviço direto é mais simples e tem uma peça a menos para dar problema.

## O arquivo .service

Antes do arquivo, crie um usuário só para o app, sem privilégio de administrador. O passo a passo para isso está em [criar um usuário na VPS](https://streethosting.com.br/guias/vps/criar-usuario-sudo-vps-linux). Aqui vamos supor um usuário chamado **app** e o código em **/home/app/meuapp**.

Crie o arquivo com `sudo nano /etc/systemd/system/app.service` e cole este conteúdo, ajustando os caminhos:

```
[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
```

O que cada linha faz:

- **Description:** o texto que aparece no status e nos logs. Escreva algo que você reconheça daqui a seis meses.
- **After e Wants com network-online.target:** o systemd espera a rede estar de pé antes de iniciar o app. Importa para quem conecta em banco de dados ou API logo na largada.
- **StartLimitIntervalSec e StartLimitBurst:** se o serviço precisar ser iniciado mais de 5 vezes em 60 segundos, o systemd desiste e marca como falho em vez de ficar reiniciando para sempre.
- **User e Group:** quem executa o processo. Nunca deixe como root sem necessidade.
- **WorkingDirectory:** a pasta onde o app roda, a mesma em que você faria `cd` antes de iniciar. Caminhos relativos dentro do app partem dela.
- **EnvironmentFile:** arquivo com as variáveis de ambiente, uma por linha. Detalhes na seção sobre variáveis.
- **ExecStart:** o comando que inicia o app, sempre com o caminho absoluto do executável.
- **Restart=on-failure e RestartSec:** reinicia quando o processo sai com erro ou é morto por sinal, esperando 5 segundos entre as tentativas. Uma parada limpa, como um stop manual, não dispara reinício.
- **WantedBy=multi-user.target:** é o que o comando enable usa para ligar o serviço no boot normal do servidor.

Para outras linguagens muda só a linha do ExecStart. Descubra o caminho real de cada executável com `command -v`:

```
# Node instalado pelo apt ou pelo NodeSource
ExecStart=/usr/bin/node /home/app/meuapp/index.js

# Python dentro de um ambiente virtual
ExecStart=/home/app/meuapp/venv/bin/python /home/app/meuapp/main.py

# Gunicorn ou Uvicorn dentro do venv
ExecStart=/home/app/meuapp/venv/bin/gunicorn --bind 127.0.0.1:8000 projeto.wsgi

# Binário Go já compilado
ExecStart=/home/app/meuapp/servidor --porta 8080
```

> **Dica**
>
> Em Python, aponte direto para o executável dentro do venv. Assim você não precisa ativar o ambiente virtual: o interpretador do venv já enxerga as bibliotecas instaladas nele.

## Ativar e conferir

Com o arquivo salvo, avise o systemd que existe um serviço novo, ligue o início no boot e inicie agora:

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

No status, procure a linha `Active: active (running)` em verde. Se aparecer `failed` ou `activating (auto-restart)`, o app está caindo logo depois de subir e a resposta está nos logs.

Os comandos do dia a dia:

1. `sudo systemctl restart app`: reinicia depois de atualizar o código.
2. `sudo systemctl stop app` e `start`: para e inicia manualmente.
3. `sudo systemctl disable app`: tira o serviço do boot, sem parar o que está rodando.
4. `systemctl cat app`: mostra o arquivo que o systemd realmente está usando.

> **Atenção**
>
> Toda vez que você editar o arquivo .service, rode `sudo systemctl daemon-reload` antes do restart. Sem isso o systemd continua com a versão antiga na memória e parece que a mudança não fez efeito.

## Logs com journalctl

O systemd captura tudo o que o app escreve na tela e guarda no journal. Você lê com o journalctl, filtrando pelo nome do serviço:

```
# acompanhar ao vivo
journalctl -u app -f

# últimas 100 linhas
journalctl -u app -n 100 --no-pager

# só o que aconteceu desde o último boot
journalctl -u app -b

# desde uma hora atrás
journalctl -u app --since "1 hour ago"
```

Se o seu usuário comum não vê os logs, rode com `sudo` ou adicione o usuário ao grupo `systemd-journal`. Para investigar outros arquivos de log do servidor, o guia de [análise de logs na VPS](https://streethosting.com.br/guias/vps/analisar-logs-vps-linux) cobre a parte que o journalctl não alcança.

## Variáveis de ambiente

Tokens, senhas de banco e chaves de API não devem ficar dentro do código nem dentro do arquivo .service, que qualquer usuário do sistema consegue ler. O caminho certo é o `EnvironmentFile`, um arquivo simples no formato CHAVE=valor, sem aspas obrigatórias e sem a palavra export:

```
sudo mkdir -p /etc/meuapp
sudo nano /etc/meuapp/app.env

# conteúdo do arquivo:
NODE_ENV=production
PORT=3000
DATABASE_URL=postgres://usuario:senha@127.0.0.1:5432/meuapp

# só o root lê e escreve
sudo chmod 600 /etc/meuapp/app.env
sudo chown root:root /etc/meuapp/app.env
```

O systemd lê esse arquivo como root antes de trocar para o usuário do serviço, então o app recebe as variáveis mesmo sem poder abrir o arquivo. Para valores pequenos e sem segredo você pode usar `Environment=PORT=3000` direto no .service. Depois de mudar qualquer variável, reinicie o serviço.

## Erros comuns

Quase todo serviço que falha na primeira vez cai em uma destas situações. O código de saída que o status mostra já diz muito.

- **Executável sem caminho completo:** o systemd não usa o PATH do seu terminal. Com um nome curto, como em `ExecStart=node index.js`, ele só procura em algumas pastas fixas do sistema, como /usr/bin e /usr/local/bin. Tudo o que está fora delas, como um venv ou a pasta do projeto, falha com `status=203/EXEC`. Use sempre o caminho completo do executável e do script.
- **Node instalado com nvm:** o nvm só existe dentro do seu shell e o systemd não carrega o seu perfil. O ExecStart precisa apontar para o binário exato, algo como `/home/app/.nvm/versions/node/v22.11.0/bin/node`. Rode `command -v node` logado como o usuário do serviço para ver o caminho real. Quem não quer fixar versão no arquivo pode instalar o Node pelo apt, como mostra o guia de [Node e nvm na VPS](https://streethosting.com.br/guias/vps/instalar-node-nvm-vps).
- **Permissão negada:** o usuário do serviço precisa conseguir entrar na pasta e ler os arquivos. Se você criou o código como root, rode `sudo chown -R app:app /home/app/meuapp`. Binários também precisam de permissão de execução, com `chmod +x`.
- **status=200/CHDIR:** a pasta do WorkingDirectory não existe ou o usuário não consegue entrar nela.
- **status=217/USER:** o usuário escrito em User= não existe no sistema. Confira a grafia.
- **Porta já em uso:** o app sobe e cai com erro de endereço em uso. Provavelmente ainda há uma cópia rodando de um teste manual. Ache com `sudo ss -tlnp` e encerre.
- **Porta abaixo de 1024 sem ser root:** um usuário comum não abre a 80 nem a 443. Deixe o app em uma porta alta, como 3000, e coloque o Nginx na frente, como no guia de [reverse proxy com Nginx](https://streethosting.com.br/guias/vps/configurar-nginx-reverse-proxy-vps).

Quando o motivo não está claro, rode o mesmo comando do ExecStart manualmente, logado como o usuário do serviço, e veja a mensagem de erro completa. Se funciona no seu usuário e não no serviço, o problema quase sempre é variável de ambiente ou permissão.

## Onde rodar

Criar serviços exige acesso root para escrever em `/etc/systemd/system`, coisa que hospedagem compartilhada não dá. Nas [VPS da StreetHosting](https://streethosting.com.br/vps) a virtualização é KVM, com kernel próprio e acesso root, então o systemd funciona como em qualquer servidor Linux.

- **Vários serviços pequenos:** a VPS Xeon, a partir de R$ 26,00 por mês, tem 2 vCPU, 2 GB de RAM e 20 GB NVMe, o bastante para uma API, um bot e um worker rodando como serviços.
- **App mais pesado:** a [VPS Ryzen 9 9950X](https://streethosting.com.br/vps/ryzen) começa em R$ 43,00 por mês, com 1 vCPU e 2 GB DDR5, e chega a 64 GB de RAM.

Todas ficam em São Paulo, com AntiDDoS incluso, até 5 TB de tráfego por mês e ativação em cerca de 60 segundos depois do Pix ou do cartão aprovado.

## Perguntas frequentes

### Qual a diferença entre systemd e PM2?

O systemd já vem no Ubuntu e no Debian, serve para qualquer linguagem e é quem inicia tudo no boot. O PM2 nasceu para Node, depende do Node instalado e precisa do próprio systemd para voltar depois de um reinício. Para um app isolado, o systemd puro costuma bastar.

### Preciso rodar o serviço como root?

Não, e é melhor evitar. Crie um usuário comum só para o app e use User= no arquivo. Se o app for invadido, o estrago fica limitado ao que esse usuário enxerga.

### O que significa o erro status=203/EXEC?

O systemd não conseguiu executar o comando do ExecStart. As causas mais comuns são um caminho errado, um executável que o systemd não acha sozinho, um arquivo sem permissão de execução ou um interpretador que não está onde você disse. Confira com ls -l no caminho exato.

### Como aplicar uma mudança no arquivo .service?

Rode sudo systemctl daemon-reload para o systemd reler o arquivo e depois sudo systemctl restart nome. Sem o daemon-reload o serviço continua com a versão antiga das configurações.

### O serviço volta sozinho depois de reiniciar a VPS?

Volta se você rodou systemctl enable. O comando enable liga o início no boot e o start liga agora. Por isso o atalho enable --now faz as duas coisas de uma vez.

## Guias relacionados

- [PM2 ou systemd: manter sua aplicação Node sempre online na VPS](https://streethosting.com.br/guias/vps/configurar-pm2-startup-systemd-vps.md)
- [tmux na VPS: como manter um processo rodando depois de fechar o SSH](https://streethosting.com.br/guias/vps/tmux-manter-processo-rodando-ssh.md)
- [Como analisar logs de uma VPS Linux com journalctl e grep](https://streethosting.com.br/guias/vps/analisar-logs-vps-linux.md)
- [Como criar um usuário com sudo na VPS Linux](https://streethosting.com.br/guias/vps/criar-usuario-sudo-vps-linux.md)
- [Como instalar o Node na VPS com o nvm e gerenciar versões](https://streethosting.com.br/guias/vps/instalar-node-nvm-vps.md)

## Produtos citados

- https://streethosting.com.br/vps
- https://streethosting.com.br/vps/ryzen

## Dados estruturados

```json
[
  {
    "@context": "https://schema.org",
    "@type": [
      "Article",
      "TechArticle"
    ],
    "headline": "Como criar um serviço systemd no Linux e manter seu app sempre no ar",
    "name": "Como criar um serviço systemd no Linux para rodar qualquer app",
    "abstract": "Um serviço systemd inicia seu app junto com o servidor, reinicia quando ele cai e guarda os logs. Veja o arquivo .service completo, os comandos do dia a dia e os erros que mais travam quem faz isso pela primeira vez.",
    "description": "Transforme um app Node, Python ou Go em serviço systemd na VPS: arquivo .service, reinício sozinho, variáveis de ambiente, logs com journalctl e erros comuns.",
    "datePublished": "2026-11-13",
    "dateModified": "2026-11-13",
    "author": {
      "@type": "Organization",
      "name": "Equipe StreetHosting"
    },
    "publisher": {
      "@type": "Organization",
      "name": "StreetHosting",
      "url": "https://streethosting.com.br"
    },
    "inLanguage": "pt-BR",
    "mainEntityOfPage": {
      "@type": "WebPage",
      "@id": "https://streethosting.com.br/guias/vps/criar-servico-systemd-linux"
    }
  },
  {
    "@context": "https://schema.org",
    "@type": "FAQPage",
    "mainEntity": [
      {
        "@type": "Question",
        "name": "Qual a diferença entre systemd e PM2?",
        "acceptedAnswer": {
          "@type": "Answer",
          "text": "O systemd já vem no Ubuntu e no Debian, serve para qualquer linguagem e é quem inicia tudo no boot. O PM2 nasceu para Node, depende do Node instalado e precisa do próprio systemd para voltar depois de um reinício. Para um app isolado, o systemd puro costuma bastar."
        }
      },
      {
        "@type": "Question",
        "name": "Preciso rodar o serviço como root?",
        "acceptedAnswer": {
          "@type": "Answer",
          "text": "Não, e é melhor evitar. Crie um usuário comum só para o app e use User= no arquivo. Se o app for invadido, o estrago fica limitado ao que esse usuário enxerga."
        }
      },
      {
        "@type": "Question",
        "name": "O que significa o erro status=203/EXEC?",
        "acceptedAnswer": {
          "@type": "Answer",
          "text": "O systemd não conseguiu executar o comando do ExecStart. As causas mais comuns são um caminho errado, um executável que o systemd não acha sozinho, um arquivo sem permissão de execução ou um interpretador que não está onde você disse. Confira com ls -l no caminho exato."
        }
      },
      {
        "@type": "Question",
        "name": "Como aplicar uma mudança no arquivo .service?",
        "acceptedAnswer": {
          "@type": "Answer",
          "text": "Rode sudo systemctl daemon-reload para o systemd reler o arquivo e depois sudo systemctl restart nome. Sem o daemon-reload o serviço continua com a versão antiga das configurações."
        }
      },
      {
        "@type": "Question",
        "name": "O serviço volta sozinho depois de reiniciar a VPS?",
        "acceptedAnswer": {
          "@type": "Answer",
          "text": "Volta se você rodou systemctl enable. O comando enable liga o início no boot e o start liga agora. Por isso o atalho enable --now faz as duas coisas de uma vez."
        }
      }
    ]
  }
]
```
