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 -lAs linhas que importam, na ordem:
Loaded:— diz se a unit foi encontrada e se está habilitada no boot. UmLoaded: not-foundsignifica que o nome está errado ou o arquivo.servicenunca 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 dostatus.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-pagerTrê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 novoO 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ódigo | Causa mais comum |
|---|---|
| 1 | erro genérico da aplicação: leia o journal |
| 2 | erro de uso ou de sintaxe do próprio binário |
| 126 | arquivo encontrado mas sem permissão de execução |
| 127 | binário não encontrado: caminho errado no ExecStart |
| 203 | o systemd não conseguiu executar o ExecStart |
| 209 | falha 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 :80Se 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/nginxEm 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/nullSe 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=5sCorrigir "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 oExecStart. 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 exigirPIDFile=.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 comRemainAfterExit=yesse 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 nginxEsquecer 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 desconhecidaE, 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 nginxSe 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.