¿Cómo ejecuto una aplicación Node.js como su propio proceso?

195

¿Cuál es la mejor manera de implementar Node.js?

Tengo un Dreamhost VPS (eso es lo que llaman una VM ), y he podido instalar Node.js y configurar un proxy. Esto funciona muy bien siempre que mantenga abierta la conexión SSH con la que comencé el nodo.

respectTheCode
fuente
66
Hmm, me parece extraño que llames usando Forever como "desplegando node.js". ¿No es solo una herramienta de supervisión / supervisión de procesos? Por lo general, la implementación web significa (al menos lo que encuentro en los artículos) varias actividades interrelacionadas que hacen que una aplicación web esté disponible (esta herramienta de proceso es parte de ella). De todos modos, esta es una gran publicación aquí en StackOverflow, como he aprendido de las respuestas de todos.
mikong
Esta es solo la implementación más simple de node.js en Dreamhost. El objetivo era simplemente hacer que el nodo se ejecute de manera confiable como punto de partida para construir.
respectTheCode
¿Cómo ha manejado el reenvío del dominio al nodo de puerto en el que se ejecuta?
grm
2
@grm Uso HTTP-Proxy github.com/nodejitsu/node-http-proxy
respectTheCode
Estamos usando Elastic Beanstalk ahora y está funcionando bastante bien.
respectTheCode

Respuestas:

107

Respuesta de 2016 : casi todas las distribuciones de Linux vienen con systemd, lo que significa que para siempre, monit, PM2, etc. ya no son necesarias: su sistema operativo ya maneja estas tareas .

Cree un myapp.servicearchivo (reemplazando 'myapp' con el nombre de su aplicación, obviamente):

[Unit]
Description=My app

[Service]
ExecStart=/var/www/myapp/app.js
Restart=always
User=nobody
# Note Debian/Ubuntu uses 'nogroup', RHEL/Fedora uses 'nobody'
Group=nobody
Environment=PATH=/usr/bin:/usr/local/bin
Environment=NODE_ENV=production
WorkingDirectory=/var/www/myapp

[Install]
WantedBy=multi-user.target

Tenga en cuenta si es nuevo en Unix: /var/www/myapp/app.js debería tener #!/usr/bin/env nodeen la primera línea.

Copie su archivo de servicio en la /etc/systemd/systemcarpeta.

Informe a systemd sobre el nuevo servicio con systemctl daemon-reload.

Comenzar con systemctl start myapp.

Permitir que se ejecute en el arranque con systemctl enable myapp.

Ver registros con journalctl -u myapp

Esto se toma de Cómo implementamos aplicaciones de nodo en Linux, edición 2018 , que también incluye comandos para generar un AWS / DigitalOcean / Azure CloudConfig para construir servidores Linux / nodo (incluido el .servicearchivo).

mikemaccana
fuente
1
¿Alguna idea sobre cómo lidiar Failed to issue method call: Unit name ... is not valid.?
Julien Genestoux 01 de
1
@JulienGenestoux el nombre de la 'unidad' es el mismo que su servicio. Parece que hay una discrepancia allí. Después de copiar el archivo, /etc/systemd/systemes posible que deba ejecutarlo systemctl daemon-reload(systemd normalmente le dirá si es necesario). TBH esto se hace mejor como una pregunta separada.
mikemaccana 01 de
3
En lugar de copiar su archivo de servicio /etc/systemd/system, puede usarlo systemctl enable /full/path/to/myapp.service, lo que crea un enlace simbólico /etc/systemd/systempara usted.
Arne
1
¿Cómo se compara con pm2? ¿Puede reemplazar pm2 o pm2 ofrece funciones más necesarias?
Sergei Basharov
1
@VinodSrivastav nodese llama /var/www/myapp/app.jssolo. En Unix, si hace que un archivo sea ejecutable y la primera línea que comienza con #!/some/fileel archivo se interpretará con ese binario. Google 'intérprete Unix' para saber más.
mikemaccana
101

Usar para siempre . Ejecuta los programas Node.js en procesos separados y los reinicia si alguno muere.

Uso:

  • forever start example.js para iniciar un proceso
  • forever list para ver la lista de todos los procesos iniciados por forever
  • forever stop example.js para detener el proceso, o forever stop 0 para detener el proceso con el índice 0 (como se muestra en forever list).
David Tang
fuente
Esto esta cerca. Comienza bien pero no me deja detener nada. Pude cerrar sesión y volver a iniciarla y luego eliminar el proceso del nodo. Forever no lo reinició. Así que estoy pensando que algo sobre cómo funciona no es compatible con DH.
respectTheCode
@Kevin, ¡no puedes matar el proceso del nodo porque Forever mismo se ejecuta en el nodo! He agregado algunas instrucciones de uso a mi respuesta, incluido cómo detener un proceso. He estado usando esto en mi VPS y funcionó de maravilla.
David Tang el
forever stop 0tuvo un error y las cosas se desmoronaron a partir de ahí. He estado tratando de hacer esto sin root en su propio usuario para poder limpiarlo fácilmente una vez que encuentre la solución correcta. Ese puede ser mi problema. Lo investigaré un poco más.
respectTheCode
Tenía algo mal con npm que estaba causando problemas. Con npm y el nodo instalados correctamente, siempre funcionan muy bien. Lo que terminé haciendo fue agregar los comandos de inicio para siempre a un cronjob configurado para ejecutarse al reiniciar. Ahora estoy trabajando en una pequeña aplicación de nodo que me permitirá iniciar y detener los procesos para siempre.
respectTheCode
Hay una alternativa a Forever que utiliza la API de clúster nativa del nodo: github.com/superjoe30/naught
andrewrk
41

He escrito sobre mi método de implementación aquí: Implementar aplicaciones node.js

En breve:

  • Use el gancho post-recepción de git
  • Jake para la herramienta de compilación
  • Upstart como un contenedor de servicios para el nodo
  • Monit para monitorear y reiniciar las aplicaciones si bajan
  • nginx para enrutar solicitudes a diferentes aplicaciones en el mismo servidor
Ben
fuente
2
Si siempre tendré un único sitio Node en mi servidor, ¿puedo deshacerme de Nginx de forma segura?
Dor
3
El enlace parece estar roto
verybadalloc
@Dor Sé que esta es una respuesta tardía, pero no lo haría. Además de cosas como la terminación SSL y el almacenamiento en caché, un proxy inverso nginx frente al host le permite una mayor flexibilidad de infraestructura que ejecutar el nodo directamente en el puerto 80. También significa que no tiene que ejecutar el nodo como root, lo que creo que es un argumento bastante pesado a favor de la configuración de nginx.
Chris Browne
16

pm2 hace los trucos.

Las características son: Monitoreo, recarga de código activo, equilibrador de carga incorporado, secuencia de comandos de inicio automático y procesos de resucitación / volcado.

nickleefly
fuente
¿Es compatible con servicios como Heroku?
FRD
@FRD No creo que funcione con heroku, mira este artículo
nickleefly
9

Se puede utilizar monit, forever, upstartosystemd para iniciar su servidor.

Puede usar Varnish o HAProxy en lugar de Nginx (se sabe que Nginx no funciona con websockets).

Como solución rápida y sucia, puede usar nohup node your_app.js &para evitar que su aplicación termine con su servidor, pero forever, monity otras soluciones propuestas son mejores.

nponeccop
fuente
2
Un usuario "Sergey Yarotskiy" intentó editar su publicación diciendo que Nginx ahora es compatible con WebSockets (desde la versión 1.3). Rechacé la edición porque creo que debería publicarse como un comentario. (De lo contrario, tendría dos oraciones contradictorias en la misma publicación, lo cual es confuso).
Backlin
7

Hice un script de Upstart actualmente utilizado para mis aplicaciones:

description "YOUR APP NAME"
author "Capy - http://ecapy.com"

env LOG_FILE=/var/log/node/miapp.log
env APP_DIR=/var/node/miapp
env APP=app.js
env PID_NAME=miapp.pid
env USER=www-data
env GROUP=www-data
env POST_START_MESSAGE_TO_LOG="miapp HAS BEEN STARTED."
env NODE_BIN=/usr/local/bin/node
env PID_PATH=/var/opt/node/run
env SERVER_ENV="production"

######################################################

start on runlevel [2345]
stop on runlevel [016]

respawn
respawn limit 99 5

pre-start script
    mkdir -p $PID_PATH
    mkdir -p /var/log/node
end script

script
    export NODE_ENV=$SERVER_ENV
    exec start-stop-daemon --start --chuid $USER:$GROUP --make-pidfile --pidfile $PID_PATH/$PID_NAME --chdir $APP_DIR --exec $NODE_BIN -- $APP >> $LOG_FILE 2>&1
end script

post-start script
    echo $POST_START_MESSAGE_TO_LOG >> $LOG_FILE
end script

Personalice todo antes de #########, cree un archivo en /etc/init/your-service.conf y péguelo allí.

Entonces tú puedes:

start your-service
stop your-service
restart your-service
status your-service
Capy
fuente
Gracias, justo lo que necesitaba.
Nilson Morais
6

He escrito una guía bastante completa para implementar Node.js, con archivos de ejemplo:

Tutorial: Cómo implementar aplicaciones Node.js, con ejemplos

Cubre cosas como http-proxy, SSL y Socket.IO .

Rich Jones
fuente
Esto se ve genial. Estoy usando heroku para el desarrollo y el lanzamiento inicial, pero eventualmente necesitaré escalar heroku pasado e implementarlo directamente en EC2. Jugaré con esto cuando tenga tiempo.
respectTheCode
5

Aquí hay un artículo más largo sobre cómo resolver este problema con systemd: http://savanne.be/articles/deploying-node-js-with-systemd/

Algunas cosas para tener en mente:

  • ¿Quién comenzará su proceso de monitoreo? Forever es una gran herramienta, pero necesita una herramienta de monitoreo para mantenerse en funcionamiento. Eso es un poco tonto, ¿por qué no usar su sistema init?
  • ¿Puedes monitorear adecuadamente tus procesos?
  • ¿Estás ejecutando múltiples backends? Si es así, ¿tiene disposiciones establecidas para evitar que alguno de ellos derribe a los demás en términos de uso de recursos?
  • ¿Se necesitará el servicio todo el tiempo? Si no, considere la activación del socket (vea el artículo).

Todas estas cosas se hacen fácilmente con systemd.

Ruben Vermeersch
fuente
5

Si tiene acceso root, será mejor que configure un demonio para que se ejecute sano y salvo en segundo plano. Puede leer cómo hacer eso para Debian y Ubuntu en la publicación de blog Ejecutar Node.js como servicio en Ubuntu .

Seldaek
fuente
No pensé que tenía root, pero parece que solo tengo que habilitarlo en el panel web. Le voy a dar una oportunidad.
respectTheCode el
3

Por siempre hará el truco.

@Kevin: Deberías poder matar los procesos bien. Verificaría un poco la documentación un poco. Si puede reproducir el error, sería genial publicarlo como un problema en GitHub.

Marak
fuente
Quien es kevin El OP?
Peter Mortensen
2

Como dijo Box9, Forever es una buena opción para el código de producción. Pero también es posible mantener un proceso en marcha incluso si la conexión SSH está cerrada desde el cliente.

Si bien no es necesariamente una buena idea para la producción, esto es muy útil cuando se realizan largas sesiones de depuración, o para seguir la salida de la consola de largos procesos, o cuando sea útil para desconectar su conexión SSH, pero mantener el terminal vivo en el servidor para volver a conectarse más tarde (como iniciar la aplicación Node.js en casa y volver a conectarse a la consola más tarde en el trabajo para verificar cómo van las cosas).

Suponiendo que su servidor es un cuadro * nix, puede usar el comando de pantalla del shell para mantener el proceso en ejecución incluso si el cliente SSH está cerrado. Puede descargar / instalar la pantalla desde la web si aún no está instalado (busque un paquete para su distribución en Linux, o use MacPorts en OS X).

Funciona de la siguiente manera:

  1. Cuando abra la conexión SSH por primera vez, escriba 'pantalla'; esto iniciará su sesión de pantalla.
  2. Comience a trabajar normalmente (es decir, inicie su aplicación Node.js)
  3. Cuando haya terminado, cierre su terminal. Los procesos del servidor continuarán ejecutándose.
  4. Para volver a conectarse a su consola, vuelva al servidor, inicie sesión e ingrese 'screen -r' para volver a conectarse. Su antiguo contexto de consola volverá a aparecer listo para que pueda continuar usándolo.
  5. Para salir de la pantalla, mientras está conectado al servidor, escriba 'salir' en el indicador de la consola; eso lo colocará en el shell normal.

Puede tener múltiples sesiones de pantalla ejecutándose simultáneamente de esta manera si lo necesita, y puede conectarse a cualquiera de ellas desde cualquier cliente. Lea la documentación en línea para todas las opciones.

cjcela
fuente
Buena información para tener. Estoy de acuerdo en que no funcionaría para la producción, pero podría ser muy útil al depurar en un servidor remoto.
respectTheCode
¿por qué no usar nohup node myapp.js & 2> /var/log/myapp.log 1> / dev / null
markus_p
Encontré esto av útil youtube.com/watch?v=P4mT5Tbx_KE explicando nohupyforever
Vinod Srivastav
1

Forever es una buena opción para mantener las aplicaciones en funcionamiento (y es npm instalable como un módulo, lo cual es bueno).

Pero para una 'implementación' más seria, como la administración remota de la implementación, el reinicio, la ejecución de comandos, etc., usaría capistrano con la extensión de nodo.

https://github.com/loopj/capistrano-node-deploy

martyman
fuente
1

https://paastor.com es un servicio relativamente nuevo que se implementa en un VPS u otro servidor. Hay una CLI para insertar código. Paastor tiene un nivel gratuito, al menos lo tenía al momento de publicar esto.

ruffrey
fuente
1

Prueba node-deploy-server . Es un conjunto de herramientas complejo para implementar una aplicación en sus servidores privados. Está escrito en Node.js y usa npm para la instalación.

AndyGrom
fuente