Iniciar automáticamente para siempre (nodo) al reiniciar el sistema

190

Estoy usando el módulo de nodo para siempre para mantener mi servidor de nodo en ejecución. Sin embargo, para siempre termina cuando hay un reinicio del sistema. ¿Hay alguna manera de que pueda iniciar automáticamente el servidor de nodo (con forever) cuando el sistema se reinicia?

Kehers
fuente
1
¿Está este servidor en la nube? ¿Tiene alguna secuencia de comandos de arranque para ello?
Jorge Aranda
66
Pedido PM2 ! También es compatible con la generación de scripts de inicio (systemd, systemv ...) pm2.keymetrics.io/docs/usage/startup
Unitech el

Respuestas:

341

Sugeriría usar crontab. Es facil de usar.

Cómo

  1. Para comenzar a editar, ejecute lo siguiente reemplazando el "usuario de prueba" con el usuario de tiempo de ejecución deseado para el proceso de nodo. Si elige un usuario diferente a usted, tendrá que ejecutar esto con sudo.

    $ crontab -u testuser -e
  2. Si nunca ha hecho esto antes, le preguntará con qué editor desea editar. Me gusta vim, pero recomendaré nano para facilitar su uso.

  3. Una vez en el editor, agregue la siguiente línea:

    @reboot /usr/local/bin/forever start /your/path/to/your/app.js
  4. Guarda el archivo. Debería recibir algún comentario de que el cron se ha instalado.

  5. Para obtener más confirmación de la instalación del cron, ejecute lo siguiente (nuevamente reemplazando "testuser" con su nombre de usuario objetivo) para enumerar los crons instalados actualmente:

    $ crontab -u testuser -l 

Tenga en cuenta que, en mi opinión, siempre debe usar rutas completas al ejecutar binarios en cron. Además, si la ruta a su script para siempre no es correcta, ejecute which foreverpara obtener la ruta completa.

Teniendo en cuenta esas foreverllamadas node, es posible que también desee proporcionar la ruta completa para node:

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

Otras lecturas

Julian Lannigan
fuente
2
Este enfoque es bueno, pero solo para aquellos casos en que el sistema se reinicia. Si el servidor se apaga y luego se enciende, este trabajo cron no se ejecutará.
ecdeveloper
66
¿Qué te hace pensar que? en.wikipedia.org/wiki/Cron#Predefined_scheduling_definitions Explica que los @rebootcron se ejecutan en el inicio del cron deamon. Para agregar, nunca me he encontrado con una situación que sugiera que mis cron que están configurados en @rebootno se ejecutan en el arranque del sistema. La forma en que lo apaga es irrelevante para esto.
Julian Lannigan
16
parece que /homeaún no está montado, por lo que esto no funcionará si su código vive /home.
chovy
66
Descubrí que lo anterior me falló porque el nodo no está en la ruta cuando cron intenta ejecutarse para siempre, incluso con la opción -c. Sin embargo, resulta que puede agregar una declaración PATH = directamente en el crontab siempre que esté por encima de las declaraciones de programación. Una vez que se establece PATH, la declaración @reboot funcionó como un sueño.
YorkshireKev
2
Gracias por tu comentario @chovy, fue muy útil. Para aquellos que usan variables de entorno de bashrc, tenga en cuenta su comentario. Como / home no está montado, no funcionará. Establezca las variables en el comando crontab como@reboot varname=value ...
lsborg
123

Puede usar el servicio para siempre para hacer esto.

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

Esto proporcionará app.js en el directorio actual como un servicio para siempre. El servicio se reiniciará automáticamente cada vez que se reinicie el sistema. Además, cuando se detenga, intentará una parada elegante. Este script también proporciona el script logrotate.

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

NOTA: Soy el autor de forever-service.

arva
fuente
2
Use la opción -e "PORT = 80 ENV = prod FOO = bar"
arva
2
No entiendo cómo ejecutar el servicio para siempre. ¿Qué es esa "prueba" en "prueba de instalación de servicio para siempre"? Mi comando para iniciar mi aplicación para siempre es: "/ usr / local / bin / forever start -c / usr / local / bin / node / home / alex / public / node_modules / http-server / bin / http-server -s - d falso ". ¿Qué tendría que escribir?
Alex
3
prueba aquí es el nombre del servicio. cuando ejecuta la prueba de instalación de servicio para siempre, crea un servicio llamado prueba, para ejecutar app.js en ese directorio que se ejecutará como un servicio. Sugeriría leer la documentación de ayuda en la página gihub y agregar un problema allí si no puede entenderlo.
arva
66
@Alex - para aclarar el comentario de arva - en el ejemplo forever-service install test, testserá el nombre del servicio , pero no el nombre del archivo .js del programa / nodo real a ejecutar. Por defecto, se supone que el nombre del programa es app.js, pero se puede anularlo con la --scriptbandera, de la siguiente manera: forever-service install test --script main.js. (No probado, así que corríjame si hay algún detalle de sintaxis incorrecto).
Dan Nissenbaum
3
@DanNissenbaum Gracias por responder. Ahora estoy usando PM2 que funciona muy bien. Instrucciones: digitalocean.com/community/tutorials/…
Alex
26

Este caso es válido para Debian.

Agregue lo siguiente a /etc/rc.local

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

  • {{user}} reemplaza su nombre de usuario.
  • {{app path}}reemplaza la ruta de su aplicación. Por ejemplo,/var/www/test/app.js
NiLL
fuente
2
Este método no trata con apagados elegantes, aunque para muchas personas esto probablemente no sea un problema.
UpTheCreek
66
Por cierto, creo que deberías estar editando /etc/rc.local, no/etc/init.d/rc.local
UpTheCreek
De acuerdo con @UpTheCreek en que /etc/rc.local es el lugar más apropiado para agregar esto; consulte: unix.stackexchange.com/a/59945 para obtener una excelente explicación.
So Over It
2
Además, es posible que desee especificar el 'directorio de trabajo actual' app.jspara garantizar que los archivos relativos se carguen correctamente - process.chdir('/your/path/to/your/app'); Node.js ref docs here
So Over It
1
Si necesita establecer variables de entorno para su script Node.JS (como $ PORT para express), agregar la siguiente línea /etc/rc.localme ( cd /path/to/project && /usr/bin/sudo -u {{user}} env PORT={{port number}} PATH=$PATH:/usr/local/bin sh -c "forever start app.js" )
sirvió
25
  1. Instale PM2 globalmente usando NPM

    npm install pm2 -g

  2. Comience su secuencia de comandos con pm2

    pm2 start app.js

  3. generar un script de inicio activo

    pm2 startup

    NOTA: el inicio de pm2 es para iniciar el PM2 cuando el sistema se reinicia. PM2 una vez iniciado, reinicia todos los procesos que había estado administrando antes de que el sistema se cayera.

En caso de que desee deshabilitar el inicio automático, simplemente use pm2 unstartup

Si desea que el script de inicio se ejecute bajo otro usuario, simplemente use la -u <username>opción y el--hp <user_home>:

fsamuel
fuente
No publique la misma respuesta a varias preguntas.
FelixSFD
Realmente me encanta cómo se refina pm2, y viene con una increíble herramienta de monitoreo. Espero que esto se destaque más para los demás. @ rv7 Estoy seguro de que vio esto, pero hay una solución de Windows: npmjs.com/package/pm2-windows-service . Sin embargo, no lo he probado.
John Lee
11

Un método alternativo de crontab inspirado en esta respuesta y esta publicación de blog.

1. Cree un archivo de script bash (cambie bob al usuario deseado).

vi /home/bob/node_server_init.sh

2. Copie y pegue esto dentro del archivo que acaba de crear.

#!/bin/sh

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

¡Asegúrese de editar las rutas anteriores de acuerdo con su configuración!

3. Asegúrese de que se pueda ejecutar el script bash.

chmod 700 /home/bob/node_server_init.sh

4. Pruebe el script bash.

sh /home/bob/node_server_init.sh

5. Reemplace "bob" con el usuario de tiempo de ejecución para el nodo.

crontab -u bob -e

6. Copie y pegue (cambie bob al usuario deseado).

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

Guarda el crontab.

Has llegado al final, tu premio es un reinicio (para probar) :)

Emre
fuente
Este método funcionó mejor para mí. Forever se cerraría cuando coloque una ruta completa al archivo server.js. Si lo ejecuté en el mismo directorio, foreveer funcionaría bien. La razón por la que falló es que el archivo server.js incluía otros archivos, pero las rutas estaban en mal estado. Usando este método, podría CD en mi script .sh en el directorio, luego ejecutar todo lo relativo a allí.
BeardedGeek
9

Respuesta copiada de la pregunta adjunta .

Puede usar PM2 , es un administrador de procesos de producción para aplicaciones Node.js con un equilibrador de carga incorporado.

Instalar PM2

$ npm install pm2 -g

Inicia una aplicación

$ pm2 start app.js

Si usa Express, puede iniciar su aplicación como

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

Listado de todos los procesos en ejecución:

$ pm2 list

Enumerará todo el proceso. Luego puede detener / reiniciar su servicio utilizando la ID o el nombre de la aplicación con el siguiente comando.

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

Para mostrar registros

$ pm2 logs ['all'|app_name|app_id]
Vikash Rajpurohit
fuente
¿Cómo se inicia AUTOMÁTICAMENTE en el arranque del sistema? Simplemente copie / pegue la escritura manual de CLI
Verde
@ Verde, Ejecutar, $pm2 startupdespués de eso verá pm2 pidiendo ejecutar manualmente un comando, copiar y ejecutar eso. Entonces, $pm2 saveahora su app.js sobrevivirá a los reinicios del sistema
yajnesh
7

Necesita crear un script de shell en la carpeta /etc/init.d para eso. Es un poco complicado si nunca lo ha hecho, pero hay mucha información en la web sobre scripts init.d.

Aquí hay una muestra de un script que creé para ejecutar un sitio CoffeeScript para siempre:

#!/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

Tenía que asegurarme de que la carpeta y las RUTA estuvieran establecidas explícitamente o disponibles para el usuario raíz ya que las secuencias de comandos init.d se ejecutan como raíz.

Héctor Correa
fuente
2
Si tiene dependencias que también se inician con init.d, es posible que tenga problemas de orden de carga.
UpTheCreek
@ alexandru.topliceanu He arreglado el enlace.
Héctor Correa
6

Usa el PM2

¿Cuál es la mejor opción para ejecutar el servidor de producción del servidor?

¿Cuáles son las ventajas de ejecutar su aplicación de esta manera?

  • PM2 reiniciará automáticamente su aplicación si se bloquea.

  • PM2 mantendrá un registro de sus excepciones no controladas, en este caso, en un archivo en /home/safeuser/.pm2/logs/app-err.log.

  • Con un comando, PM2 puede garantizar que cualquier aplicación que administre se reinicie cuando el servidor se reinicie. Básicamente, su aplicación de nodo comenzará como un servicio.

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

Vishnu Mishra
fuente
5

Forever no se creó para que las aplicaciones de nodo se ejecuten como servicios. El enfoque correcto es crear una entrada / etc / inittab (sistemas linux antiguos) o una fuente nueva (sistemas linux más nuevos).

Aquí hay alguna documentación sobre cómo configurar esto como un arranque: https://github.com/cvee/node-upstart

snez
fuente
Upstart me falló en CentOS y leí que va a desaparecer. Crear una entrada init.d no es realmente la forma más fácil de usar, pero supongo que es Linux :)
Jorre
5

crontabno me funciona en CentOS x86 6.5. @reboot parece no funcionar.

Finalmente obtuve esta solución:

Editar: /etc/rc.local

sudo vi /etc/rc.local

Agregue esta línea al final del archivo. Cambio USER_NAMEy PATH_TO_PROJECTpara los tuyos. NODE_ENV=productionsignifica que la aplicación se ejecuta en modo de producción. Puede agregar más líneas si necesita ejecutar más de una aplicación node.js.

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

No establezca NODE_ENVen una línea separada, su aplicación seguirá ejecutándose en modo de desarrollo, porque no siempre se obtiene NODE_ENV.

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

Guarde y salga de vi (presione ESC : w q return). Puede intentar reiniciar su servidor. Después de que su servidor se reinicie, su aplicación node.js debería ejecutarse automáticamente, incluso si no inicia sesión en ninguna cuenta de forma remota a través de ssh.

Será mejor que establezca el NODE_ENVentorno en su shell. NODE_ENVse configurará automáticamente cuando su cuenta USER_NAMEinicie sesión.

echo export NODE_ENV=production >> ~/.bash_profile

Para que pueda ejecutar comandos como detener / iniciar para siempre a /PATH_TO_PROJECT/app.jstravés de ssh sin configurarNODE_ENV nuevamente.

Vince Yuan
fuente
Tengo el mismo problema en Debian 7.6. Esto me solucionó. Muchas gracias.
Daniele Vrut
En caso de que no quiera usar 'para siempre', puede cambiar la línea a 'su - NOMBRE_USUARIO -c "NODE_ENV = nodo de producción / PATH_TO_PROJECT / bin / www"'.
yaobin
3

Escribí un script que hace exactamente esto:

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

No lo he intentado para siempre, pero puedes personalizar el comando que ejecuta, por lo que debería ser sencillo:

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

Intenté muchas de las respuestas anteriores. Ninguno de ellos funcionó para mí. Mi aplicación está instalada en /homey como usuario, no como root. Esto probablemente significa que cuando se ejecutan los scripts de inicio mencionados anteriormente,/home aún no está montado, por lo que la aplicación no se inicia.

Luego encontré estas instrucciones de Digital Ocean:

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

Usar PM2 como se explicó fue muy simple y funciona perfectamente: mis servidores virtuales tuvieron dos fallas físicas desde entonces: el tiempo de inactividad fue de aproximadamente un minuto.

Alex
fuente
PM2 tiene muchas más estrellas (2x) en Github, que para siempre, y también tiene más funciones. Creo que la mayoría de las respuestas son obsoletas aquí.
inf3rno
1

El problema con rc.local es que se accede a los comandos como root, lo que es diferente de iniciar sesión como usuario y usar sudo.

Resolví este problema agregando un script .sh con los comandos de inicio que quiero, etc / profile.d. Cualquier archivo .sh en profile.d se cargará automáticamente y cualquier comando será tratado como si usaras el sudo regular.

El único inconveniente de esto es que el usuario especificado necesita iniciar sesión para que las cosas comiencen, lo que en mi situación siempre fue el caso.

Moe Elsharif
fuente
0

ejemplo completo crontab (ubicado en / 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
fuente
-1

Puede usar el siguiente comando en su shell para iniciar su nodo para siempre:

forever app.js //my node script

Debe tener en cuenta que el servidor en el que se ejecuta su aplicación siempre debe mantenerse encendido.

Gaurav Singh
fuente