1. O modelo mental
Um script executado manualmente não tem reinício, identidade operacional nem histórico confiável. Uma unit systemd transforma o processo em uma unidade observável e declarativa.
2. Criando a unit
[Unit]
Description=IRN Worker
After=network-online.target
Wants=network-online.target
[Service]
User=worker
WorkingDirectory=/opt/worker
ExecStart=/opt/worker/.venv/bin/python worker.py
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable --now irn-worker
systemctl status irn-worker
journalctl -u irn-worker -f3. Diagnóstico de falhas
Comece pelo status, depois leia o journal desde o último boot. Diferencie erro de aplicação, permissão, caminho de trabalho, ambiente ausente e porta ocupada.
systemctl show irn-worker -p User -p ExecMainStatus
journalctl -u irn-worker -b --no-pager
systemctl reset-failed irn-worker4. Segurança e limites
Use usuário dedicado, caminhos absolutos, arquivos de ambiente protegidos e limites de memória conforme o risco. Nunca coloque segredos diretamente na unit versionada.
5. Checklist
- Usuário dedicado
- WorkingDirectory explícito
- Restart controlado
- Logs no journal
- Daemon recarregado após alteração
- Rollback documentado
6. Troubleshooting
Erros comuns são caminho relativo, ambiente virtual inexistente e permissões incorretas. Reproduza o comando como o mesmo usuário da unit antes de culpar o systemd. Para testar uma alteração, use systemd-analyze verify e recarregue o daemon.
sudo systemd-analyze verify /etc/systemd/system/irn-worker.service
sudo -u worker /opt/worker/.venv/bin/python /opt/worker/worker.py
7. Diretivas e comandos explicados
| Diretiva da unit | O que faz |
|---|---|
Description=IRN Worker | Texto que aparece no systemctl status. |
After=network-online.target | Inicia o serviço só depois de a rede estar disponível. |
Wants=network-online.target | Pede que a rede seja ativada junto, sem tornar isso obrigatório. |
User=worker | Executa com um usuário sem privilégios, e não como root. |
WorkingDirectory=/opt/worker | Define o diretório em que o processo começa. |
ExecStart=/opt/worker/.venv/bin/python worker.py | Comando que inicia o serviço, sempre com caminho absoluto. |
Restart=on-failure | Reinicia se o processo terminar com erro. |
RestartSec=5 | Espera 5 segundos antes de reiniciar. |
WantedBy=multi-user.target | Liga o serviço na inicialização normal do sistema. |
Valor de Restart= | Quando reinicia |
|---|---|
no | nunca |
on-failure | se sair com código de erro, por sinal ou por timeout |
always | sempre, até quando o programa termina sem erro |
| Comando | O que faz |
|---|---|
sudo systemctl daemon-reload | Faz o systemd reler as units. É obrigatório depois de criar ou editar uma. |
sudo systemctl enable --now irn-worker | Liga no boot e inicia agora. |
systemctl status irn-worker | Mostra o estado, o PID e as últimas linhas de log. |
journalctl -u irn-worker -f | Acompanha os logs em tempo real. |
systemctl show irn-worker -p User -p ExecMainStatus | Mostra propriedades específicas: o usuário efetivo e o código de saída. |
journalctl -u irn-worker -b --no-pager | Logs do boot atual, sem paginador. |
systemctl reset-failed irn-worker | Limpa o estado de falha registrado. |
systemd-analyze verify ...service | Verifica a sintaxe da unit. |
sudo -u worker ... worker.py | Reproduz o comando como o mesmo usuário do serviço, para descobrir erros de permissão. |
8. Exemplo: como fica o status de um serviço saudável
A saída abaixo é ilustrativa e muda conforme a versão do systemd:
● irn-worker.service - IRN Worker
Loaded: loaded (/etc/systemd/system/irn-worker.service; enabled)
Active: active (running) since Sun 2026-09-20 10:02:11 -03; 5min ago
Main PID: 1234 (python)enabled indica que sobe no boot, active (running) que está rodando agora, e o Main PID é o processo principal.
9. Códigos de erro mais comuns
| Mensagem | Causa provável | Solução |
|---|---|---|
status=203/EXEC | O ExecStart aponta para um caminho que não existe ou sem permissão de execução. | Confira o caminho absoluto, o ambiente virtual e o chmod +x. |
status=200/CHDIR | O WorkingDirectory não existe. | Crie o diretório ou corrija o caminho. |
status=217/USER | O usuário definido em User= não existe. | Crie o usuário com adduser ou useradd. |
| A alteração na unit não tem efeito | Faltou o daemon-reload. | Rode sudo systemctl daemon-reload e reinicie o serviço. |
start request repeated too quickly | O serviço falha logo ao iniciar e o systemd desiste de reiniciar. | Corrija a causa no log e rode reset-failed. |