Como usar systemd para iniciar um serviço Linux na inicialização
Garantir que os serviços críticos iniciem automaticamente quando o servidor reinicia é uma das responsabilidades mais fundamentais de qualquer administrador de sistemas Linux. Quer esteja a executar uma aplicação web, um motor de base de dados ou um daemon personalizado num ambiente de VPS Hosting, uma reinicialização inesperada nunca deve significar tempo de inatividade prolongado. Com systemd — o moderno sistema init que alimenta a maioria das distribuições Linux atuais — pode definir precisamente como, quando e como qual utilizador os seus serviços são iniciados, tudo através de um ficheiro de unidade limpo e declarativo.
Este guia abrangente o orienta em cada etapa: compreender o que é systemd, criar um ficheiro de unidade de serviço pronto para produção, verificar permissões, testar o seu executável e gerir o ciclo de vida do serviço. No final, a sua aplicação personalizada sobreviverá a cada reinicialização automaticamente.
O que é systemd e por que é importante?
systemd é um sistema init e gestor de serviços que substituiu alternativas mais antigas como SysVinit e Upstart em praticamente todas as principais distribuições Linux, incluindo Ubuntu, Debian, CentOS, Rocky Linux, AlmaLinux e Fedora. Em vez de executar uma cadeia sequencial de scripts de shell no arranque, systemd paraleliza o arranque do serviço, resolve a ordenação de dependências e gere todo o ciclo de vida dos processos do sistema a partir de uma única interface unificada.
Principais vantagens do systemd para ambientes de servidor
| Funcionalidade | Benefício |
|---|---|
| Arranque paralelo de serviços | Tempos de arranque mais rápidos em servidores com múltiplos serviços |
| Gestão de dependências | Os serviços iniciam apenas após os seus pré-requisitos estarem prontos |
| Políticas de reinício automático | Os serviços falhados recuperam sem intervenção manual |
| Registo centralizado via journald | Toda a saída do serviço é capturada num diário consultável |
| Controlo de recursos baseado em cgroup | Limites de CPU e memória aplicados por serviço |
| Ativação de socket e dispositivo | Os serviços iniciam sob demanda, não incondicionalmente |
Para qualquer pessoa que gerencie aplicações em Servidores Dedicados ou instâncias VPS, estas capacidades traduzem-se diretamente em maior tempo de atividade e comportamento mais previsível sob carga.
Compreender ficheiros de unidade systemd
Tudo o que systemd gere é representado por um ficheiro de unidade — um ficheiro de configuração em texto simples dividido em secções. Um ficheiro de unidade .service diz ao systemd:
- O que é o serviço (metadados, descrição, dependências)
- Como executá-lo (caminho do executável, diretório de trabalho, contexto do utilizador)
- Quando iniciá-lo (alvo de arranque, ordenação relativa a outras unidades)
- O que fazer se falhar (política de reinício, atraso de reinício)
Os ficheiros de unidade de serviço para serviços em todo o sistema residem em /etc/systemd/system/. Os ficheiros colocados aqui têm precedência sobre as unidades fornecidas pelo fornecedor em /lib/systemd/system/ e persistem entre atualizações de pacotes.
Passo a passo: Criar uma unidade de serviço systemd
O seguinte passo a passo usa uma aplicação fictícia chamada myapp. Substitua cada instância de myapp, myuser e /usr/bin/myapp com valores apropriados para o seu próprio ambiente.
Passo 1: Preparar o diretório de trabalho
Antes de escrever o ficheiro de unidade, decida de onde a sua aplicação será executada. Um diretório de trabalho dedicado mantém os ficheiros de configuração, registos e dados de tempo de execução organizados e torna a gestão de permissões simples.
Crie o diretório se ainda não existir:
sudo mkdir -p /opt/myapp> Por que /opt/ em vez de /etc/systemd/?
> A árvore /etc/systemd/ é reservada para a própria configuração do systemd. Colocar dados de aplicação lá é não-padrão e pode causar confusão. Use /opt/myapp, /srv/myapp ou /var/lib/myapp dependendo da categoria do Padrão de Hierarquia do Sistema de Ficheiros que melhor se adequa à sua carga de trabalho.
Atribua propriedade ao utilizador que executará o serviço:
sudo useradd --system --no-create-home --shell /usr/sbin/nologin myuser
sudo chown -R myuser:myuser /opt/myappUsar uma conta de sistema dedicada (sem shell de login, sem diretório inicial) é uma melhor prática de segurança. Limita o raio de explosão se a aplicação for alguma vez comprometida.
Verifique o resultado:
ls -ld /opt/myapp
# Expected output: drwxr-xr-x 2 myuser myuser 4096 Jan 1 00:00 /opt/myappPasso 2: Criar o ficheiro de unidade de serviço
Abra um novo ficheiro de unidade com o seu editor preferido:
sudo nano /etc/systemd/system/myapp.serviceCole o seguinte conteúdo, ajustando os valores para corresponder à sua aplicação:
[Unit]
Description=My Custom Application
Documentation=https://example.com/docs
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/bin/myapp --config /opt/myapp/myapp.conf
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5s
User=myuser
Group=myuser
WorkingDirectory=/opt/myapp
StandardOutput=journal
StandardError=journal
SyslogIdentifier=myapp
# Security hardening
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
PrivateTmp=true
[Install]
WantedBy=multi-user.targetGuarde o ficheiro com Ctrl+O e saia com Ctrl+X.
Passo 3: Compreender cada diretiva
#### Secção [Unit]
| Diretiva | Propósito |
|---|---|
Description | Nome legível por humanos mostrado na saída systemctl status |
Documentation | Referência de URL ou página de manual para o serviço |
After | Garante que o serviço inicia *após* a unidade listada estar ativa |
Wants | Dependência suave — systemd *tentará* iniciar a unidade listada mas não falhará se não estiver disponível |
> network-online.target vs network.target: Use network-online.target (combinado com Wants=network-online.target) para serviços que genuinamente precisam de uma interface de rede totalmente configurada — por exemplo, uma aplicação que se conecta a uma base de dados remota ou a uma API externa no arranque. network.target apenas garante que o subsistema de rede foi *iniciado*, não que as interfaces estão ativas e os endereços foram atribuídos.
#### Secção [Service]
| Diretiva | Propósito |
|---|---|
Type=simple | O processo iniciado por ExecStart é o processo principal (padrão para a maioria das aplicações) |
ExecStart | Caminho completo para o binário e quaisquer argumentos. Sempre use caminhos absolutos. |
ExecReload | Comando para recarregar a configuração sem um reinício completo (opcional mas recomendado) |
Restart=on-failure | Reinicie o serviço apenas quando sair com um código diferente de zero ou for morto por um sinal. Use always se quiser reinícios mesmo em saídas limpas. |
RestartSec | Segundos a aguardar antes de tentar um reinício |
User / Group | Execute o processo como este utilizador/grupo em vez de root |
WorkingDirectory | Defina o diretório atual antes de executar ExecStart |
StandardOutput / StandardError | Encaminhe stdout/stderr para o diário systemd |
SyslogIdentifier | Etiqueta usada para filtrar entradas de diário para este serviço |
NoNewPrivileges | Impede que o processo ganhe privilégios adicionais através de binários setuid |
ProtectSystem=strict | Monta /usr, /boot e /etc como apenas leitura para o serviço |
ProtectHome | Torna /home, /root e /run/user inacessíveis |
PrivateTmp | Dá ao serviço o seu próprio espaço de nomes /tmp privado |
#### Secção [Install]
| Diretiva | Propósito |
|---|---|
WantedBy=multi-user.target | Ativa o serviço quando o sistema atinge o nível de execução multi-utilizador padrão (não gráfico). Este é o alvo correto para praticamente todos os daemons de servidor. |
Passo 4: Verificar permissões de ficheiro e diretório
Antes de recarregar systemd, confirme que o utilizador do serviço pode realmente aceder a tudo o que precisa:
# Check working directory ownership and permissions
ls -ld /opt/myapp
# Confirm the executable exists and is executable
ls -l /usr/bin/myapp
# Verify the config file is readable by myuser
sudo -u myuser cat /opt/myapp/myapp.confSe alguma destas verificações falhar, corrija as permissões antes de prosseguir:
# Make the binary executable
sudo chmod +x /usr/bin/myapp
# Grant read access to the config file
sudo chmod 640 /opt/myapp/myapp.conf
sudo chown myuser:myuser /opt/myapp/myapp.confPasso 5: Testar o executável manualmente
Sempre verifique que a sua aplicação é executada corretamente *antes* de entregar o controlo ao systemd. Isto isola bugs de aplicação de problemas de configuração do systemd:
sudo -u myuser /usr/bin/myapp --config /opt/myapp/myapp.confSe a aplicação iniciar sem erros, pressione Ctrl+C para pará-la e prossiga. Se falhar, resolva a própria aplicação — verifique se todas as dependências estão instaladas, as variáveis de ambiente estão definidas e as portas necessárias estão disponíveis.
Passo 6: Recarregar systemd e ativar o serviço
Após guardar o ficheiro de unidade, instrua o systemd a re-ler a sua configuração:
sudo systemctl daemon-reloadAtive o serviço para que inicie automaticamente em cada arranque subsequente:
sudo systemctl enable myapp.serviceEste comando cria uma ligação simbólica no diretório .wants apropriado, ligando o seu ficheiro de unidade na sequência de arranque multi-user.target. Deverá ver uma saída semelhante a:
Created symlink /etc/systemd/system/multi-user.target.wants/myapp.service → /etc/systemd/system/myapp.service.Inicie o serviço imediatamente sem reiniciar:
sudo systemctl start myapp.servicePasso 7: Verificar se o serviço está em execução
Verifique o estado atual do serviço:
sudo systemctl status myapp.serviceUm serviço saudável produz uma saída como esta:
● myapp.service - My Custom Application
Loaded: loaded (/etc/systemd/system/myapp.service; enabled; vendor preset: disabled)
Active: active (running) since Wed 2025-01-01 12:00:00 UTC; 5s ago
Main PID: 12345 (myapp)
Tasks: 4 (limit: 4915)
Memory: 12.3M
CPU: 45ms
CGroup: /system.slice/myapp.service
└─12345 /usr/bin/myapp --config /opt/myapp/myapp.confCampos-chave a verificar:
Loaded— confirma que o ficheiro de unidade foi analisado com sucesso e mostra se estáenabledoudisabledpara arranqueActive: active (running)— o serviço está atualmente em execuçãoMain PID— o ID do processo da sua aplicação
Passo 8: Monitorizar registos com journalctl
systemd encaminha toda a saída do serviço para o diário, um armazenamento de registo estruturado e consultável. Use journalctl para inspecioná-lo:
# View all logs for myapp (most recent last)
journalctl -u myapp.service
# Follow live log output (like tail -f)
journalctl -u myapp.service -f
# Show only logs since the last boot
journalctl -u myapp.service -b
# Show the last 50 lines
journalctl -u myapp.service -n 50
# Show logs since a specific time
journalctl -u myapp.service --since "2025-01-01 12:00:00"Se o seu serviço falhar ao iniciar, o diário quase sempre contém a mensagem de erro exata explicando o porquê. Este é o primeiro lugar a procurar antes de fazer qualquer alteração.
Passo 9: Testar o comportamento de arranque
Para confirmar que o serviço sobrevive a uma reinicialização sem inspecionar manualmente a sequência de arranque, pode simulá-lo:
# Reboot the server (only if safe to do so)
sudo rebootApós o servidor voltar a estar online, verifique o estado do serviço novamente:
sudo systemctl status myapp.serviceSe mostrar active (running), o seu serviço está corretamente configurado para arranque automático.
Gerir o ciclo de vida do serviço
Uma vez que o seu serviço está em execução, utilizará regularmente os seguintes comandos:
Comandos systemctl comuns
# Start the service
sudo systemctl start myapp.service
# Stop the service gracefully
sudo systemctl stop myapp.service
# Restart the service (stop + start)
sudo systemctl restart myapp.service
# Reload configuration without restarting (if ExecReload is defined)
sudo systemctl reload myapp.service
# Enable automatic startup at boot
sudo systemctl enable myapp.service
# Disable automatic startup at boot
sudo systemctl disable myapp.service
# Check whether the service is enabled
sudo systemctl is-enabled myapp.service
# Check whether the service is currently active
sudo systemctl is-active myapp.service
# View the full unit file as systemd interprets it
sudo systemctl cat myapp.service
# Edit the unit file and reload in one step
sudo systemctl edit --full myapp.serviceResolução de problemas comuns
O serviço falha ao iniciar: “No such file or directory”
Isto geralmente significa que ExecStart aponta para um binário inexistente ou WorkingDirectory não existe. Verifique ambos os caminhos:
which myapp
ls -l /opt/myappO serviço inicia mas sai imediatamente
Verifique o diário para a saída de erro da própria aplicação:
journalctl -u myapp.service -n 100 --no-pagerTambém verifique se Type=simple está correto para a sua aplicação. Se o seu binário se bifurca em segundo plano, use Type=forking em vez disso.
Erros de “Permission denied”
O utilizador do serviço não tem acesso a um ficheiro ou diretório necessário. Use ls -l para auditar permissões e sudo -u myuser para testar o acesso interativamente.
Porta já em uso
Outro processo está vinculado à porta que a sua aplicação precisa. Identifique-o com:
sudo ss -tlnp | grep :<port>O serviço reinicia num ciclo
Se Restart=on-failure causa ciclos de reinício rápido, systemd eventualmente acelerará os reinícios. Verifique StartLimitIntervalSec e StartLimitBurst na secção [Unit] para afinar este comportamento e sempre investigue a causa raiz no diário.
Padrões avançados de systemd para servidores de produção
Variáveis de ambiente e ficheiros de ambiente
Nunca codifique segredos em ficheiros de unidade. Use um ficheiro de ambiente em vez disso:
[Service]
EnvironmentFile=/etc/myapp/myapp.env
ExecStart=/usr/bin/myappCrie /etc/myapp/myapp.env com chmod 600 e chown root:myuser para restringir o acesso:
DATABASE_URL=postgresql://user:password@localhost/mydb
API_KEY=supersecretkeyDependências de serviço e ordenação
Se a sua aplicação depende de um serviço de base de dados (por exemplo, PostgreSQL ou MySQL), declare essa dependência explicitamente:
[Unit]
After=network-online.target postgresql.service
Requires=postgresql.serviceRequires é uma dependência dura — se PostgreSQL falhar ao iniciar, systemd não tentará iniciar o seu serviço também.
Integração de watchdog
Para serviços críticos para a missão, ative o watchdog integrado do systemd para detetar processos travados:
[Service]
WatchdogSec=30s
Restart=on-watchdogA sua aplicação deve chamar sd_notify(0, "WATCHDOG=1") periodicamente para repor o temporizador do watchdog. Se falhar ao fazê-lo dentro de WatchdogSec, systemd mata e reinicia o serviço.
Escolher o ambiente de alojamento correto
Os padrões de configuração do systemd descritos neste guia aplicam-se igualmente em todos os tipos de servidores Linux, mas a sua escolha de infraestrutura de alojamento afeta quanto controlo tem sobre o sistema init e a gestão de serviços.
- VPS Hosting — Acesso root completo, controlo systemd completo, ideal para implementações de aplicações personalizadas. Os planos VPS da AlexHost funcionam em virtualização KVM, dando-lhe um ambiente kernel isolado genuíno.
- Servidores Dedicados — Desempenho máximo e isolamento para serviços intensivos em recursos. Acesso completo ao hardware sem vizinhos barulhentos.
- VPS com cPanel — Combina acesso systemd ao nível de root com um painel de controlo gráfico para equipas que gerem serviços de sistema e alojamento web a partir de uma única interface.
- Alojamento web partilhado — Adequado para aplicações web padrão que não requerem serviços de sistema personalizados. Sem acesso root, mas sem sobrecarga de gestão de servidor.
Se está a implementar um daemon personalizado, microserviço ou qualquer aplicação que precise de sobreviver a reinícios automaticamente, um VPS ou servidor dedicado com acesso root completo é a escolha apropriada
