Iniciar automaticamente para sempre (nó) na reinicialização do sistema

190

Estou usando o módulo forever do nó para manter meu servidor de nós em execução. Para sempre, porém, termina quando há uma reinicialização do sistema. Existe alguma maneira de iniciar automaticamente o servidor do nó (com uma eternidade) quando o sistema reiniciar?

kehers
fonte
1
Este servidor está na nuvem? Você tem algum script de inicialização para isso?
Jorge Aranda
6
Caixa PM2 ! Ele também suporta a geração de scripts de inicialização (systemd, systemv ...) pm2.keymetrics.io/docs/usage/startup
Unitech

Respostas:

341

Eu sugeriria o uso do crontab. É fácil de usar.

Como

  1. Para iniciar a edição, execute o seguinte substituindo o "testuser" pelo usuário de tempo de execução desejado para o processo do nó. Se você escolher um usuário diferente de você, será necessário executá-lo com o sudo.

    $ crontab -u testuser -e
  2. Se você nunca fez isso antes, ele perguntará com qual editor você deseja editar. Eu gosto do vim, mas recomendarei o nano para facilitar o uso.

  3. Uma vez no editor, adicione a seguinte linha:

    @reboot /usr/local/bin/forever start /your/path/to/your/app.js
  4. Salve o arquivo. Você deve receber algum feedback de que o cron foi instalado.

  5. Para confirmação adicional da instalação do cron, execute o seguinte (substituindo novamente "testuser" pelo nome de usuário de destino) para listar os crons atualmente instalados:

    $ crontab -u testuser -l 

Observe que, na minha opinião, você sempre deve usar caminhos completos ao executar binários no cron. Além disso, se o caminho para o script forever não estiver correto, execute which foreverpara obter o caminho completo.

Dadas as foreverchamadas node, você também pode fornecer o caminho completo para node:

@reboot /usr/local/bin/forever start -c /usr/local/bin/node /your/path/to/your/app.js

Leitura adicional

Julian Lannigan
fonte
2
Essa abordagem é boa, mas apenas para os casos em que o sistema é reiniciado. Se o servidor for desligado e depois ligado - este trabalho cron não será executado.
Ecdeveloper 17/05
6
O que te faz pensar isso? en.wikipedia.org/wiki/Cron#Predefined_scheduling_definitions Explica que o @rebootcron é executado no inicio do cron deamon. Para adicionar, nunca me deparei com uma situação que sugerisse que meus cron's configurados em @rebootnão sejam executados na inicialização do sistema. A maneira como você o encerra é irrelevante para isso.
Julian Lannigan
16
parece que /homeainda não está montado, portanto, isso não funcionará se o seu código residir /home.
chovy
6
Eu descobri que o acima falhou para mim porque o nó não está no caminho quando o cron tenta executar para sempre, mesmo com a opção -c. Entretanto, você pode adicionar uma instrução PATH = diretamente no crontab, desde que esteja acima das instruções de programação. Depois que PATH é definido, a instrução @reboot funcionou como um sonho.
YorkshireKev
2
Obrigado pelo seu comentário @chovy, foi muito útil. Para aqueles que usam variáveis ​​de ambiente do bashrc, lembre-se de seu comentário. Como / home não está montado, não funcionará. Defina as variáveis ​​no comando crontab como@reboot varname=value ...
lsborg
123

Você pode usar o serviço permanente para fazer isso.

npm install -g forever-service
forever-service install test

Isso fornecerá o app.js no diretório atual como um serviço para sempre. O serviço será reiniciado automaticamente sempre que o sistema for reiniciado. Além disso, quando parado, tentará uma parada suave. Esse script também fornece o script logrotate.

URL do Github: https://github.com/zapty/forever-service

NOTA: Sou o autor do serviço permanente.

arva
fonte
2
Use -e "PORT = 80 ENV = prod FOO = bar" opção
Arva
2
Eu não entendo como executar o serviço para sempre. O que é esse "teste" em "teste de instalação de serviço permanente"? Meu comando para iniciar meu aplicativo para sempre é: "/ usr / local / bin / para sempre start -c / usr / local / bin / node / home / alex / public / node_modules / http-server / bin / http-server -s - d falso ". O que eu teria que escrever?
Alex
3
test aqui é o nome do serviço. quando você executa o teste de instalação de serviço permanente, ele cria um serviço chamado test, para executar o app.js nesse diretório para ser executado como um serviço. Sugiro ler a documentação de ajuda na página do gihub e adicionar um problema se você não conseguir entendê-lo.
Arva 27/05
6
@Alex - para esclarecer o comentário do arva - no exemplo forever-service install test, testserá o nome do serviço , mas não o nome do arquivo .js do programa / nó real a ser executado. Por padrão, ele assume o nome do programa é app.js, mas você pode substituí-lo com a --scriptbandeira, como segue: forever-service install test --script main.js. (Não testado, então por favor me corrigir se há alguma sintaxe detalhe errado.)
Dan Nissenbaum
3
@DanNissenbaum Obrigado por responder. Agora estou usando o PM2, que funciona lindamente. Instruções: digitalocean.com/community/tutorials/…
Alex
26

Este caso é válido para o Debian.

Adicione o seguinte a /etc/rc.local

/usr/bin/sudo -u {{user}} /usr/local/bin/forever start {{app path}}

  • {{user}} substitui seu nome de usuário.
  • {{app path}}substitui o caminho do seu aplicativo. Por exemplo,/var/www/test/app.js
NiLL
fonte
2
Esse método não lida com desligamentos simples, embora para muitas pessoas isso provavelmente não seja um problema.
UpTheCreek
6
BTW - Acho que você deveria estar editando /etc/rc.local, não/etc/init.d/rc.local
UpTheCreek
Concorde com @UpTheCreek que /etc/rc.local é o local mais apropriado para adicionar isso - consulte: unix.stackexchange.com/a/59945 para obter uma ótima explicação.
Então Over It
2
Além disso, convém especificar o 'diretório de trabalho atual' app.jspara garantir que os arquivos relativos sejam carregados corretamente - process.chdir('/your/path/to/your/app'); Node.js. ref docs here
So Over It
1
Se você precisar definir variáveis ​​de ambiente para o script Node.JS (como $ PORT para express), adicione a seguinte linha para /etc/rc.localfazer o truque para mim:( cd /path/to/project && /usr/bin/sudo -u {{user}} env PORT={{port number}} PATH=$PATH:/usr/local/bin sh -c "forever start app.js" )
sffc
25
  1. Instale o PM2 globalmente usando o NPM

    npm install pm2 -g

  2. Comece seu script com pm2

    pm2 start app.js

  3. gerar um script de inicialização ativo

    pm2 startup

    NOTA: a inicialização do pm2 é para iniciar o PM2 quando o sistema é reiniciado. O PM2, uma vez iniciado, reinicia todos os processos que estava gerenciando antes da queda do sistema.

Caso deseje desativar a inicialização automática, basta usar o pm2 unstartup

Se você deseja que o script de inicialização seja executado em outro usuário, use a -u <username>opção e o--hp <user_home>:

fsamuel
fonte
Não poste a mesma resposta em várias perguntas.
perfil completo de FelixSFD
Eu realmente amo como o pm2 é refinado e vem com uma ferramenta de monitoramento incrível. Espero que isso seja destacado mais para os outros. @ rv7 Tenho certeza que você viu isso, mas existe uma solução para Windows: npmjs.com/package/pm2-windows-service . Ainda não tentei.
John Lee
11

Um método alternativo de crontab inspirado nesta resposta e nesta postagem do blog.

1. Crie um arquivo de script bash (altere bob para o usuário desejado).

vi /home/bob/node_server_init.sh

2. Copie e cole isso dentro do arquivo que você acabou de criar.

#!/bin/sh

export NODE_ENV=production
export PATH=/usr/local/bin:$PATH
forever start /node/server/path/server.js > /dev/null

Certifique-se de editar os caminhos acima de acordo com sua configuração!

3. Verifique se o script bash pode ser executado.

chmod 700 /home/bob/node_server_init.sh

4. Teste o script bash.

sh /home/bob/node_server_init.sh

5. Substitua "bob" pelo usuário de tempo de execução para o nó.

crontab -u bob -e

6. Copie e cole (altere bob para o usuário desejado).

@reboot /bin/sh /home/bob/node_server_init.sh

Salve o crontab.

Você chegou ao fim, seu prêmio é uma reinicialização (para testar) :)

Emre
fonte
Este método funcionou melhor para mim. O Forever terminaria quando eu colocasse um caminho completo para o arquivo server.js. Se eu o executasse no mesmo diretório, o foreveer funcionaria bem. A razão pela qual falhou é que o arquivo server.js incluiu outros arquivos, mas os caminhos foram alterados. Usando esse método, eu poderia colocar o CD no meu script .sh no diretório e, em seguida, executar tudo relativo a ele.
precisa saber é o seguinte
9

Resposta copiada da pergunta em anexo .

Você pode usar o PM2 , é um gerenciador de processos de produção para aplicativos Node.js. com um balanceador de carga interno.

Instale o PM2

$ npm install pm2 -g

Iniciar uma aplicação

$ pm2 start app.js

Se você estiver usando o express, poderá iniciar seu aplicativo como

pm2 start ./bin/www --name="app"

Listando todos os processos em execução:

$ pm2 list

Ele listará todo o processo. Em seguida, você pode parar / reiniciar o serviço usando o ID ou o nome do aplicativo com o seguinte comando.

$ pm2 stop all                  
$ pm2 stop 0                    
$ pm2 restart all               

Para exibir logs

$ pm2 logs ['all'|app_name|app_id]
Vikash Rajpurohit
fonte
Como ele é iniciado automaticamente na inicialização do sistema? Basta copiar / colar CLI digitação manual de
Verde
@ Green, Run, $pm2 startupDepois disso, você verá o pm2 pedindo para executar manualmente um comando, copie e execute. $pm2 saveAgora , agora o seu app.js sobreviverá à reinicialização do sistema
yajnesh
7

Você precisa criar um script de shell na pasta /etc/init.d para isso. É meio complicado se você nunca fez isso, mas há muita informação na web sobre scripts init.d.

Aqui está uma amostra de um script que eu criei para executar um site CoffeeScript para sempre:

#!/bin/bash
#
# initd-example      Node init.d 
#
# chkconfig: 345 
# description: Script to start a coffee script application through forever
# processname: forever/coffeescript/node
# pidfile: /var/run/forever-initd-hectorcorrea.pid 
# logfile: /var/run/forever-initd-hectorcorrea.log
#
# Based on a script posted by https://gist.github.com/jinze at https://gist.github.com/3748766
#


# Source function library.
. /lib/lsb/init-functions


pidFile=/var/run/forever-initd-hectorcorrea.pid 
logFile=/var/run/forever-initd-hectorcorrea.log 

sourceDir=/home/hectorlinux/website
coffeeFile=app.coffee
scriptId=$sourceDir/$coffeeFile


start() {
    echo "Starting $scriptId"

    # This is found in the library referenced at the top of the script
    start_daemon

    # Start our CoffeeScript app through forever
    # Notice that we change the PATH because on reboot
    # the PATH does not include the path to node.
    # Launching forever or coffee with a full path
    # does not work unless we set the PATH.
    cd $sourceDir
    PATH=/usr/local/bin:$PATH
    NODE_ENV=production PORT=80 forever start --pidFile $pidFile -l $logFile -a -d --sourceDir $sourceDir/ -c coffee $coffeeFile

    RETVAL=$?
}

restart() {
    echo -n "Restarting $scriptId"
    /usr/local/bin/forever restart $scriptId
    RETVAL=$?
}

stop() {
    echo -n "Shutting down $scriptId"
    /usr/local/bin/forever stop $scriptId
    RETVAL=$?
}

status() {
    echo -n "Status $scriptId"
    /usr/local/bin/forever list
    RETVAL=$?
}


case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    status)
        status
        ;;
    restart)
        restart
        ;;
    *)
        echo "Usage:  {start|stop|status|restart}"
        exit 1
        ;;
esac
exit $RETVAL

Eu tinha que ter certeza de que a pasta e os PATHs estavam explicitamente definidos ou disponíveis para o usuário raiz, pois os scripts init.d são executados como raiz.

Hector Correa
fonte
2
Se você tiver alguma dependência que também foi iniciada com o init.d, você pode ter problemas com o carregamento do pedido.
UpTheCreek
@ alexandru.topliceanu Corrigi o link.
Hector Correa
6

Use o PM2

Qual é a melhor opção para executar o servidor de produção do servidor

Quais são as vantagens de executar seu aplicativo dessa maneira?

  • O PM2 reiniciará seu aplicativo automaticamente se ele falhar.

  • O PM2 manterá um registro de suas exceções não tratadas - nesse caso, em um arquivo em /home/safeuser/.pm2/logs/app-err.log.

  • Com um comando, o PM2 pode garantir que todos os aplicativos gerenciados sejam reiniciados quando o servidor for reiniciado. Basicamente, o aplicativo do nó será iniciado como um serviço.

ref: https://www.digitalocean.com/community/tutorials/how-to-use-pm2-to-setup-a-node-js-production-environment-on-an-ubuntu-vps

Vishnu Mishra
fonte
5

O Forever não foi criado para fazer com que os aplicativos de nó funcionassem como serviços. A abordagem correta é criar uma entrada / etc / inittab (sistemas linux antigos) ou um upstart (sistemas linux mais recentes).

Aqui está uma documentação sobre como configurá-lo como um iniciante: https://github.com/cvee/node-upstart

snez
fonte
O Upstart falhou comigo no CentOS e eu li que ele vai desaparecer. Criação de uma entrada init.d não é realmente a maneira mais amigável, mas é linux Suponho :)
Jorre
5

crontabnão funciona para mim no CentOS x86 6.5. O @reboot parece não estar funcionando.

Finalmente, consegui esta solução:

Editar: /etc/rc.local

sudo vi /etc/rc.local

Adicione esta linha ao final do arquivo. Mude USER_NAMEe PATH_TO_PROJECTpara o seu próprio país. NODE_ENV=productionsignifica que o aplicativo é executado no modo de produção. Você pode adicionar mais linhas se precisar executar mais de um aplicativo node.js.

su - USER_NAME -c "NODE_ENV=production /usr/local/bin/forever start /PATH_TO_PROJECT/app.js"

Não defina NODE_ENVem uma linha separada, seu aplicativo continuará sendo executado no modo de desenvolvimento, porque sempre não é possível NODE_ENV.

# WRONG!
su - USER_NAME -c "export NODE_ENV=production"

Salve e saia do vi (pressione ESC : w q return). Você pode tentar reiniciar o servidor. Após a reinicialização do servidor, o aplicativo node.js. deve ser executado automaticamente, mesmo se você não fizer login em nenhuma conta remotamente via ssh.

É melhor definir o NODE_ENVambiente em seu shell. NODE_ENVserá definido automaticamente quando sua conta USER_NAMEfizer login.

echo export NODE_ENV=production >> ~/.bash_profile

Assim, você pode executar comandos como parar / iniciar para sempre /PATH_TO_PROJECT/app.jsvia ssh sem configurar NODE_ENVnovamente.

Vince Yuan
fonte
tem o mesmo problema no debian 7.6. Isso consertou para mim. Muito Obrigado.
precisa saber é o seguinte
Caso você não queira usar 'forever', altere a linha para 'su - USER_NAME -c "NODE_ENV = nó de produção / PATH_TO_PROJECT / bin / www"'.
Yaobin 03/10/2015
3

Eu escrevi um script que faz exatamente isso:

https://github.com/chovy/node-startup

Eu não tentei com uma eternidade, mas você pode personalizar o comando que ele executa, por isso deve ser direto:

/etc/init.d/node-app start
/etc/init.d/node-app restart
/etc/init.d/node-app stop
chovy
fonte
1

Eu tentei muitas das respostas acima. Nenhum deles funcionou para mim. Meu aplicativo está instalado no /homee como usuário, não como root. Isso provavelmente significa que, quando os scripts de inicialização mencionados acima são executados,/home ainda não está montado, portanto o aplicativo não é iniciado.

Então eu encontrei estas instruções da Digital Ocean:

https://www.digitalocean.com/community/tutorials/how-to-use-pm2-to-setup-a-node-js-production-environment-on-an-ubuntu-vps

Usar o PM2 como explicado foi muito simples e funciona perfeitamente: Meus servidores virtuais tiveram duas falhas físicas desde - o tempo de inatividade foi de apenas um minuto.

Alex
fonte
O PM2 tem muito mais estrelas (2x) no github do que para sempre, além de ter mais recursos. Eu acho que a maioria das respostas é obsoleta aqui.
inf3rno 21/02
1

O problema com o rc.local é que os comandos são acessados ​​como raiz, o que é diferente de fazer logon como usuário e usar o sudo.

Resolvi esse problema adicionando um script .sh com os comandos de inicialização que desejo etc / profile.d. Qualquer arquivo .sh em profile.d será carregado automaticamente e qualquer comando será tratado como se você usasse o sudo comum.

A única desvantagem disso é que o usuário especificado precisa fazer logon para iniciar o processo, o que na minha situação sempre foi o caso.

Moe Elsharif
fonte
0

exemplo completo crontab (localizado em / etc / crontab) ..

#!/bin/bash

# edit this file with .. crontab -u root -e
# view this file with .. crontab -u root -l

# put your path here if it differs
PATH=/root/bin:/root/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin

# * * * * * echo "executes once every minute" > /root/deleteme

@reboot cd /root/bible-api-dbt-server; npm run forever;
@reboot cd /root/database-api-server; npm run forever;
@reboot cd /root/mailer-api-server; npm run forever;
danday74
fonte
-1

Você pode usar o seguinte comando no seu shell para iniciar seu nó para sempre:

forever app.js //my node script

Você deve ter em mente que o servidor no qual seu aplicativo está sendo executado deve sempre ser mantido.

Gaurav Singh
fonte