¿Cómo ejecutar Node.js como un proceso en segundo plano y nunca morir?

480

Me conecto al servidor Linux a través de masilla SSH. Traté de ejecutarlo como un proceso en segundo plano como este:

$ node server.js &

Sin embargo, después de 2.5 horas, el terminal se vuelve inactivo y el proceso muere. ¿Hay alguna forma de mantener vivo el proceso incluso con el terminal desconectado?


Editar 1

En realidad, lo intenté nohup, pero tan pronto como cierro el terminal Putty SSH o desconecto mi internet, el proceso del servidor se detiene de inmediato.

¿Hay algo que tenga que hacer en Putty?


Edición 2 (en febrero de 2012)

Hay un node.jsmódulo, para siempre . Ejecutará el servidor node.js como servicio daemon.

murvinlai
fuente
77
En mi caso, nohup funciona cuando salgo de la Terminal escribiendo exit. Cuando acabo de cerrar la ventana Putty falla.
Pawel Furmaniak

Respuestas:

513

Solución simple (si no está interesado en volver al proceso, solo quiere que siga ejecutándose):

nohup node server.js &

También existe el jobscomando para ver una lista indexada de esos procesos en segundo plano. Y puede eliminar un proceso en segundo plano ejecutando kill %1o kill %2con el número como índice del proceso.

Solución poderosa (le permite volver a conectarse al proceso si es interactivo):

screen

Luego puede separar presionando Ctrl + a + dy luego volver a conectar ejecutando screen -r

Considere también la alternativa más nueva a la pantalla, tmux.

MK
fuente
1
Entonces, si ejecuto "pantalla", creo la pantalla y ejecuto dentro de ella, ¿verdad?
murvinlai
30
sí y luego puede desconectar presionando Ctrl + a, dy luego volver a conectar ejecutando la pantalla -r
MK.
1
@murvinlai EC2 es un entorno y no tiene nada que ver con el privilegio de root. Probablemente se trata de tu AMI. Por ejemplo, con Amazon AMI ciertamente puedes sudo bash.
ShuaiYuan
1
man bash: si el operador de control termina un comando &, el shell ejecuta el comando en segundo plano en un subshell. El shell no espera a que termine el comando y el estado de retorno es 0.
MK.
34
Por favor, para cualquiera que lea esto: ¡ejecutar un servidor node.js dentro de una sesión de pantalla o tmux es una solución AMATEUR ! No hagas eso, a menos que se realicen pruebas rápidas. Para mantener un proceso en ejecución, ¡debes demonizarlo ! Utilice herramientas adecuadas para ello, como siempre , PM2 o las llanura de edad scripts de init.d .
Victor Schröder
1119

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

  1. nohupsignifica: No finalice este proceso incluso cuando el stty esté cortado.
  2. > /dev/nullsignifica: stdout va a / dev / null (que es un dispositivo ficticio que no registra ninguna salida).
  3. 2>&1significa: stderr también va al stdout (que ya está redirigido a /dev/null). Puede reemplazar & 1 con una ruta de archivo para mantener un registro de errores, por ejemplo:2>/tmp/myLog
  4. &al final significa: ejecutar este comando como una tarea en segundo plano.
Yoichi
fuente
49
Esta debería ser la respuesta aceptada, porque es de mucha mayor calidad que la actualmente aceptada.
L0j1k
2
@ L0j1k discutible, OP ha demostrado un nivel de comprensión que requiere una pequeña explicación para la respuesta aceptada.
JFA
41
SO no se trata tanto del OP como de las miles de personas que acuden a la pregunta de OP en busca de ayuda.
L0j1k
3
¿Es necesario redirigir stdout y stderr? ¿Funcionaría igual de bien si no los redirigiera? ¿O si los redirigí a archivos?
Shawn
10
Enviar stdout y stderr a /dev/null? Buen registro ... Buena suerte tratando de depurar esto ...
Victor Schröder
138

Realmente deberías intentar usarlo screen. Es un poco más complicado que solo hacerlo nohup long_running &, pero entender la pantalla una vez que nunca vuelves.

Comience su sesión de pantalla al principio:

user@host:~$ screen

Ejecuta lo que quieras:

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

Presione ctrl + A y luego d. Hecho. Tu sesión continúa en segundo plano.

Puede enumerar todas las sesiones screen -lsy adjuntarlas a algunas por screen -r 20673.pts-0.srvcomando, donde 0673.pts-0.srv es una lista de entradas.

Alex Povar
fuente
125

Esta es una vieja pregunta, pero ocupa un lugar destacado en Google. Casi no puedo creer en las respuestas más votadas, porque ejecutar un proceso node.js dentro de una sesión de pantalla, con &o incluso con la nohupbandera, todas ellas, son solo soluciones.

Especialmente la solución screen / tmux, que realmente debería considerarse una solución amateur . Screen y Tmux no están diseñados para mantener los procesos en ejecución, sino para multiplexar sesiones de terminal. Está bien, cuando está ejecutando un script en su servidor y desea desconectarse. Pero para un servidor node.js no desea que su proceso se adjunte a una sesión de terminal. Esto es muy frágil. ¡Para mantener las cosas en funcionamiento, debe demonizar el proceso!

Hay muchas buenas herramientas para hacer eso.

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

Una gran ventaja que veo a favor de PM2 es que puede generar el script de inicio del sistema para que el proceso persista entre reinicios:

$ pm2 startup [platform]

Donde platformpuede haber 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

Guiones de inicio :

No voy a entrar en detalles sobre cómo escribir un guión de inicio, porque no soy un experto en este tema y sería demasiado largo para esta respuesta, pero básicamente son simples guiones de shell, activados por eventos del sistema operativo. Puedes leer más sobre esto aquí

Docker :

Simplemente ejecute su servidor en un contenedor Docker con -dopción y, ¡ voilá , tiene un servidor demonizado node.js!

Aquí hay un Dockerfile de muestra (de la guía oficial de 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" ]

Luego construye tu imagen y ejecuta tu contenedor:

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

Espero que esto ayude a alguien a aterrizar en esta página. Utilice siempre la herramienta adecuada para el trabajo. ¡Le ahorrará muchos dolores de cabeza y más horas!

Victor Schröder
fuente
2
Esto es lo que estaba buscando. Con la solución pm2, ¿hay alguna forma de conectarle un terminal más tarde?
Quantumplation
44
@ Cuantificación, no. Eso no es posible porque el proceso no se ejecuta en una sesión interactiva. Pero puede tener el mismo "sentimiento" tail -fal ingresar el archivo de registro que genera pm2.
Victor Schröder
1
Usted especifica la screensolución que muchas personas están encontrando para el trabajo es una solución alternativa. Hay muchas formas de lograr una tarea específica. Creo que sucede que (considere la pregunta específica) está logrando la tarea específica de run as background and never dieexcelente para muchos. También tiene la ventaja adicional de permitir que el usuario regrese a él para volver a interactuar y realizar cambios si lo desea. La clave es componentes es backgroundy never die. Todas las soluciones tienen ciertas bonificaciones.
LD James
@Rakshith Ravi - No estoy de acuerdo. Todos estos requieren descargas / software / herramientas adicionales (excepto la solución init, a la que no se le dio ninguna solución). El nohup es la solución. Está integrado en Linux, y es para lo que está allí. Es una línea, está limpia y funciona según lo previsto, siempre, independientemente de las actualizaciones. Las personas realmente deberían tratar de evitar el uso de herramientas de terceros para casos de uso básicos como este. El ejemplo de Docker (por ejemplo) es mucho más detallado y requiere más recursos que el comando simple en la respuesta más votada. Amo a Docker, pero no por esto.
Jack_Hu
1
@Jack_Hu, no tengo dudas sobre los gastos generales, pero la nohupsolución no satisface el requisito de "nunca morir". A menos que escriba un trapbucle infinito muy complicado o hacky, no veo cómo mantener el proceso demonizado sin usar herramientas especialmente escritas para este propósito (o un script de inicio escrito por usted mismo, por supuesto).
Victor Schröder
24

otra solución desconoce el trabajo

$ nohup node server.js &
[1] 1711
$ disown -h %1
myururdurmaz
fuente
Desconocido es exactamente lo que estaba buscando, pero ¿qué hace -h flag? No puedo encontrarlo en el manual
Rimantas Jacikevicius
desde la página de manual: si se da la opción -h, cada especificación de trabajo no se elimina de la tabla, sino que se marca para que SIGHUP no se envíe al trabajo si el shell recibe un SIGHUP. Si no se proporciona una especificación de trabajo, la opción -a significa eliminar o marcar todos los trabajos;
myururdurmaz
14

nohuppermitirá que el programa continúe incluso después de que la terminal muera. En realidad, he tenido situaciones en las que nohupimpide que la sesión SSH finalice correctamente, por lo que también debe redirigir la entrada:

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

Dependiendo de cómo nohupesté configurado, es posible que también deba redirigir la salida estándar y el error estándar a los archivos.

Daniel Gallagher
fuente
7

Tengo esta función en mi archivo rc de shell, según la respuesta de @ Yoichi:

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

Puedes usarlo de esta manera:

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

Nohup y la pantalla ofrecen excelentes soluciones ligeras para ejecutar Node.js en segundo plano. El administrador de procesos Node.js ( PM2 ) es una herramienta útil para la implementación. Instálelo con npm globalmente en su sistema:

npm install pm2 -g

ejecutar una aplicación Node.js como demonio:

pm2 start app.js

Opcionalmente, puede vincularlo a Keymetrics.io, un SAAS de monitoreo realizado por Unitech.

Donald Derek
fuente
6
$ disown node server.js &

Eliminará el comando de la lista de tareas activas y lo enviará a segundo plano.

Skynet
fuente
5

¿Has leído sobre el comando nohup ?

S.Lott
fuente
3

Para ejecutar el comando como un servicio del sistema en debian con sysv init:

Copie el script de esqueleto y adáptelo a sus necesidades, probablemente todo lo que tiene que hacer es establecer algunas variables. Su script heredará valores predeterminados finos /lib/init/init-d-script, si algo no se ajusta a sus necesidades, anúlelo en su script. Si algo sale mal, puede ver los detalles en la fuente /lib/init/init-d-script. Los vars obligatorios son DAEMONy NAME. El script se usará start-stop-daemonpara ejecutar su comando, en el START_ARGSque puede definir parámetros adicionales 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

Así es como ejecuto algunas cosas de Python para mi wiki de 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
}

Además de configurar vars, tuve que anular do_stop_cmddebido a que Python sustituye al ejecutable, por lo que el servicio no se detuvo correctamente.

usuario3132194
fuente
3

Además de las soluciones interesantes mencionadas anteriormente, mencionaría también las herramientas de supervisión y monitoreo que permiten iniciar el proceso, monitorear su presencia e iniciarlo si murió. Con 'monit' también puede ejecutar algunas verificaciones activas como verificar si el proceso responde a la solicitud http

Krzysztof Księżyk
fuente
3

Para Ubuntu uso esto:

(exec PROG_SH &> / dev / null &)

Saludos

David Lopes
fuente
Punto menor: 'exec' no es necesario si PROG_SH es un ejecutable. El punto de la solución propuesta por David es desasociar al niño del shell actual. El padre del niño se convierte en 'pid 1' y no se verá afectado cuando finalice el shell.
SoloPilot
0

Prueba esto para una solución simple

cmd y salir

Hunter Frazier
fuente