15%

Poupe 15% em todos os serviços

Teste as suas habilidades e obtenha Desconto em qualquer plano

Utilizar o código:

Skills
Começar a trabalhar
06.11.2024

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

FuncionalidadeBenefício
Arranque paralelo de serviçosTempos de arranque mais rápidos em servidores com múltiplos serviços
Gestão de dependênciasOs serviços iniciam apenas após os seus pré-requisitos estarem prontos
Políticas de reinício automáticoOs serviços falhados recuperam sem intervenção manual
Registo centralizado via journaldToda a saída do serviço é capturada num diário consultável
Controlo de recursos baseado em cgroupLimites de CPU e memória aplicados por serviço
Ativação de socket e dispositivoOs 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/myapp

Usar 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/myapp

Passo 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.service

Cole 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.target

Guarde o ficheiro com Ctrl+O e saia com Ctrl+X.

Passo 3: Compreender cada diretiva

#### Secção [Unit]

DiretivaPropósito
DescriptionNome legível por humanos mostrado na saída systemctl status
DocumentationReferência de URL ou página de manual para o serviço
AfterGarante que o serviço inicia *após* a unidade listada estar ativa
WantsDependê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]

DiretivaPropósito
Type=simpleO processo iniciado por ExecStart é o processo principal (padrão para a maioria das aplicações)
ExecStartCaminho completo para o binário e quaisquer argumentos. Sempre use caminhos absolutos.
ExecReloadComando para recarregar a configuração sem um reinício completo (opcional mas recomendado)
Restart=on-failureReinicie 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.
RestartSecSegundos a aguardar antes de tentar um reinício
User / GroupExecute o processo como este utilizador/grupo em vez de root
WorkingDirectoryDefina o diretório atual antes de executar ExecStart
StandardOutput / StandardErrorEncaminhe stdout/stderr para o diário systemd
SyslogIdentifierEtiqueta usada para filtrar entradas de diário para este serviço
NoNewPrivilegesImpede que o processo ganhe privilégios adicionais através de binários setuid
ProtectSystem=strictMonta /usr, /boot e /etc como apenas leitura para o serviço
ProtectHomeTorna /home, /root e /run/user inacessíveis
PrivateTmpDá ao serviço o seu próprio espaço de nomes /tmp privado

#### Secção [Install]

DiretivaPropósito
WantedBy=multi-user.targetAtiva 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.conf

Se 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.conf

Passo 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.conf

Se 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-reload

Ative o serviço para que inicie automaticamente em cada arranque subsequente:

sudo systemctl enable myapp.service

Este 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.service

Passo 7: Verificar se o serviço está em execução

Verifique o estado atual do serviço:

sudo systemctl status myapp.service

Um 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.conf

Campos-chave a verificar:

  • Loaded — confirma que o ficheiro de unidade foi analisado com sucesso e mostra se está enabled ou disabled para arranque
  • Active: active (running) — o serviço está atualmente em execução
  • Main 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 reboot

Após o servidor voltar a estar online, verifique o estado do serviço novamente:

sudo systemctl status myapp.service

Se 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.service

Resoluçã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/myapp

O 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-pager

També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/myapp

Crie /etc/myapp/myapp.env com chmod 600 e chown root:myuser para restringir o acesso:

DATABASE_URL=postgresql://user:password@localhost/mydb
API_KEY=supersecretkey

Dependê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.service

Requires é 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-watchdog

A 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

15%

Poupe 15% em todos os serviços

Teste as suas habilidades e obtenha Desconto em qualquer plano

Utilizar o código:

Skills
Começar a trabalhar