De acordo com as Leis 12.965/2014 e 13.709/2018, que regulam o uso da Internet e o tratamento de dados pessoais no Brasil, ao me inscrever na newsletter do portal DICAS-L, autorizo o envio de notificações por e-mail ou outros meios e declaro estar ciente e concordar com seus Termos de Uso e Política de Privacidade.

Como criar seu primeiro serviço systemd

Colaboração: Rubens Queiroz de Almeida

Data de Publicação: 10 de outubro de 2026

Em muitas distribuições Linux, o systemd é o primeiro processo iniciado pelo kernel. Ele recebe o identificador de processo 1, organiza a inicialização do sistema e administra serviços, dispositivos, pontos de montagem, temporizadores e outros recursos.

Quando instalamos programas como Apache, Nginx, PostgreSQL ou SSH, normalmente encontramos serviços que podem ser controlados com comandos como:

$ sudo systemctl start nginx
$ sudo systemctl stop nginx
$ sudo systemctl restart nginx

Também podemos criar nossos próprios serviços. Isso é útil para iniciar automaticamente um programa, manter uma aplicação em segundo plano, reiniciá-la em caso de falha e centralizar suas mensagens no journal do sistema.

Neste tutorial criaremos um serviço simples que executará continuamente um script e registrará uma mensagem a cada 30 segundos.

O que é uma unidade do systemd?

O systemd trabalha com objetos chamados unidades. Cada unidade é descrita por um arquivo de configuração cuja extensão identifica sua finalidade.

Alguns tipos comuns são:

Extensão Finalidade
.service Executar e administrar um serviço
.socket Representar um socket de comunicação
.timer Programar a execução de uma unidade
.mount Administrar um ponto de montagem
.path Monitorar arquivos ou diretórios
.target Agrupar unidades e representar estados do sistema

Neste artigo trabalharemos com uma unidade do tipo service.

Os serviços criados pelo administrador normalmente são armazenados em /etc/systemd/system/.

Os arquivos fornecidos pelos pacotes da distribuição costumam ficar abaixo de /usr/lib/systemd/system/ ou /lib/systemd/system/, dependendo da distribuição. Como /etc/systemd/system/ possui prioridade administrativa, é o local apropriado para nossos próprios serviços e personalizações.

Criando o programa que será executado

Nosso primeiro serviço executará um pequeno script chamado meu-servico.sh. Ele escreverá uma mensagem com a data e a hora e aguardará 30 segundos antes de repetir a operação.

Crie o arquivo:

$ sudo nano /usr/local/bin/meu-servico.sh 
'''

Insira o seguinte conteúdo:

#!/bin/sh

while true
do
    echo "Meu serviço está ativo: $(date)"
    sleep 30
done

Salve o arquivo e torne-o executável:

$ sudo chmod 755 /usr/local/bin/meu-servico.sh 

Antes de criar o serviço, execute o script manualmente:

$ /usr/local/bin/meu-servico.sh 

Uma nova mensagem deverá aparecer a cada 30 segundos:

Meu serviço está ativo: Thu Oct 8 20:45:00 -03 2026
Meu serviço está ativo: Thu Oct 8 20:45:30 -03 2026

Pressione Ctrl+C para interromper o teste.

Executar o programa manualmente antes de colocá-lo sob o controle do systemd é uma boa prática. Dessa forma, podemos separar problemas existentes no programa daqueles causados pela configuração do serviço.

Criando um usuário para o serviço

É possível executar o script como root, mas ele não precisa de privilégios administrativos. Criaremos um usuário de sistema exclusivo:

$ sudo useradd \
    --system \
    --no-create-home \
    --shell /usr/sbin/nologin \
    meu-servico

Esse usuário não terá um diretório pessoal nem poderá iniciar uma sessão interativa. Sua única finalidade será executar nosso serviço.

Confirme sua criação:

$ getent passwd meu-servico 

Em algumas distribuições, o comando equivalente para criar uma conta de sistema pode ser diferente. O importante é que o usuário exista antes que o serviço seja iniciado.

Criando o arquivo da unidade

Agora criaremos a unidade:

$ sudo nano /etc/systemd/system/meu-servico.service 

Insira:

[Unit]
Description=Meu primeiro serviço systemd
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/meu-servico.sh
User=meu-servico
Group=meu-servico
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target

O arquivo está dividido em três seções: [Unit], [Service] e [Install].

Entendendo a seção Unit

A seção [Unit] contém informações gerais e relacionamentos com outras unidades:

[Unit]
Description=Meu primeiro serviço systemd
After=network.target

A diretiva Description apresenta uma descrição legível do serviço. Ela aparecerá em comandos como:

$ systemctl status meu-servico

A diretiva

 After=network.target 

define uma relação de ordem. Ela informa que nosso serviço deverá ser iniciado depois que o alvo network.target for alcançado.

Isso não significa necessariamente que a conexão com a Internet estará disponível. Para um programa que realmente dependa da rede completamente configurada, poderá ser necessário utilizar network-online.target e também garantir que o gerenciador de rede ofereça o serviço de espera correspondente.

Nosso script não depende da rede. A diretiva foi incluída apenas para demonstrar como a ordem de inicialização pode ser declarada e poderia ser removida neste exemplo.

Entendendo a seção Service

A seção [Service] descreve como o programa será executado:

[Service]
Type=simple
ExecStart=/usr/local/bin/meu-servico.sh
User=meu-servico
Group=meu-servico
Restart=on-failure
RestartSec=5s

A configuração:

 Type=simple 

indica que o processo iniciado por ExecStart será o processo principal do serviço. Esse é o tipo padrão quando Type e determinadas formas especiais de ativação não são declarados.

A linha mais importante é:

 ExecStart=/usr/local/bin/meu-servico.sh  

Ela informa o programa que o systemd deverá executar. É recomendável utilizar um caminho absoluto e evitar depender de recursos específicos de um shell interativo.

As diretivas:

User=meu-servico
Group=meu-servico

determinam a conta utilizada para executar o processo. Se elas fossem omitidas em um serviço do sistema, o processo seria iniciado como root.

A configuração:

 Restart=on-failure 

faz com que o serviço seja reiniciado quando o processo terminar devido a uma falha. Um encerramento normal não provocará a reinicialização.

O intervalo antes de uma nova tentativa será de cinco segundos:

 RestartSec=5s 

Usar on-failure costuma ser uma escolha adequada para serviços de longa duração, pois recupera o processo após uma falha sem reiniciá-lo quando ele é encerrado normalmente por decisão do administrador.

Entendendo a seção Install

A última seção determina como a unidade será ligada à inicialização do sistema:

[Install]
WantedBy=multi-user.target

O multi-user.target representa um sistema preparado para executar vários serviços e sessões de usuários, normalmente sem depender de uma interface gráfica.

A diretiva WantedBy é utilizada pelo comando systemctl enable. Ela faz com que sejam criados os vínculos necessários para incluir o serviço na inicialização associada ao alvo indicado. Habilitar um serviço e iniciá-lo são operações diferentes.

Verificando o arquivo

Antes de iniciar o serviço, podemos procurar erros no arquivo da unidade:

$ sudo systemd-analyze verify \
    /etc/systemd/system/meu-servico.service

Se nenhum problema for encontrado, o comando poderá não apresentar mensagem alguma.

O verify consegue detectar diretivas desconhecidas, dependências ausentes e alguns erros relacionados aos comandos configurados. Ainda assim, ele não substitui o teste real do serviço.

Recarregando a configuração

Depois de criar ou modificar uma unidade, precisamos solicitar que o systemd releia os arquivos:

$ sudo systemctl daemon-reload 

Esse comando recarrega a configuração do gerenciador. Ele não inicia nem reinicia automaticamente nosso serviço.

Agora podemos iniciá-lo:

$ sudo systemctl start meu-servico.service 

A extensão pode ser omitida:

$ sudo systemctl start meu-servico 

Examinando o estado do serviço

Consulte o estado:

$ systemctl status meu-servico 

A saída deverá ser semelhante a:

meu-servico.service - Meu primeiro serviço systemd
     Loaded: loaded
     Active: active (running)
   Main PID: 12345

A indicação:

 active (running) 

mostra que o processo está em execução.

Também podemos fazer uma verificação adequada para scripts:

$ systemctl is-active meu-servico 

Se estiver funcionando, a resposta será active.

Para verificar se ele está habilitado para a inicialização:

$ systemctl is-enabled meu-servico 

Como ainda apenas iniciamos o serviço, a resposta provavelmente será disabled.

Consultando os registros

Nosso script escreve suas mensagens na saída padrão. Por padrão, a saída dos serviços é integrada ao journal, o sistema de registros do systemd.

Para consultar as mensagens do serviço:

$ sudo journalctl --unit=meu-servico 

A opção pode ser abreviada:

$ sudo journalctl -u meu-servico 

Para mostrar apenas as mensagens da inicialização atual:

$ sudo journalctl -u meu-servico -b 

Para acompanhar novas mensagens em tempo real:

$ sudo journalctl -u meu-servico -f 

Pressione Ctrl+C para encerrar o acompanhamento. Isso interrompe apenas o journalctl; o serviço continuará funcionando.

Também podemos limitar a quantidade de linhas:

$ sudo journalctl -u meu-servico -n 20 

Uma vantagem dessa integração é que o programa não precisa criar e administrar seu próprio arquivo de log. Cada linha escrita em sua saída poderá ser associada à unidade correspondente.

Habilitando o serviço na inicialização

Para fazer com que o serviço seja iniciado automaticamente:

$ sudo systemctl enable meu-servico 

Esse comando habilita a unidade, mas não é necessário aguardar a próxima reinicialização para colocá-la em funcionamento. Podemos habilitar e iniciar em uma única operação:

$ sudo systemctl enable --now meu-servico 

Como o serviço já está em execução, o --now apenas garante que ele continue ativo.

Confirme:

$ systemctl is-enabled meu-servico
$ systemctl is-active meu-servico

As respostas esperadas são:

enabled active 

Iniciar, parar e reiniciar

A administração cotidiana pode ser feita com os seguintes comandos:

$ sudo systemctl start meu-servico
$ sudo systemctl stop meu-servico
$ sudo systemctl restart meu-servico

Para interromper o serviço:

$ sudo systemctl stop meu-servico 

Confira:

$ systemctl status meu-servico 

O serviço deverá aparecer como inativo.

Inicie-o novamente:

$ sudo systemctl start meu-servico 

O comando restart interrompe e inicia novamente o serviço:

$ sudo systemctl restart meu-servico 

Ele é particularmente útil depois de modificarmos o programa executado.

Alterando a unidade

Suponha que mudemos o intervalo de reinicialização:

 RestartSec=10s 

Depois de salvar o arquivo, será necessário executar:

$ sudo systemctl daemon-reload
$ sudo systemctl restart meu-servico

O primeiro comando faz o systemd reler a definição da unidade. O segundo reinicia o processo para que a nova configuração seja aplicada.

Podemos examinar exatamente qual arquivo está sendo usado:

$ systemctl cat meu-servico 

E consultar propriedades calculadas pelo systemd:

$ systemctl show meu-servico 

Para mostrar apenas algumas propriedades:

$ systemctl show meu-servico \
    --property=User,Group,MainPID,ActiveState,SubState

Testando a recuperação após uma falha

Nosso serviço possui:

 Restart=on-failure 

Para observar esse comportamento, descubra o identificador do processo principal:

$ systemctl show meu-servico --property=MainPID 

A saída será semelhante a:

MainPID=12345

Encerre abruptamente esse processo, substituindo o número pelo PID apresentado em seu sistema:

$ sudo kill -KILL 12345 

Depois de alguns segundos, consulte novamente:

$ systemctl status meu-servico 

O serviço deverá estar em execução com outro PID. O journal mostrará o encerramento e a tentativa de recuperação:

$ sudo journalctl -u meu-servico -n 30 

Esse teste demonstra que o systemd não é apenas um mecanismo de inicialização. Ele também acompanha o processo e pode tomar providências quando ocorre uma falha.

Um serviço não deve depender do terminal

Um erro comum é criar um script que funciona no terminal, mas falha quando executado como serviço. Isso acontece porque um serviço não recebe necessariamente o mesmo ambiente da sessão interativa.

Ele poderá ter diferenças em itens como:

  • diretório de trabalho;
  • variável PATH;
  • usuário e grupo;
  • variáveis de ambiente;
  • permissões de acesso;
  • terminal disponível;
  • localização do diretório pessoal.

Se o programa precisar de um diretório específico, declare-o explicitamente:

 WorkingDirectory=/diretorio/da/aplicacao 

Se precisar de uma variável de ambiente:

 Environment="MODO=producao" 

Também podemos usar um arquivo externo:

 EnvironmentFile=/etc/meu-servico.conf 

Senhas e outros segredos exigem cuidados adicionais. Um arquivo referenciado por EnvironmentFile não deve ser considerado automaticamente um cofre seguro apenas porque está fora da unidade.

Alguns recursos de proteção

O systemd oferece diversas diretivas que podem reduzir o acesso concedido ao serviço. Em nosso exemplo simples, podemos acrescentar:

[Service]
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes
Diretiva Função
NoNewPrivileges=yes impede que o processo e seus descendentes obtenham novos privilégios por meio de mecanismos como executáveis setuid.
PrivateTmp=yes fornece ao serviço uma visão privada dos diretórios temporários.
ProtectSystem=strict torna grande parte do sistema de arquivos disponível apenas para leitura dentro do ambiente do serviço.
ProtectHome=yes impede o acesso normal aos diretórios pessoais.

Essas opções precisam ser escolhidas de acordo com a aplicação. Um programa que precise gravar em determinado local poderá deixar de funcionar se suas permissões forem restringidas indiscriminadamente.

Uma forma de examinar a exposição de segurança da unidade é:

$ systemd-analyze security meu-servico 

A análise apresenta recomendações, mas a pontuação não deve ser interpretada isoladamente. A configuração adequada depende da função real do serviço.

Erros frequentes

O arquivo foi alterado, mas nada mudou

Execute:

$ sudo systemctl daemon-reload
$ sudo systemctl restart meu-servico

O daemon-reload atualiza a definição conhecida pelo systemd, enquanto o restart recria o processo.

O serviço não inicia

Consulte o estado completo:

$ systemctl status meu-servico --no-pager --full 

Depois, examine o journal:

$ sudo journalctl -u meu-servico -b --no-pager 

Verifique também o arquivo da unidade:

$ sudo systemd-analyze verify \
    /etc/systemd/system/meu-servico.service

O comando não foi encontrado

Use caminhos absolutos em ExecStart e confirme sua localização:

$ command -v nome-do-programa 

Também verifique se o arquivo existe e possui permissão de execução:

$ ls -l /usr/local/bin/meu-servico.sh 

O serviço recebe “Permission denied”

Confirme qual usuário executa o serviço:

$ systemctl show meu-servico --property=User,Group 

Depois, examine as permissões do programa e dos diretórios acessados por ele:

$ namei -l /usr/local/bin/meu-servico.sh 

O usuário precisa conseguir atravessar os diretórios do caminho e executar o arquivo. Se o programa gravar dados, também precisará de permissão no diretório correspondente.

O serviço inicia manualmente, mas não durante o boot

Verifique se ele está habilitado:

$ systemctl is-enabled meu-servico 

Examine os registros da inicialização atual:

$ sudo journalctl -u meu-servico -b 

Se o programa depender de rede, discos ou outros serviços, reveja as dependências e a ordem declaradas na seção [Unit].

O serviço entra em um ciclo de reinicialização

Consulte:

$ systemctl status meu-servico
$ sudo journalctl -u meu-servico -n 50

Depois de várias falhas em pouco tempo, o systemd poderá limitar novas tentativas. Após corrigir o problema, limpe o estado de falha:

$ sudo systemctl reset-failed meu-servico
$ sudo systemctl start meu-servico

Desabilitando e removendo o serviço

Para impedir a inicialização automática e interromper o serviço imediatamente:

$ sudo systemctl disable --now meu-servico 

Confirme:

$ systemctl is-enabled meu-servico
$ systemctl is-active meu-servico

Para removê-lo definitivamente, apague o arquivo da unidade e o script:

$ sudo rm /etc/systemd/system/meu-servico.service
$ sudo rm /usr/local/bin/meu-servico.sh

Depois, atualize o systemd:

$ sudo systemctl daemon-reload
$ sudo systemctl reset-failed

Se o usuário de sistema não for mais necessário:

$ sudo userdel meu-servico 

Antes de remover arquivos ou usuários de um serviço real, verifique se eles não estão sendo utilizados por outras unidades ou aplicações.

Resumo dos comandos

Objetivo Comando
Recarregar as unidades sudo systemctl daemon-reload
Iniciar o serviço sudo systemctl start meu-servico
Parar o serviço sudo systemctl stop meu-servico
Reiniciar o serviço sudo systemctl restart meu-servico
Ver o estado systemctl status meu-servico
Consultar os registros sudo journalctl -u meu-servico
Acompanhar os registros sudo journalctl -u meu-servico -f
Habilitar na inicialização sudo systemctl enable meu-servico
Habilitar e iniciar sudo systemctl enable --now meu-servico
Desabilitar e parar sudo systemctl disable --now meu-servico
Ver o arquivo carregado systemctl cat meu-servico
Validar a unidade sudo systemd-analyze verify ARQUIVO
Analisar a segurança systemd-analyze security meu-servico
Limpar o estado de falha sudo systemctl reset-failed meu-servico

Conclusão

Criar um serviço systemd consiste em preparar o programa que será executado, escrever um arquivo de unidade e informar ao systemd quando e em quais condições o processo deverá funcionar.

Neste primeiro exemplo, criamos um script contínuo, configuramos um usuário exclusivo, registramos uma unidade em /etc/systemd/system/, iniciamos o processo, consultamos suas mensagens e habilitamos sua execução durante a inicialização do Linux.

A partir dessa estrutura, podemos administrar servidores web, aplicações próprias, agentes de monitoramento, scripts de automação e diversos outros programas. O systemd oferece um ponto central para iniciar, interromper, acompanhar e proteger esses processos.

O próximo passo pode ser substituir o script de demonstração por uma aplicação real ou aprender a criar uma unidade .timer, capaz de executar tarefas programadas sem depender diretamente do cron.



Veja a relação completa dos artigos de Rubens Queiroz de Almeida