Capítulo 8.2 - Serviços Personalizados
Objetivos de Aprendizagem
Ao final deste capítulo, você será capaz de:
- Criar um arquivo unit do systemd
- Configurar um serviço personalizado
- Compreender as seções de um unit file
- Gerenciar dependências
- Criar serviços para scripts
Estrutura de um Unit File
Localização
# Sistema
/etc/systemd/system/
# Usuário
~/.config/systemd/user/
Prioridade:
/etc/systemd/system/(sistema) >/usr/lib/systemd/system/(pacotes)
Formato Básico
[Unit]
Description=Descrição do serviço
After=network.target
[Service]
Type=simple
ExecStart=/caminho/para/comando
Restart=always
[Install]
WantedBy=multi-user.target
Seções Principais
[Unit]
[Unit]
Description=Meu Serviço Personalizado
Documentation=man:meu-servico(1)
After=network.target sshd.service
Before=some-service.service
Requires=network.target
Wants=sshd.service
Conflicts=old-service.service
Diretivas:
- Description: Descrição do serviço
- After: Inicia após estas unidades
- Before: Inicia antes destas unidades
- Requires: Dependência forte (falha se a dependência falhar)
- Wants: Dependência fraca (continua se a dependência falhar)
- Conflicts: Não pode rodar ao mesmo tempo
[Service]
[Service]
Type=simple
ExecStart=/usr/local/bin/meu-script.sh
ExecStartPre=/bin/echo "Iniciando"
ExecStartPost=/bin/echo "Iniciado"
ExecStop=/bin/echo "Parando"
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
RestartSec=10
User=meuusuario
Group=meugrupo
WorkingDirectory=/var/lib/meuservico
Environment="VAR1=valor1"
EnvironmentFile=/etc/meuservico/env
StandardOutput=journal
StandardError=journal
Tipos:
- simple: Comando principal (padrão)
- forking: Fork em background
- oneshot: Execução única
- notify: Notifica o systemd quando estiver pronto
Restart:
- no: Não reinicia
- always: Sempre reiniciar
- on-failure: Reiniciar em caso de falha
- on-success: Reiniciar em caso de sucesso
[Install]
[Install]
WantedBy=multi-user.target
Alias=meuservico.service
Targets comuns:
- multi-user.target: Modo multiusuário
- graphical.target: Modo gráfico
- default.target: Target padrão
Exemplos Práticos
Serviço Simples
# /etc/systemd/system/meu-servico.service
[Unit]
Description=Meu Serviço Simples
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/meu-script.sh
Restart=always
RestartSec=10
User=www-data
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
Ativar:
sudo systemctl daemon-reload
sudo systemctl enable meu-servico
sudo systemctl start meu-servico
Serviço com Script
#!/bin/bash
# /usr/local/bin/meu-script.sh
# Script de serviço
# Função de limpeza
cleanup() {
echo "Parando o serviço"
# Limpeza...
exit 0
}
# Trap signals
trap cleanup SIGTERM SIGINT
# Loop principal
while true; do
# Trabalho...
echo "Serviço ativo: $(date)"
sleep 60
done
Unit file:
[Unit]
Description=Serviço com Script
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/meu-script.sh
Restart=always
RestartSec=5
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
Serviço Forking
[Unit]
Description=Serviço Forking
After=network.target
[Service]
Type=forking
ExecStart=/usr/local/bin/daemon --daemonize
PIDFile=/var/run/daemon.pid
Restart=always
[Install]
WantedBy=multi-user.target
Serviço Oneshot
[Unit]
Description=Script Oneshot
After=network.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/init-script.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
Variáveis de Ambiente
No Unit File
[Service]
Environment="VAR1=valor1"
Environment="VAR2=valor2"
EnvironmentFile=/etc/meuservico/env
Arquivo de Ambiente
# /etc/meuservico/env
VAR1=valor1
VAR2=valor2
VAR3="valor com espaços"
Gerenciamento de Logs
Journal do systemd
# Ver logs do serviço
sudo journalctl -u meu-servico
# Seguir logs
sudo journalctl -u meu-servico -f
# Logs recentes
sudo journalctl -u meu-servico -n 50
# Desde data
sudo journalctl -u meu-servico --since "2024-01-01"
Redirecionamento
[Service]
# Para o journal (padrão)
StandardOutput=journal
StandardError=journal
# Para arquivo
StandardOutput=file:/var/log/meuservico.log
StandardError=file:/var/log/meuservico-error.log
# Ignorar
StandardOutput=null
StandardError=null
Boas Práticas
Estrutura
[Unit]
# Descrição clara
# Dependências apropriadas
[Service]
# Tipo correto
# User/Group não-root se possível
# Restart apropriado
# Logging configurado
[Install]
# Target apropriado
Segurança
[Service]
# Não usar root se possível
User=serviceuser
Group=servicegroup
# Limitar capacidades
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
NoNewPrivileges=true
# Chroot se possível
RootDirectory=/var/lib/meuservico
Resumo
Neste capítulo, você aprendeu:
Unit files: Estrutura [Unit], [Service], [Install]
Tipos: simple, forking, oneshot, notify
Dependências: After, Before, Requires, Wants
Restart: always, on-failure, never
Ambiente: Environment, EnvironmentFile
Logs: journalctl, redirecionamento para arquivos
Prática: Criar serviços para scripts e aplicações
Próximos Passos
Capítulo 8.3: Cron Avançado e systemd Timers
Módulo 9: Segurança de Sistema
Capítulo criado em: Dezembro 2024