SystemD - Criando e Gerenciando Serviços no Linux
Tabela de Conteúdo
O systemd é o sistema de inicialização e gerenciamento de serviços padrão na maioria das distribuições Linux modernas. Ele substituiu o antigo SysVinit e oferece recursos avançados como paralelização de inicialização, gerenciamento de dependências, controle de recursos e logging integrado.
Neste post, vamos aprender a criar e gerenciar serviços usando systemd, desde a criação de unit files até o troubleshooting de problemas.
Anatomia de um Unit File
Os unit files do systemd são arquivos de configuração em formato INI que definem como um serviço, timer, mount ou outro recurso do sistema deve ser gerenciado. As seções principais são:
- [Unit]: Metadados e dependências do serviço
- [Service]: Configurações específicas do serviço
- [Install]: Informações de instalação e ativação
Seção [Unit]
Define descrição, dependências e relacionamentos com outros serviços:
[Unit]
Description=Minha Aplicação Web
After=network.target
Wants=network.target
Diretivas comuns:
Description: Descrição do serviçoAfter: Inicia após esses serviçosBefore: Inicia antes desses serviçosRequires: Dependência obrigatória (se falhar, este serviço também falha)Wants: Dependência opcional (se falhar, este serviço continua)
Seção [Service]
Define como o serviço será executado:
[Service]
Type=simple
ExecStart=/usr/bin/minha-aplicacao
Restart=always
RestartSec=10
User=www-data
WorkingDirectory=/var/www/app
Diretivas importantes:
Type: Tipo de serviço (simple, forking, oneshot, notify)ExecStart: Comando para iniciar o serviçoExecStop: Comando para parar o serviço (opcional)Restart: Quando reiniciar (always, on-failure, never)RestartSec: Tempo de espera antes de reiniciarUser: Usuário que executa o serviçoWorkingDirectory: Diretório de trabalho
Seção [Install]
Define como o serviço será habilitado:
[Install]
WantedBy=multi-user.target
Criando Seu Primeiro Serviço
Vamos criar um exemplo prático: transformar uma aplicação Python em um serviço systemd.
Exemplo: Aplicação Python
Suponha que você tenha uma aplicação Flask rodando em /opt/myapp/app.py. Vamos criar um serviço para ela:
$ sudo nano /etc/systemd/system/myapp.service
Conteúdo do arquivo:
[Unit]
Description=Minha Aplicação Web Flask
After=network.target
[Service]
Type=simple
User=www-data
Group=www-data
WorkingDirectory=/opt/myapp
Environment="PATH=/opt/myapp/venv/bin"
ExecStart=/opt/myapp/venv/bin/python /opt/myapp/app.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
Configurações de Restart e Dependências
Controle de Restart
O Restart define quando o systemd deve reiniciar o serviço:
Restart=always # Sempre reinicia, mesmo após parada normal
Restart=on-failure # Reinicia apenas em caso de falha
Restart=on-success # Reinicia apenas após sucesso
Restart=never # Nunca reinicia automaticamente
O RestartSec define o tempo de espera antes de reiniciar:
RestartSec=10 # Espera 10 segundos
RestartSec=5s # Espera 5 segundos
RestartSec=1min # Espera 1 minuto
Dependências entre Serviços
Requires vs Wants:
# Requires: Se o serviço dependente falhar, este também falha
Requires=postgresql.service
# Wants: Se o serviço dependente falhar, este continua
Wants=redis.service
After e Before:
# Inicia após a rede estar disponível
After=network.target
# Inicia antes de outro serviço
Before=nginx.service
Gerenciando o Serviço
Após criar o unit file, recarregue o systemd e gerencie o serviço:
Recarregar Configurações
Sempre que criar ou modificar um unit file, recarregue o systemd:
$ sudo systemctl daemon-reload
Comandos Básicos
$ sudo systemctl start myapp.service
$ sudo systemctl stop myapp.service
$ sudo systemctl restart myapp.service
$ sudo systemctl reload myapp.service
$ sudo systemctl status myapp.service
Habilitar no Boot
Para que o serviço inicie automaticamente ao boot:
$ sudo systemctl enable myapp.service
$ sudo systemctl enable --now myapp.service
Verificar Status
O comando status mostra informações detalhadas:
$ sudo systemctl status myapp.service
Saída exemplo:
● myapp.service - Minha Aplicação Web Flask
Loaded: loaded (/etc/systemd/system/myapp.service; enabled)
Active: active (running) since Mon 2022-08-07 10:30:00 UTC; 5min ago
Main PID: 1234 (python)
Tasks: 1
Memory: 50.0M
CGroup: /system.slice/myapp.service
└─1234 /opt/myapp/venv/bin/python /opt/myapp/app.py
Troubleshooting com journalctl
O systemd integra logging através do journalctl. Use-o para investigar problemas:
Logs de um Serviço Específico
$ sudo journalctl -u myapp.service
$ sudo journalctl -u myapp.service -f
$ sudo journalctl -u myapp.service -n 50
Filtrar por Tempo
$ sudo journalctl -u myapp.service --since today
$ sudo journalctl -u myapp.service --since "1 hour ago"
$ sudo journalctl -u myapp.service --since "2022-08-07 10:00:00" --until "2022-08-07 11:00:00"
Validação e Debug
Antes de ativar um serviço, valide o unit file:
Verificar Sintaxe
$ sudo systemd-analyze verify /etc/systemd/system/myapp.service
Ver Configuração Completa
Para ver a configuração final (incluindo padrões do systemd):
$ sudo systemctl cat myapp.service
Ver Dependências
# Ver o que este serviço requer
$ systemctl list-dependencies myapp.service
# Ver o que requer este serviço
$ systemctl list-dependencies --reverse myapp.service
Dicas Adicionais
Variáveis de Ambiente
Você pode definir variáveis de ambiente de várias formas:
# Diretamente no unit file
Environment="VAR=valor"
# De um arquivo
EnvironmentFile=/etc/myapp/env.conf
# Múltiplas variáveis
Environment="VAR1=valor1" "VAR2=valor2"
Timers (Agendamento)
O systemd também pode agendar tarefas usando timers:
# /etc/systemd/system/backup.timer
[Unit]
Description=Backup Diário
[Timer]
OnCalendar=daily
OnBootSec=15min
[Install]
WantedBy=timers.target
Simples assim!