Seu serviço não tem Type=
especificado na seção [Service]
, então systemd
assume que você quis dizer Type=simple
.
Isso significa que systemd
esperará que o processo iniciado com ExecStart=
continue em execução enquanto o serviço estiver em execução. Mas parece que o seu start.sh
apenas executa um comando e depois sai. Isso é o comando forever
: forever start
inicia o comando de destino como um daemon, ou em outras palavras, em segundo plano. Assim que o comando forever start
for concluído, o shell executando start.sh
será encerrado.
Nesse momento, systemd
considera este serviço como falho. Mas espere, o grupo de controle designado para esse serviço ainda tem um processo em execução nele. "Então," pensa systemd
", não apenas falhou, mas também deixou uma bagunça atrás de si. Não pode ter isso." Como não há KillMode=
nem KillSignal=
especificado, systemd
prossegue com seus padrões e envia um SIGTERM para qualquer processo restante nesse grupo de controle, e se eles não pararem em tempo hábil, segue com um SIGKILL Depois disso, seu processo atual do NodeJS estará morto, garantido.
Como corrigir isso
Como o comando executado com ExecStart=
será encerrado assim que o servidor real for iniciado, você não poderá usar o padrão Type=simple
. Você deve especificar outro tipo de serviço.
Você pode usar o Type=forking
. Com esse tipo, man systemd.service
recomenda o uso de uma opção PIDFile=
, portanto, se seu servidor NodeJS criar um arquivo PID para si mesmo (ou você adicionar opções ao comando forever
para criar um para ele), você deverá deixar systemd
saiba onde será.
[Service]
Type=forking
PIDFile=/absolute/path/to/nodejs.pid
User=rails
... <the rest as before>
Se Type=forking
não funcionar para você, especifique Type=oneshot
com RemainAfterExit=yes
.
Isso faz com que systemd
apenas execute o comando ExecStart=
ao iniciar seu serviço e ExecStop=
ao interrompê-lo e não se importe com mais nada.
systemd
ainda lembrará se o serviço foi definido pela última vez em um estado parado ou iniciado. Portanto, se você configurar outro serviço para depender desse serviço e, em seguida, interromper seu serviço NodeJS manualmente, o outro serviço não será interrompido automaticamente e, sem dúvida, retornará erros quando não puder usar seu serviço NodeJS.
A terceira opção é ignorar totalmente o comando forever
e deixar que systemd
faça o trabalho de reiniciar o processo NodeJS. Nesse caso, toda a sua unidade nodejs.service
seria:
[Unit]
Description=nodejs server
[Service]
User=rails
Group=rails
ExecStart=/home/rails/NodeJSserver/server.js
Restart=always
[Install]
WantedBy=multi-user.target
Você pode adicionar outras opções.
Por exemplo, você pode especificar RestartSec=5
para especificar um período de espera de 5 segundos antes de tentar reiniciar o serviço se ele morrer inesperadamente, para evitar sobrecarregar os recursos do sistema por tentativas frequentes de reinicialização se o serviço continuar morrendo imediatamente após ser reiniciado por algum tempo razão. (O valor padrão RestartSec=
é 100 ms.)
Ou se você quiser que o serviço seja reiniciado se ele retornar alguns valores de status de saída específicos, mas considere que ele falhou em outros, também há opções para isso.