node-header

Desplegar una aplicación Node.js como servicio Upstart (demonio)

Cuando quise desplegar mi app, imagine que iba a ser fácil, que lanzaba el comando “node miapp.js” y punto, pero aprendí a palos que así no va la cosa.

Para desplegar una aplicación web, necesitas que funcione como apache por lo menos: que puedas arrancarla, pararla, reiniciarla, ver su estado, acceder a su log, que se reinicie si se produce un error, etc etc etc.

Busque por Internet y leí un montón de artículos y foros que te dicen como montartelo: haciendo scripts en /etc/init.d y combinándolo con monit para reiniciarlo si se cae, Usando Upstart, lanzando la aplicación con “node miapp.js &” (proceso en background pero es la peor solución que leí en años), y alguna que otra mas.

La mas razonable fue la de Upstart, aunque ninguna de las soluciones fue bastante clara o completa como para copiar, pegar y arrancar. Por eso hice este script que toma en cuenta todo lo que hace falta para montar tu app como un servicio:

Puede parecer un poco largo, pero si lo lees detenidamente vas a ver que es bastante concreto:

  1. Autor y descripción: son parte básica de un script Upstart
  2. Variables de configuración para que no tengas que meterte entre el código para ajustar el script para cada nueva app que crees.
  3. Cuerpo del script.

Acá esta el mismo script sin comentarios:

Uso:

Por cada aplicación en nodejs que quieras montar tenes que crear un archivo en /etc/init/. El nombre del archivo tiene que terminar en .conf. por ejemplo miapp-service.conf. Una cosa importante es que el servicio que estas creando se llama como el archivo (sin el .conf), por lo que en nuestro ejemplo se va a llamar miapp-service.

Dentro de /etc/init/miapp-service.conf pegas el script y personalizas todo lo que haya hasta la linea divisoria.

Un par de aclaraciones:
env APP=app.js define el nombre del “index” de tu aplicación, y por lo general se usan o app.js o server.js. Pon el nombre de tu app sin el path hasta ella. Si tu aplicación lleva parámetros podes encerrar en comillas dobles algo asi como “env APP=app.js -extrasettings ../settrings.json”
env APP_DIR=/var/node/miapp el path hasta tu aplicación
env PID_NAME=miapp.pid pon el nombre que quieras, pero que sea único. por ejemplo, si tu app es una pagina web pon el nombre de tu pagina “mipaginaweb_com.pid” o algo así.
env USER=www-data y env GROUP=www-data no sería muy responsable usar root para ejecutar tu aplicación salvo que esta si que necesite estar en root, pero en el caso de que sea una pagina web, usa el usuario y grupo www-data así podes unificar criterios. Es solo una sugerencia, yo para mi app uso www-data aunque podes usar el grupo y usuario que te parezca mejor.
POST_START_MESSAGE_TO_LOG es solo un mensaje que se envía al log de la app cuando esta arranca.
NODE_BIN indica donde esta ubicado node, por lo general está en /usr/local/bin/node aunque si no estuviera allí podes cambiar este parámetro.
env SERVER_ENV=”production” Posiblemente tu aplicación web utilice entornos de “development“, “test” y “production“. Bien, especificalo acá.

El resto del script está comentado en código así que no añado nada.

Cuando hayas acabado ya vas a disponer de tu servicio y tratarlo como cualquier otro:

Espero que les sirva.

Chau!

15 Comments

  • Eugenio 13/07/2013

    El artículo es perfecto: útil y pedagógico. Felicidades!. Y me ha funcionado a la segunda 🙂

    En mi instalación Ubuntu 12.04.2 he tenido que cambiar el env NODE_BIN=/usr/local/bin/node por env NODE_BIN=/usr/bin/node

    Saludos
    .

  • siempre dejaba tirada mi aplicacion , lo que hacia era correrla en una tty (node app) y le daba por que no tenia tiempo de buscar pense que encontraria un comando por no leer bien el node -h o el manual pero parece ser que aun no hay una funcionalidad asi en el node propio , no es algo que me moleste pero en los tutoriales que vi nunca mencionaban nada de esto siendo que es algo muy importante, gracias por el script

  • Daniel Espinosa 07/09/2013

    Muchas gracias
    Estuve mucho tiempo buscando esto , en ubuntu corrió de maravilla (Y)

  • Yeison Cardona 15/11/2013

    Realmente útil, mejor explicado imposible!!
    Muchas gracias 😉

  • Alejonext 12/04/2014

    tengo una pregunta!!! cuando se tiene un “prestart”, desde la aplicación como se ejecuta?

    • Capy 16/04/2014

      Ni idea 🙁

  • Cesar 16/04/2014

    No me funciona en un debian 6 me sale unrecognized service

  • Jesus Perales 19/04/2014

    Creo que este script deberia de estar en github,igual lo buscare quiza ya lo tienes 😀

  • Pingback: Desplegar una aplicación Node.js como servicio systemd (demonio) | Capy

  • david 08/09/2015

    Bueníiiiiiisiiiiimo!!! Gracias!!!!!!!!

  • Jairo 05/10/2015

    Gracias por el script,

    estoy tratando de usarlo en Ubuntu 14.04 para levantar una aplicación generada con express-generator, sin embargo la aplicación no esta iniciando, cuando abro el archivo .pid veo que el proceso esta cambiando constantemente, alguien le pasa lo mismo? o tiene alguna idea de como solucionarlo?

    env LOG_FILE=/var/log/node/QA-CMMS.log
    env APP_DIR=/var/node/QA-CMMS
    env APP=app.js
    env PID_NAME=qa-cmms-co.pid
    env USER=www-data
    env GROUP=www-data
    env POST_START_MESSAGE_TO_LOG=”qa-cmms ha sido iniciada.”
    env NODE_BIN=/usr/bin/node
    env PID_PATH=/var/opt/node/run
    env SERVER_ENV=”production”

    esta es la configuración del script que tengo para mi aplicación

    • Jairo 06/10/2015

      Se soluciono solo con reiniciar el servidor

  • hector 27/10/2015

    Excelente entrega, hace unos meses había probado este script pero corriéndolo desde el usuario root pero ahora intento de nuevo con un usuario distinto y haciendo las debidas modificaciones y NO me funciona pudes ayudarme?

  • Jaider 13/07/2016

    Hola,

    Muy util el script, en ubuntu funciono de manera correcta, mas sin embargo en Centos si no lo he podido hacer funcionar, siempre sale el error de “exec: start-stop-daemon: not found”, no se si tienes una solución al respecto. Gracias.

  • Juan García 28/10/2016

    Muchas gracias por tu aporte, yo ya tenia un script muy simple usando upstart pero era muy simple comparado con este y no funcionaba bien, al principio pensé que con tu script se estaba iniciando 2 veces, pero luego me di cuenta que el comando que inicia el servicio manda todo al archivo de log, lo que paso es que también mi aplicación escribe todo en el archivo de log y por eso salia 2 veces todo, pero aparentemente funciona bien, el script que tenia antes era algo como esto:

    start on runlevel [2345]
    stop on runlevel [!2345]
    respawn
    respawn limit 10 5
    setuid administrador
    chdir /var/www/myapp
    env MYAPP_PORT=3002
    exec npm start

    Y tenia el inconveniente que pasados varios días, me metía a revisar y se estaba ejecutando en paralelo varias veces la aplicación, llegue a notar que corría hasta 7 veces simultáneamente la aplicación, ya les comento como me va con este nuevo script.

    Saludos.

:).