Como executar o Node.js como um processo em segundo plano e nunca morrer?

480

Eu me conecto ao servidor linux via putty SSH. Tentei executá-lo como um processo em segundo plano como este:

$ node server.js &

No entanto, após 2,5 horas, o terminal fica inativo e o processo morre. Existe alguma maneira de manter o processo vivo, mesmo com o terminal desconectado?


Editar 1

Na verdade, tentei nohup, mas assim que fecho o terminal Putty SSH ou desconecto a Internet, o processo do servidor para imediatamente.

Existe algo que eu tenho que fazer em Putty?


Edit 2 (em fevereiro de 2012)

Existe um node.jsmódulo para sempre . Ele executará o servidor node.js como serviço daemon.

murvinlai
fonte
7
No meu caso, o nohup funciona quando eu saio do Terminal digitando exit. Quando eu fecho a janela do Putty, ele falha.
Pawel Furmaniak

Respostas:

513

Solução simples (se você não estiver interessado em voltar ao processo, apenas queira que ele continue em execução):

nohup node server.js &

Há também o jobscomando para ver uma lista indexada desses processos em segundo plano. E você pode eliminar um processo em segundo plano executando kill %1ou kill %2com o número sendo o índice do processo.

Solução poderosa (permite que você se reconecte ao processo, se for interativo):

screen

Você pode desanexar pressionando Ctrl + a + de reconectar executando screen -r

Considere também a alternativa mais nova para a tela, o tmux.

MK.
fonte
1
Então, se eu rodar "tela", crio a tela e corro dentro dela, certo?
murvinlai
30
sim e, em seguida, você pode desconectar pressionando as teclas Ctrl + a, de anexar novamente executando a tela -r
MK.
1
@murvinlai O EC2 é um ambiente e não tem nada a ver com privilégios de root. Provavelmente é sobre o seu AMI. Por exemplo, com o Amazon AMI, você certamente pode sudo bash.
ShuaiYuan 02/04
1
man bash: Se um comando é finalizado pelo operador de controle &, o shell executa o comando em segundo plano em uma subshell. O shell não espera o comando terminar e o status de retorno é 0.
MK.
34
Por favor, para quem lê isto: executando um servidor node.js dentro de uma tela ou tmux sessão é uma AMADORES solução! Não faça isso, a menos que seja para testes rápidos. Para manter um processo em execução, você precisa daemonize -o! Use ferramentas apropriadas para isso, como para sempre , pm2 ou os scripts init.d simples e antigos .
Victor Schröder
1119

nohup node server.js > /dev/null 2>&1 &

  1. nohupsignifica: Não encerre esse processo mesmo quando o stty estiver cortado.
  2. > /dev/nullsignifica: stdout vai para / dev / null (que é um dispositivo fictício que não registra nenhuma saída).
  3. 2>&1significa: stderr também vai para o stdout (que já está redirecionado /dev/null). Você pode substituir & 1 por um caminho de arquivo para manter um registro de erros, por exemplo:2>/tmp/myLog
  4. &no final significa: execute este comando como uma tarefa em segundo plano.
Yoichi
fonte
49
Essa deve ser a resposta aceita, porque é de qualidade muito superior à atualmente aceita.
L0j1k
2
@ L0j1k discutível, o OP demonstrou um nível de entendimento de que é necessária mais explicação para a resposta aceita.
JFA
41
O SO não se refere tanto ao OP quanto às milhares de pessoas que vêm à pergunta do OP para obter ajuda.
L0j1k
3
É necessário redirecionar stdout e stderr? Funcionaria tão bem se eu não os redirecionasse? Ou se eu os redirecionasse para arquivos?
Shawn
10
Enviar stdout AND stderr para /dev/null? Agradável logging ... Boa sorte tentando depurar isso ...
Victor Schröder
138

Você realmente deveria tentar usar screen. É um pouco mais complicado do que apenas fazer nohup long_running &, mas entender a tela quando você nunca mais voltar.

Inicie sua sessão na tela primeiro:

user@host:~$ screen

Execute o que quiser:

wget http://mirror.yandex.ru/centos/4.6/isos/i386/CentOS-4.6-i386-binDVD.iso

Pressione ctrl + A e depois d. Feito. Sua sessão continua em segundo plano.

Você pode listar todas as sessões por screen -lse anexar a algumas por screen -r 20673.pts-0.srvcomando, em que 0673.pts-0.srv é uma lista de entradas.

Alex Povar
fonte
125

Esta é uma pergunta antiga, mas tem uma classificação alta no Google. Quase não consigo acreditar nas respostas mais votadas, porque executar um processo node.js dentro de uma sessão de tela, com &ou mesmo com o nohupsinalizador - todos eles - são apenas soluções alternativas.

Especialmente a solução screen / tmux, que realmente deve ser considerada uma solução amadora . Screen e Tmux não são para manter os processos em execução, mas para multiplexar sessões de terminal. Tudo bem, quando você está executando um script no servidor e deseja desconectar. Mas para um servidor node.js. você não deseja que seu processo seja anexado a uma sessão de terminal. Isso é muito frágil. Para manter as coisas funcionando, você precisa daemonize o processo!

Existem muitas boas ferramentas para fazer isso.

PM2 : http://pm2.keymetrics.io/

# basic usage
$ npm install pm2 -g
$ pm2 start server.js

# you can even define how many processes you want in cluster mode:
$ pm2 start server.js -i 4

# you can start various processes, with complex startup settings
# using an ecosystem.json file (with env variables, custom args, etc):
$ pm2 start ecosystem.json

Uma grande vantagem que vejo a favor do PM2 é que ele pode gerar o script de inicialização do sistema para fazer com que o processo persista entre as reinicializações:

$ pm2 startup [platform]

Onde platformpode estar ubuntu|centos|redhat|gentoo|systemd|darwin|amazon.

forever.js : https://github.com/foreverjs/forever

# basic usage
$ npm install forever -g
$ forever start app.js

# you can run from a json configuration as well, for
# more complex environments or multi-apps
$ forever start development.json

Scripts de inicialização :

Não vou entrar em detalhes sobre como escrever um script init, porque não sou especialista neste assunto e seria muito longo para essa resposta, mas basicamente são simples scripts de shell, acionados por eventos do SO. Você pode ler mais sobre isso aqui

Docker :

Basta executar o servidor em um contêiner do Docker com a -dopção e, voilá , você tem um servidor node.j daemonizado!

Aqui está uma amostra do Dockerfile (no guia oficial node.js. ):

FROM node:argon

# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# Install app dependencies
COPY package.json /usr/src/app/
RUN npm install

# Bundle app source
COPY . /usr/src/app

EXPOSE 8080
CMD [ "npm", "start" ]

Em seguida, crie sua imagem e execute seu contêiner:

$ docker build -t <your username>/node-web-app .
$ docker run -p 49160:8080 -d <your username>/node-web-app

Espero que isso ajude alguém a chegar nesta página. Sempre use a ferramenta adequada para o trabalho. Isso vai lhe poupar muitas dores de cabeça e durante horas!

Victor Schröder
fonte
2
Era isso que eu estava procurando. Com a solução pm2, existe uma maneira de conectar um terminal a ele mais tarde?
Quantumplation 15/07/16
4
@Quantumplation, não. Isso não é possível porque o processo não está sendo executado em uma sessão interativa. Mas você pode ter o mesmo "sentimento" tail -finserindo o arquivo de log que o pm2 gera.
Victor Schröder
1
Você especifica a screensolução que muitas pessoas estão encontrando faz o trabalho é uma solução alternativa. Existem várias maneiras de realizar uma tarefa específica. Acredito que aconteça (considere a questão específica) estar cumprindo a tarefa específica de run as background and never dieexcelência para muitos. Ele também tem o bônus adicional de permitir que o usuário volte a interagir novamente e faça alterações, se quiser. A chave é componentes é backgrounde never die. Todas as soluções têm certos bônus.
LD James
@Rakshith Ravi - eu discordo. Tudo isso requer downloads / software / ferramentas adicionais (exceto a solução init, para a qual nenhuma solução foi fornecida). A nohup é a solução. É feito no Linux e é para isso que serve. É uma linha, é limpa e funciona como planejado, sempre, independentemente de atualizações. As pessoas realmente devem tentar evitar o uso de ferramentas de terceiros para casos de uso básicos como esse. O exemplo da janela de encaixe (por exemplo) é muito mais detalhado e com muitos recursos do que o único comando na resposta votada superior. Amo o Docker, mas não para isso.
Jack_Hu
1
@Jack_Hu, não tenho dúvidas sobre a sobrecarga, mas a nohupsolução não atende ao requisito "nunca morra". A menos que você escreva um traploop infinito muito complicado ou hacky, não vejo como manter o processo daemonized sem usar ferramentas especialmente escritas para esse fim (ou um script init escrito por você mesmo, é claro).
Victor Schröder
24

outra solução negou o trabalho

$ nohup node server.js &
[1] 1711
$ disown -h %1
myururdurmaz
fonte
renegar é exatamente o que eu estava procurando, mas o que a bandeira -h faz? Não consigo encontrá-lo no manual
Rimantas Jacikevicius 15/01
from man page: Se a opção -h for dada, cada jobpec não será removido da tabela, mas será marcado para que o SIGHUP não seja enviado ao job se o shell receber um SIGHUP. Se nenhuma especificação de trabalho for fornecida, a opção -a significa remover ou marcar todas as tarefas;
myururdurmaz
14

nohuppermitirá que o programa continue mesmo após a morte do terminal. Na verdade, tive situações em que nohupimpede que a sessão SSH seja encerrada corretamente, portanto, você deve redirecionar a entrada também:

$ nohup node server.js </dev/null &

Dependendo de como nohupestá configurado, também pode ser necessário redirecionar a saída padrão e o erro padrão para os arquivos.

Daniel Gallagher
fonte
7

Eu tenho essa função no meu arquivo shell rc, com base na resposta de @ Yoichi:

nohup-template () {
    [[ "$1" = "" ]] && echo "Example usage:\nnohup-template urxvtd" && return 0
    nohup "$1" > /dev/null 2>&1 &
}

Você pode usá-lo desta maneira:

nohup-template "command you would execute here"
thiagowfx
fonte
7

O Nohup e a tela oferecem ótimas soluções leves para executar o Node.js em segundo plano. O gerenciador de processos do Node.js. ( PM2 ) é uma ferramenta útil para implantação. Instale-o com o npm globalmente no seu sistema:

npm install pm2 -g

para executar um aplicativo Node.js como um daemon:

pm2 start app.js

Opcionalmente, você pode vinculá-lo ao Keymetrics.io, um SAAS de monitoramento feito pela Unitech.

Donald Derek
fonte
6
$ disown node server.js &

Ele removerá o comando da lista de tarefas ativas e enviará o comando para segundo plano

Skynet
fonte
5

Você leu sobre o comando nohup ?

S.Lott
fonte
3

Para executar o comando como um serviço do sistema no debian com sysv init:

Copie o script do esqueleto e adapte-o às suas necessidades, provavelmente tudo o que você precisa fazer é definir algumas variáveis. Seu script herdará padrões finos de /lib/init/init-d-script, se algo não atender às suas necessidades - substitua-o em seu script. Se algo der errado, você poderá ver detalhes na fonte /lib/init/init-d-script. Vars obrigatórios são DAEMONe NAME. O script será usado start-stop-daemonpara executar seu comando, pois START_ARGSvocê pode definir parâmetros adicionais start-stop-daemonpara usar.

cp /etc/init.d/skeleton /etc/init.d/myservice
chmod +x /etc/init.d/myservice
nano /etc/init.d/myservice

/etc/init.d/myservice start
/etc/init.d/myservice stop

É assim que eu executo algumas coisas em python no meu wiki da wikimedia:

...
DESC="mediawiki articles converter"
DAEMON='/home/mss/pp/bin/nslave'
DAEMON_ARGS='--cachedir /home/mss/cache/'
NAME='nslave'
PIDFILE='/var/run/nslave.pid'
START_ARGS='--background --make-pidfile --remove-pidfile --chuid mss --chdir /home/mss/pp/bin'

export PATH="/home/mss/pp/bin:$PATH"

do_stop_cmd() {
    start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 \
        $STOP_ARGS \
        ${PIDFILE:+--pidfile ${PIDFILE}} --name $NAME
    RETVAL="$?"
    [ "$RETVAL" = 2 ] && return 2
    rm -f $PIDFILE
    return $RETVAL
}

Além de configurar vars, eu tive que substituir do_stop_cmdpor causa de python substitui o executável, para que o serviço não parasse corretamente.

user3132194
fonte
3

Além das soluções legais acima, eu mencionaria também as ferramentas supervisord e monit que permitem iniciar o processo, monitorar sua presença e iniciá-lo se ele morrer. Com o 'monit', você também pode executar algumas verificações ativas, como verificar se o processo responde à solicitação http

Krzysztof Księżyk
fonte
3

Para o Ubuntu, eu uso este:

(exec PROG_SH &> / dev / null &)

Saudações

David Lopes
fonte
Ponto secundário: 'exec' não é necessário se PROG_SH for um executável. O objetivo da solução proposta por David é desassociar a criança do atual shell em execução. O pai da criança se torna 'pid 1' e não será afetado quando o shell terminar.
SoloPilot 10/08/18
0

Tente isso para uma solução simples

cmd & exit

Hunter Frazier
fonte