Arrancar NodeJS como servicio en Linux (Debian)

Buenos días hoy la cosa va de NodeJS!

La verdad es que hasta fecha de hoy no me había dejado seducir por este lenguaje, personalmente le he tenido bastante «tirria» hasta que por razones que no vienen a cuento he tenido que leer y «picar» bastante sobre javascript,.. así que allá vamos!

Si vienes del mundo del PHP y de los servidores LAMP, es posible que todo esto te suene a chino por lo que recomiendo efusivamente una lectura a los siguientes enlaces:

Hasta ahora todo lo relacionado con este tipo de aplicaciones «web-based», colgaba de un Apache + modphp5 y ya teníamos resuelta la parte del servidor, las instancias que este arranca etc,… En cambio en NodeJS el tema es algo distinto.

Resulta que no solo implementamos nuestra aplicación, nosotros también implementamos todo el servidor HTTP completo. De hecho, nuestra aplicación web y su servidor web son básicamente lo mismo.

Para no entrar en detalles sobre como montar el servidor, disponéis de los links anteriores donde se detalla como hacerlo.

El tema de este post, es como hacer que nuestro servidor corra como servicio «para siempre».

Llegados a este punto nosotros arrancamos nuestro servidor desde el command line con:

# node server.js

Esto nos arranca a aplicación en primer plano pero si cerramos la conexión con el server ( incluso lanzando el proceso con un & al final para dejarlo en segundo plano ) este va a morir.

Existen varias herramientas y métodos para resolver esto:

En primer lugar podríamos utilizar nohup:

# nohup node server.js

Pero eso nos quita algo de control sobre este proceso a la hora de reiniciarlo y demás operaciones sobre este.

También podemos usar screen y dejarlo corriendo sobre este pero no me parece personalmente una solución muy óptima.

La mejor alternativa es usar las propias herramientas que NodeJS nos proporciona y juntarlas con nuestro sistema Linux.

De entre todas las herramientas que hay monit, PM2, o bien nodemon , la que más me ha interesado es  forever. De hecho puedes utilizar la que más te convenga o te guste.

Vamos a ver como con la ayuda de forever y un poco de shell scripting podemos convertir nuestro servidor en un servicio.

Básicamente lo que haremos es en primer lugar instalar forever.

npm install -g forever

Seguidamente sería una buena idea tener los PID’s de los procesos así como un poco de logs en algún sitio yo he escogido /var/run/ ( podríamos iniciar una eterna discusión sobre si es el mejor lugar o no donde dejar esto pero por el momento no entraremos en ello 😉 )

mkdir /var/run/forever

Si estas alojando como yo tus proyectos en el homedir del usuario con el que sueles conectar al servidor, DEJA DE HACERLO YA! Es hora de empezar a usar las best practices . Normalmente dejaremos los proyectos en lo que en Apache llamaríamos un DocumentRoot ( Ej: /var/www/sitioweb.com/ ) de este modo tendremos todo bien ordenado. Por lo tanto te sugiero mover todo tu directorio de trabajo a: /var/www/SERVICIO/ ( o como quieras llamarlo )

# mkdir /var/www/SERVICIO/

Yendo un paso más allá, en servidores que tengan más de una interfaz de red con diferentes IP’s asignadas a estas, es posible que nos interese configurar el servidor en un puerto determinado así como una IP específica en la que escuchar. Cabe mencionar que si estas utilizando algún módulo de Node como por ejemplo express , o similares, al final lo que acabamos llamando es a un método llamado .listen() en el objeto principal http. Es por ello que el primer argumento es el número de puerto y el segundo el hostname. Si no proporcionamos un nombre de host o el valor es nulo, por defecto el valor se pondrá a 0.0.0.0 lo que significa que escucha en todas las interfaces de red. Si por el contrario especificamos 127.0.0.1 o localhost, este servicio tan sólo podrá ser accedido desde el propio servidor, y finalmente si pasamos la dirección IP concreta solo escucharemos en esa IP. ( Ej: 217.126.99.233 )
 

Disponemos de 2 métodos:

Método A – Pasar parámetros en la línea de comandos como argumentos

Argumentos en la línea de comandos:

./server.js 9000 "localhost"

Código:

#!/usr/bin/env node

var app = require('express')();

var port = parseInt(process.argv[2], 10) || 80;
var interface = process.argv[3] || null;

app.listen(port, interface);

 

Método B – Utilizar variables de entorno ( Recomendado ) 

Variables de entorno

SERVER_PORT=9000 SERVER_IFACE="localhost" ./test.js

Código:

#!/usr/bin/env node

var app = require('express')();

var port = process.env.SERVER_PORT || 80;
var interface = process.env.SERVER_IFACE || null;

app.listen(port, interface);

De esta manera podemos utilizar las variables de entorno del shell para poder especificar el puerto y la interfaz/IP donde escuchar para atender luego las peticiones entrantes. Vamos a ello, a la parte divertida! 😀

touch /etc/init.d/SERVICIO
chmod a+x /etc/init.d/SERVICIO
update-rc.d SERVICIO defaults

Creamos con touch un fichero en /etc/init.d/ llamado SERVICIO ( o como quieras ) , le damos permisos de ejecución, y seguidamente le decimos a nuestro linux con el comando update-rc.d que este script va a ser un servicio a arrancar en los runlevels por defecto.

Ahora tan solo nos falta rellenar este script de inicio ( SERVICIO ) con una serie de líneas que nos permitan llamarlo al estilo:

# service SERVICIO start
# service SERVICIO stop
# service SERVICIO restart , etc,…

o bien

# /etc/init.d/SERVICIO start
# /etc/init.d/SERVICIO stop

Bien entonces metemos dentro del fichero lo siguiente:

#!/bin/sh

export PATH=$PATH:/usr/local/bin
export NODE_PATH=$NODE_PATH:/usr/lib/node_modules:/usr/local/lib/node_modules
export SERVER_PORT=80
export SERVER_IFACE='0.0.0.0'

case "$1" in
  start)
  exec forever --sourceDir=/var/www/SERVICE -p /var/run/forever start server.js
  ;;

  stop)
  exec forever stop --sourceDir=/var/www/SERVICE server.js
  ;;
esac

exit 0

Guardamos, salimos del editor, y listos! Ya puedes ejecutar tu servidor de NodeJS como servicio. Para saber más,enlaces relacionados:

 

Saludotes!

Deja un comentario