O servidor Node.js com daemontools é constantemente reiniciado

2

Eu quero rodar um servidor Node.js com daemontools no Debian (Jessie), mas meu script rodando sob supervise é constantemente reiniciado. Este é o script de execução que estou usando ( /etc/service/node/run ):

#!/bin/bash
exec setuidgid nodeuser bash -c './node'

O script executa o seguinte script como usuário nodeuser , onde carrego a NVM, mudo para o meu diretório de código e executo o servidor Node.js:

#!/bin/bash

# Load NVM because we are in a non-interactive shell
export NVM_DIR="/home/nodeuser/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"

# Run server
cd /path/to/code
exec node server.js

Quando inicio o serviço com sudo svc -u /etc/service/node , o processo é reiniciado o tempo todo e ps faux mostra a seguinte hierarquia de processos (a profundidade da hierarquia está sempre mudando):

/bin/sh /usr/bin/svscanboot /etc/service/
 \_ svscan /etc/service
     \_ supervise node
         \_ /bin/bash ./node
             \_ /bin/bash ./node
                 \_ /bin/bash ./node
                     \_ /bin/bash ./node
                         \_ /bin/bash ./node
                         |   \_ /bin/bash ./node
                         |       \_ /bin/bash ./node
                         |       |   \_ /bin/bash ./node
                         |       |       \_ /bin/bash ./node
                         |       \_ /bin/bash ./node
                         |           \_ tail -n1
                         \_ /bin/bash ./node
                             \_ tail -n1

Você tem uma ideia do que está acontecendo lá? Quando executo o script manualmente com ./run , o servidor é iniciado conforme o esperado e mostra sua saída no console.

EDITAR

Descobri que o serviço funciona somente após a reinicialização. Uma vez que eu reinicie com sudo svc -du /etc/service/node , ele se comporta como descrito acima.

    
por chrisklaussner 02.10.2015 / 20:12

1 resposta

2

Esse script está errado. A máxima com a família daemontools é que o programa executado por ./run deve ser o próprio processo de serviço , não seu pai, avô ou outro parente. Os serviços são executados, não gerados.

O uso de exec na linha final é a idéia correta, mas é arruinado pelo uso de bash -c explícito. Isso é desnecessário, uma vez que o script ./node tem um interpretador de script #!/bin/bash especificado e é (presumivelmente) executável. Melhor

#!/bin/bash
exec setuidgid nodeuser ./node

Isso, claro, pode ser um nosh (de o conjunto de ferramentas epônimo ) ou um execlineb , porque não há necessidade real do shell Bourne Again pesado apenas para executar um único comando setuidgid . Assim:

#!/bin/nosh
setuidgid nodeuser
./node
ou
#!/command/execlineb -P
s6-setuidgid nodeuser
./node

Então, quando o gerenciador de serviços chega para retirar o serviço em resposta a svc -d , ele envia o sinal para o processo de serviço real correto.

Leitura adicional

por 17.05.2016 / 15:57