← Voltar para o Blog

Serviço não sobe: como ler o systemd sem chutar

systemctl start voltou sem erro e o serviço continua fora. Este é o caminho que separa configuração errada de dependência faltando, de porta ocupada e de Type= incorreto.

Equipe EasyOps Cloud · · 6 min de leitura

O systemctl start volta ao prompt sem imprimir nada e o serviço continua fora do ar. Ou pior: aparece active (running) e a aplicação não responde na porta. Nos dois casos a informação existe — só não está onde a maioria olha primeiro.

Este artigo é a ordem de leitura que resolve a maior parte dos casos sem tentativa e erro.

Leia o status inteiro, não só a cor

systemctl status nginx --no-pager -l

As linhas que importam, na ordem:

  • Loaded: — diz se a unit foi encontrada e se está habilitada no boot. Um Loaded: not-found significa que o nome está errado ou o arquivo .service nunca foi lido; nesse caso nenhuma outra linha vale nada.
  • Active: — o estado e há quanto tempo. activating (auto-restart) é o sintoma clássico de serviço que sobe e morre em loop.
  • Process: — a linha de comando executada e, no fim, status= com o código de saída. É o dado mais subestimado do status.
  • Main PID: — quando aparece um PID e o serviço continua sem responder, o problema é da aplicação, não do systemd.

O status mostra só as últimas 10 linhas de log. Elas raramente contêm a causa, porque a causa costuma estar no início da tentativa de subida.

O log inteiro está no journal

journalctl -u nginx -n 100 --no-pager

Três variações que economizam tempo:

journalctl -u nginx -b            # só o boot atual
journalctl -u nginx --since "10 min ago"
journalctl -u nginx -f            # acompanhar enquanto tenta subir de novo

O padrão mais útil é abrir o -f em um terminal e dar o start em outro. Você vê a sequência exata em vez de reconstruí-la depois.

Se o journal estiver vazio para a unit, o serviço provavelmente escreve em arquivo próprio (/var/log/<serviço>/) por causa de um StandardOutput= na unit ou de configuração interna da aplicação.

O código de saída já diz quase tudo

A linha Process: ... status=N tem significados convencionais:

CódigoCausa mais comum
1erro genérico da aplicação: leia o journal
2erro de uso ou de sintaxe do próprio binário
126arquivo encontrado mas sem permissão de execução
127binário não encontrado: caminho errado no ExecStart
203o systemd não conseguiu executar o ExecStart
209falha ao aplicar StandardOutput ou similar

Os códigos 127 e 203 apontam para o mesmo erro humano: ExecStart precisa de caminho absoluto. O systemd não expande PATH como o seu shell, então ExecStart=node server.js falha mesmo com o node funcionando perfeitamente quando você digita.

As quatro causas que cobrem a maioria dos casos

Porta já ocupada

sudo ss -tlnp | grep :80

Se outro processo já segurou a porta, a aplicação sai com erro de bind. Acontece muito depois de trocar Apache por nginx sem desabilitar o primeiro, ou quando um processo antigo ficou órfão de um kill incompleto.

Permissão de arquivo ou diretório

O serviço roda com o usuário de User= na unit, não com o seu. Um diretório de socket, PID ou cache que existe para o root e não para esse usuário derruba a subida. Vale conferir quem é o dono do que a aplicação escreve:

systemctl show nginx -p User -p Group
ls -ld /run/nginx /var/lib/nginx

Em distribuição com SELinux ou AppArmor, a permissão pode estar correta no ls e ainda assim ser negada. Procure denied no journal do sistema:

sudo journalctl -k --since "10 min ago" | grep -i -E 'denied|avc'

Configuração inválida

Vários serviços validam a própria configuração sem subir. É o teste mais rápido que existe:

sudo nginx -t
sudo apachectl configtest
sudo sshd -t
sudo postconf -n > /dev/null

Se a validação passa e o serviço ainda não sobe, o problema não é sintaxe.

Ordem de dependências

Uma aplicação que precisa do banco ou de um ponto de montagem sobe antes dele e morre. After= só ordena a partida; não garante que o outro serviço já esteja pronto para aceitar conexão. Para a maioria dos casos, a solução honesta é deixar a aplicação tolerar a indisponibilidade inicial e o systemd reiniciar:

[Service]
Restart=on-failure
RestartSec=5s

Corrigir "dependência não pronta" com sleep no ExecStartPre funciona no seu teste e falha no boot da máquina, quando tudo está mais lento.

"Sobe e morre" quase sempre é o Type= errado

Este é o caso que mais consome tempo, porque nada parece errado:

  • Type=simple (padrão) — o systemd considera o serviço pronto assim que executa o ExecStart. Se o processo faz fork e o pai sai, o systemd entende que o serviço terminou e mata o resto do grupo.
  • Type=forking — para daemons que forçam segundo plano por conta própria. Costuma exigir PIDFile=.
  • Type=notify — o processo avisa o systemd quando ficou pronto. É o mais correto quando a aplicação suporta.
  • Type=oneshot — para tarefas que rodam e terminam; combine com RemainAfterExit=yes se o estado precisa continuar "ativo".

Um serviço que "inicia e imediatamente para", sem erro no log da aplicação, é Type=simple com um binário que faz fork. Muitas aplicações têm uma flag para ficar em primeiro plano (--foreground, -D, daemon off;) — usá-la com Type=simple é mais simples e mais confiável do que gerenciar PID file.

Depois de editar qualquer unit

sudo systemctl daemon-reload
sudo systemctl restart nginx
sudo systemctl enable --now nginx

Esquecer o daemon-reload faz o systemd continuar rodando a versão antiga do arquivo, e você fica depurando uma edição que o sistema nunca leu.

Duas verificações que valem o hábito:

systemctl cat nginx          # a unit efetiva, com todos os drop-ins aplicados
systemd-analyze verify nginx # aponta diretiva inválida ou desconhecida

E, para customizar um serviço que veio do pacote, use sudo systemctl edit nginx em vez de editar o arquivo em /lib/systemd/system/. O drop-in em /etc/ sobrevive à próxima atualização do pacote; a edição direta é sobrescrita sem aviso.

Quando o loop de restart trava sozinho

Com Restart= ativo, o systemd desiste depois de algumas tentativas em janela curta e o serviço fica em failed mesmo com a causa já corrigida:

systemctl reset-failed nginx
systemctl start nginx

Se o loop for frequente em produção, aumente RestartSec antes de mexer em StartLimitBurst. Reiniciar mais devagar costuma ser melhor do que reiniciar mais vezes.

Antes de mexer em serviço de produção

Alteração de unit, troca de versão e mudança de configuração de servidor web podem deixar a máquina em estado pior do que estava. Tirar um snapshot antes da mudança dá um ponto de retorno conhecido e leva menos tempo do que reconstruir a configuração de memória.

Se, depois de tudo, o serviço sobe mas continua lento, o problema deixou de ser o systemd e passou a ser recurso ou I/O — o caminho está em VPS lenta: como diagnosticar.

Suba um servidor em minutos

Preço em real, suporte em português e dados no Brasil.

Criar conta