coldwa.st
Todos os guiasProgramaçãoWebDadosFerramentasBases de dadosHaskellConceitosCabal e buildsToolchainCompiladorDesempenhoEditor e HLS

Coldwast

Gerador de ficheiros de serviço systemd

Indique o comando que arranca a sua aplicação e obtenha uma unidade .service para colocar em /etc/systemd/system/, com os comandos de instalação correspondentes. O gerador também relê o que escreveu e assinala os erros que fazem uma unidade falhar logo no primeiro arranque. Tudo corre no seu navegador.

Frente de um servidor torre com grelha metálica perfurada e pequenos botões de ligar, iluminado de azul sobre fundo escuro
O painel frontal de um servidor torre, iluminado de azul. Depois de ativar a unidade, o systemd inicia a sua aplicação numa máquina como esta a cada arranque, sem que ninguém inicie sessão.
Partir de

O seu ficheiro de unidade

 

O que o gerador detetou

    Instalá-lo

     

    As cinco linhas que decidem se funciona

    ExecStart não é uma shell. O systemd divide a linha em argumentos por si próprio e executa o programa diretamente. Um pipe, uma redireção > ou um && chega ao seu programa como argumento literal. O systemd também expande $VAR por conta própria, por isso um cifrão literal escreve-se $$. Quando o gerador deteta sintaxe de shell, envolve o comando em /bin/sh -c e faz esse escape por si.

    Use um caminho absoluto. Um caminho como ./server é rejeitado de imediato. Um nome sem caminho como node é aceite, mas o systemd procura apenas nos seus próprios diretórios fixos, não no PATH da sua shell, por isso um Node instalado com nvm ou uma ferramenta em ~/.local/bin não é encontrado.

    Type=simple ou exec para quase tudo. Um servidor web, um worker ou um bot que fica em primeiro plano é simple. exec difere num ponto útil: o arranque só é dado como bem-sucedido quando o binário foi realmente executado, por isso um caminho errado faz falhar systemctl start em vez de falhar em silêncio um momento depois. forking é para daemons antigos que passam sozinhos para segundo plano, e notify só funciona se o programa chamar sd_notify.

    Restart=on-failure, com um limite. on-failure reinicia após uma falha ou uma saída diferente de zero, mas não após uma paragem limpa; always reinicia mesmo nesse caso. Por omissão o systemd permite 5 arranques em 10 segundos e, com uma espera de 5 segundos, uma app que falha nunca atinge esse limite: entra num ciclo infinito. StartLimitIntervalSec=300 com StartLimitBurst=5 faz com que desista e deixe um estado de falha claro.

    Wants= e After= juntos. After=network-online.target sozinho apenas define uma ordem; não ativa o target. Sem Wants=network-online.target o seu serviço pode arrancar antes de a rede estar pronta: o clássico «funciona depois de um reinício manual, falha no arranque da máquina».

    O isolamento, e o que ficou de fora de propósito

    Com ProtectSystem=strict todo o sistema de ficheiros fica só de leitura para o serviço, exceto os caminhos indicados em ReadWritePaths=. PrivateTmp dá-lhe o seu próprio /tmp, NoNewPrivileges impede-o de ganhar privilégios através de binários setuid, e as definições de kernel e cgroup impedem-no de alterar o estado do sistema. Execute systemd-analyze security suaapp.service antes e depois: mostra uma pontuação de exposição e lista cada definição ainda aberta.

    Duas recomendações comuns estão ausentes de propósito. MemoryDenyWriteExecute=true parte os compiladores just-in-time, ou seja Node.js, a JVM e PyPy. PrivateDevices=true não causa problemas numa app web, mas parte tudo o que fala com uma GPU ou uma porta série. Acrescente-as se souber que o seu programa não precisa delas.

    Um par de óculos numa secretária em frente a um monitor desfocado que mostra código-fonte colorido num editor
    Óculos pousados em frente a um ecrã cheio de código. Quando uma unidade falha, a resposta também está no ecrã: systemctl status dá o código de saída e journalctl a saída do seu programa.

    Quando não arranca: os códigos de saída

    systemctl status suaapp mostra um estado como status=203/EXEC. O número indica que passo falhou antes mesmo de o seu programa correr:

    EstadoSignificadoCorreção habitual
    203/EXECNão foi possível executar o programaCaminho errado, falta de permissão de execução ou script sem linha shebang
    200/CHDIRWorkingDirectory inexistente ou inacessívelCriá-lo, ou verificar que ProtectHome não o esconde
    217/USERA conta de User= não existeExecutar a linha useradd acima
    226/NAMESPACENão foi possível montar o isolamentoUm caminho de ReadWritePaths não existe: criá-lo ou prefixá-lo com -

    Qualquer outra falha é o seu próprio programa a terminar, e a saída dele está em journalctl -u suaapp -b.

    Alterá-lo mais tarde

    Depois de editar o ficheiro em /etc/systemd/system/, execute sudo systemctl daemon-reload antes de reiniciar, caso contrário o systemd continua a usar a versão antiga. Para uma unidade instalada por um pacote, não a edite no local: sudo systemctl edit suaapp cria um ficheiro de substituição que sobrevive às atualizações e recarrega o systemd por si.

    Relacionado: o que é um VPS, colocar um proxy reverso à frente da app, o básico de SSH e, para tarefas agendadas, o explicador de expressões cron.

    As diretivas seguem as páginas de manual systemd.service(5) e systemd.exec(5). Type=exec requer systemd 240 ou posterior; todas as versões atuais de Debian, Ubuntu, Fedora e RHEL cumprem.