Come eseguire Node.js come processo in background e non morire mai?


480

Mi collego al server Linux tramite putty SSH. Ho provato a eseguirlo come un processo in background come questo:

$ node server.js &

Tuttavia, dopo 2,5 ore il terminale diventa inattivo e il processo termina. Posso comunque mantenere vivo il processo anche con il terminale disconnesso?


Modifica 1

In realtà, ci ho provato nohup, ma non appena chiudo il terminale SSH Putty o scollego la mia connessione Internet, il processo del server si interrompe immediatamente.

C'è qualcosa che devo fare a Putty?


Modifica 2 (febbraio 2012)

C'è un node.jsmodulo, per sempre . Eseguirà il server node.js come servizio daemon.


7
Nel mio caso nohup funziona quando esco da Terminal digitando exit. Quando chiudo semplicemente la finestra di Putty, fallisce.
Pawel Furmaniak,

Risposte:


513

Soluzione semplice (se non sei interessato a tornare al processo, vuoi solo che continui a funzionare):

nohup node server.js &

C'è anche il jobscomando per vedere un elenco indicizzato di quei processi in background. E puoi terminare un processo in background eseguendo kill %1o kill %2con il numero come indice del processo.

Soluzione potente (consente di riconnettersi al processo se è interattivo):

screen

È quindi possibile staccare premendo Ctrl + a + d e quindi ricollegarsi eseguendo screen -r

Considera anche la nuova alternativa allo schermo, tmux.


1
Quindi, se eseguo "schermo", creo lo schermo e corro al suo interno, giusto?
Murvinlai,

30
sì, quindi puoi staccare premendo Ctrl + a, d e quindi ricollegarlo eseguendo lo schermo -r
MK.

1
@murvinlai EC2 è un ambiente e non ha nulla a che fare con il privilegio di root. Probabilmente riguarda la tua AMI. Ad esempio con Amazon AMI puoi sicuramente farlo sudo bash.
ShuaiYuan,

1
man bash: se un comando viene terminato dall'operatore di controllo &, la shell esegue il comando in background in una sottoshell. La shell non attende il completamento del comando e lo stato di ritorno è 0.
MK.

34
Per favore, per chiunque legga questo: eseguire un server node.js all'interno di una schermata o di una sessione tmux è una soluzione AMATEUR ! Non farlo, a meno che per test rapidi. Per mantenere un processo in esecuzione devi demonizzarlo ! Usa gli strumenti adeguati per farlo, come per sempre , PM2 o le semplici vecchi script init.d .
Victor Schröder,

1119

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

  1. nohupsignifica: non interrompere questo processo anche quando lo stty viene interrotto.
  2. > /dev/nullsignifica: stdout va in / dev / null (che è un dispositivo fittizio che non registra alcun output).
  3. 2>&1significa: stderr passa anche allo stdout (che è già reindirizzato a /dev/null). Puoi sostituire & 1 con un percorso file per tenere un registro degli errori, ad esempio:2>/tmp/myLog
  4. &alla fine significa: eseguire questo comando come attività in background.

49
Questa dovrebbe essere la risposta accettata, perché è di qualità molto superiore a quella attualmente accettata.
L0j1k,

2
@ L0j1k discutibile, OP ha dimostrato a livello di comprensione che per la risposta accettata sono necessarie ulteriori spiegazioni.
JFA,

41
SO non riguarda l'OP tanto quanto le migliaia di persone che arrivano alla domanda di OP per chiedere aiuto.
L0j1k,

3
È necessario reindirizzare stdout e stderr? Funzionerebbe altrettanto bene se non li reindirizzassi affatto? O se invece li ho reindirizzati ai file?
Shawn,

10
Invia stdout AND stderr a /dev/null? Bella registrazione ... Buona fortuna cercando di eseguire il debug di questo ...
Victor Schröder,

138

Dovresti davvero provare a usare screen. È un po 'più complicato del semplice farenohup long_running & , ma capire lo schermo una volta che non torni più.

Inizia la tua sessione schermo inizialmente:

user@host:~$ screen

Esegui tutto quello che vuoi:

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

Premere ctrl + A e quindi d. Fatto. La sessione continua in background.

Puoi elencare tutte le sessioni per screen -lse collegarle ad alcune per screen -r 20673.pts-0.srvcomando, dove 0673.pts-0.srv è un elenco di voci.


125

Questa è una vecchia domanda, ma è classificata in alto su Google. Quasi non riesco a credere alle risposte più votate, perché l'esecuzione di un processo node.js all'interno di una sessione dello schermo, con &o anche con il nohupflag - tutti loro - sono solo soluzioni alternative.

Specialmente la soluzione screen / tmux, che dovrebbe davvero essere considerata una soluzione amatoriale . Screen e Tmux non sono pensati per mantenere in esecuzione i processi, ma per sessioni terminali multiplexing. Va bene, quando si esegue uno script sul server e si desidera disconnettersi. Ma per un server node.js non vuoi che il tuo processo sia collegato a una sessione terminale. Questo è troppo fragile. Per far funzionare le cose devi demonizzare il processo!

Ci sono molti buoni strumenti per farlo.

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

Un grande vantaggio che vedo a favore di PM2 è che può generare lo script di avvio del sistema per rendere persistente il processo tra i riavvii:

$ pm2 startup [platform]

Dove platformpuò essere 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

Script Init :

Non entrerò nei dettagli su come scrivere uno script di init, perché non sono un esperto in questo argomento e sarebbe troppo lungo per questa risposta, ma fondamentalmente sono semplici script di shell, innescati da eventi del sistema operativo. Puoi leggere di più su questo qui

Docker :

Esegui il tuo server in un contenitore Docker con l' -dopzione e, voilá , hai un server node.js demone!

Ecco un Dockerfile di esempio (dalla guida ufficiale di 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" ]

Quindi crea la tua immagine ed esegui il tuo contenitore:

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

Spero che questo aiuti qualcuno ad atterrare su questa pagina. Utilizzare sempre lo strumento adeguato per il lavoro. Ti farà risparmiare un sacco di mal di testa e nel giro di ore!


2
Questo è quello che stavo cercando. Con la soluzione pm2, c'è un modo per collegare un terminale in un secondo momento?
Quantumplation

4
@Quantumplation, no. Ciò non è possibile perché il processo non è in esecuzione in una sessione interattiva. Ma puoi avere la stessa "sensazione" tail -fing nel file di registro che genera pm2.
Victor Schröder,

1
Si specifica la screensoluzione che molte persone trovano che il lavoro sia una soluzione alternativa. Esistono molti modi per raggiungere un compito specifico. Credo che accada che (considera la domanda specifica) capita di raggiungere il compito specifico di run as background and never dieeccellere per molti. Ha anche il vantaggio aggiuntivo di consentire all'utente di rientrare per interagire nuovamente e apportare modifiche se lo desidera. La chiave è componenti è backgrounde never die. Tutte le soluzioni hanno determinati bonus.
LD James,

@Rakshith Ravi - Non sono d'accordo. Tutto ciò richiede download / software / strumenti aggiuntivi (tranne la soluzione init, per la quale non è stata fornita alcuna soluzione). Questa nohup è la soluzione. È installato su Linux ed è quello che serve. È una riga, è pulita e funziona come previsto, ogni volta, indipendentemente dagli aggiornamenti. Le persone dovrebbero davvero cercare di evitare l'uso di strumenti di terze parti per casi d'uso di base come questo. L'esempio docker (ad esempio) è molto più dettagliato e dispendioso in termini di risorse rispetto al semplice comando nella risposta con il voto più alto. Adoro Docker, ma non per questo.
Jack_Hu,

1
@Jack_Hu, non ho dubbi sul sovraccarico, ma la nohupsoluzione non soddisfa il requisito "non morire". A meno che tu non scriva un traploop infinito molto complicato o complicato , non vedo come mantenere il processo demonizzato senza usare strumenti appositamente creati per questo scopo (o uno script init scritto da te, ovviamente).
Victor Schröder,

24

un'altra soluzione ha rinnegato il lavoro

$ nohup node server.js &
[1] 1711
$ disown -h %1

il disown è esattamente quello che stavo cercando, ma cosa fa -h flag? Non riesco a trovarlo nel manuale
Rimantas Jacikevicius,

dalla pagina man: Se viene fornita l'opzione -h, ogni jobspec non viene rimosso dalla tabella, ma è contrassegnato in modo che SIGHUP non venga inviato al lavoro se la shell riceve un SIGHUP. Se non viene fornito jobspec, l'opzione -a significa rimuovere o contrassegnare tutti i lavori;
myururdurmaz,

14

nohupconsentirà al programma di continuare anche dopo la morte del terminale. In realtà ho avuto situazioni in cui nohupimpedisce alla sessione SSH di terminare correttamente, quindi dovresti reindirizzare anche l'input:

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

A seconda della nohupconfigurazione, potrebbe essere necessario reindirizzare l'output standard e l'errore standard sui file.


7

Ho questa funzione nel mio file rc della shell, basato sulla risposta di @ Yoichi:

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

Puoi usarlo in questo modo:

nohup-template "command you would execute here"

7

Nohup e schermo offrono ottime soluzioni di illuminazione per l'esecuzione di Node.js in background. Node.js process manager ( PM2 ) è uno strumento utile per la distribuzione. Installalo con npm a livello globale sul tuo sistema:

npm install pm2 -g

per eseguire un'app Node.js come demone:

pm2 start app.js

Opzionalmente puoi collegarlo a Keymetrics.io un SAAS di monitoraggio realizzato da Unitech.


6
$ disown node server.js &

Rimuoverà il comando dall'elenco delle attività attive e invierà il comando in background



3

Per eseguire il comando come servizio di sistema su debian con sysv init:

Copia lo script skeleton e adattalo alle tue esigenze, probabilmente tutto ciò che devi fare è impostare alcune variabili. La tua sceneggiatura erediterà le impostazioni predefinite /lib/init/init-d-script, se qualcosa non soddisfa le tue esigenze - ignorala nella tua sceneggiatura. Se qualcosa va storto puoi vedere i dettagli nella fonte /lib/init/init-d-script. Vars obbligatori sono DAEMONe NAME. Lo script utilizzerà start-stop-daemonper eseguire il comando, in cui START_ARGSè possibile definire parametri aggiuntivi start-stop-daemonda utilizzare.

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

È così che eseguo alcune cose in pitone per il mio wiki 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
}

Oltre a impostare Vars, ho dovuto eseguire l'override do_stop_cmdperché Python sostituisce l'eseguibile, quindi il servizio non si è arrestato correttamente.


3

Oltre alle fantastiche soluzioni sopra menzionerei anche strumenti di supervisord e monit che consentono di avviare il processo, monitorare la sua presenza e avviarlo se è morto. Con 'monit' puoi anche eseguire alcuni controlli attivi come verificare se il processo risponde per una richiesta http


3

Per Ubuntu uso questo:

(exec PROG_SH &> / dev / null &)

Saluti


Punto minore: 'exec' non è necessario se PROG_SH è un eseguibile. Il punto della soluzione proposta da David è dissociare il bambino dall'attuale shell corrente. Il genitore del bambino diventa 'pid 1' e non sarà interessato quando la shell termina.
SoloPilot,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.