RSS Feed

NodeJS a la nube con NGINX en un VPS

20

marzo 25, 2013 by - @pjnovas

Anteriormente expliqué como poner productiva una app en NodeJS utilizando PaaS en NodeJS con Nodejitsu y Nodester, pero hace poco me puse a investigar para ir mas allá, así que me compré un VPS (Servidor Virtual Privado) e incursioné en el desafío.

Comprar un VPS, instalar una distribución de linux y configurar Node es bastante sencillo, luego bajar nuestro proyecto y ponerlo en funcionamiento tampoco tiene muchas vueltas, es lo mismo que en local en nuestras maquinas (todo por terminal/ consola). Pero la idea de un VPS es que no vamos a tener un solo proceso node, tenemos un servidor para nosotros, vamos a meter muchos procesos, varias bases de datos, la idea es que vamos más allá de una app en nodejs.

El puerto 80

Nos levantamos un servidor node en el puerto 80, y ahora?, no podemos usar el mismo puerto para otro servidor, pero queremos que la IP de nuestro VPS sirva ambos servidores.
Por ejemplo tener ejemplo.com y ejemplo2.com en el mismo servidor pero en 2 procesos distintos, es decir, cada proceso con un puerto diferente, pero para el usuario es el 80.

Virtual Hosts

Básicamente un virtual host nos va a permitir realizar un reverse proxy, es decir, cada request que nos ingresa al servidor por el puerto 80, manejamos que proceso de node sirve fijándonos el dominio por le que ingresó.

Bueno, hay algunas opciones para hacer esto en forma visual (que dependen de la distribución linux que hayamos elegido).
Para mi caso voy a ir con CentOS 6, para complicarla bien, ni siquiera podemos usar Kloxo (en la ver. 6 de CentOS), también tenemos otras opciones como puede ser WebMin, pero investigando un poco más me encontré con un punto interesante: si tenemos un VPS, donde lo importante (y limitante al bolsillo) es la transferencia mensual (entre otras cosas), no nos conviene utilizar estas herramientas web que simplemente al configurar vamos a estar consumiendo los recursos. No digo que es un limitante, pero es un punto importante aunque también es mas divertido meter mano lo máximo que se pueda. Así que descartemos estas herramientas.

Apache vs NGINX

Los que hayan usado Apache (por ejemplo para PHP) conocerán que es bastante simple configurar Virtual Hosts, pero yo tenia NodeJS, no PHP, y casualmente con Apache no vamos a estar utilizando el potencial de NodeJS así que seguí investigando y me encontré con NGINX, el cual es orientado a eventos, por lo que sería ideal para nuestro caso donde tenemos varios procesos NodeJS.

Instalando NGINX

La instalación va a depender de la Distribución de Linux / el SO que elijamos, para el caso de CentOS va por yum

wget http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm
rpm -ivh nginx-release-centos-6-0.el6.ngx.noarch.rpm
yum install nginx

Configurando NGINX

Como conté al inicio del post, es la primera vez que me meto en todo esto, así que la configuración que les voy a mostrar es lo básico para poner en funcionamiento nuestros servidores NodeJS, no mas que eso.

nginx (se pronuncia enyinex, como Engine X en inglés :P ), a diferencia de Apache, actual como un ReverseProxy antes que un HTTP Server. Y su configuración es parecida a un JSON con una suerte de herencia jerárquica, es decir, las configuraciones de abajo reemplazan a las de arriba (dependiendo el caso)

Sin meterme mucho en la configuración, ya que desconozco ampliamente (pueden ver mas acá), tenemos 3 componentes importantes:

http > server > location : donde server serían el equivalente al VirtualHost en Apache y location las rutas a los recursos (URIs).

Entonces, para nuestro caso particular donde queremos 2 procesos nodejs utilizando dominios distintos y que ambos sean accesibles desde la misma IP (de nuestro VPS) bajo el puerto 80, deberíamos crear un http, con 2 server y sus respectivas location (URI raíz) apuntando a nuestros procesos.

Así que primero, configuramos nuestros procesos de Node para que corran, por ejemplo, uno en el puerto 3000 y el otro en el 3050 y después armemos el config:

Abrimos el archivo de configuración para Linux:

vim /etc/nginx/nginx.conf
# acá otras configuraciones
http {
  server {
    listen   80;
    server_name ejemplo1.com www.ejemplo1.com *.ejemplo1.com;

    location / {
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header Host $http_host;
         proxy_set_header X-NginX-Proxy true;
         proxy_pass http://127.0.0.1:3000/;
         proxy_redirect off;
    }
  }

  server {
    listen   80;
    server_name ejemplo2.com www.ejemplo2.com *.ejemplo2.com;

    location / {
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_set_header Host $http_host;
         proxy_set_header X-NginX-Proxy true;
         proxy_pass http://127.0.0.1:3050/;
         proxy_redirect off;
    }
  }
}

Guardamos el config y arrancamos nginx

sudo service nginx start

Pueden ver un ejemplo de una configuración acá

Y listo!, ahora entramos a http://ejemplo1.com y nos levanta el servidor que tenemos en el puerto 3000 y si entramos a http://ejemplo2.com el del puerto 3050.

Mas info.

NGINX (Inglés)


  • http://twitter.com/pepoviola pepo

    Muy bueno!! saludos!

  • tito hernandez

    Pablo,

    muy interesante, este servidor ruso nginx está muy de moda.

    Entonces utilizar NodeJS con Apache como reverse proxy sería mala práctica? O sea, no se aprovecharía ninguna ventaja de NodeJS porque Apache hace un fork para atender cada request, verdad?

    • pjnovas

      Claro!, no se si llamarlo “mala practica”, pero no es lo más óptimo debido a la forma “orientada a eventos” en la que trabaja nodejs.
      Saludos!

  • Pingback: NodeJS a la nube con Nginx en un VPS | Tito Hernández

  • PepePepe

    Pensé que NGINX era un servidor y NodeJS otro donde el lenguaje es JS. :O, no comprendo. Necesitas NGINX para correr node?

    • pjnovas

      No necesitas NGINX para correr node, NGINX te ayuda como ReverseProxy para servir varias app/ servers hechos en node bajo el mismo puerto 80.

      Obviamente que también podes crear un server node que funcione como un ReverseProxy, pero la mayoría de las veces tenes varias apps node ya armadas, y querés publicarlas de manera simple y rápida bajo distintos dominios en el mismo Server (pero todos en el puerto 80).

      Saludos!

  • pelicanorojo

    Gracias por compartir toda esta magia!

  • Alx

    Que tal con NodeJS con Cherokee Server?

  • Pingback: maillot italie femme

  • Vincent

    Tengo dos dudas:
    1.No se puede usar nodejs como reverse proxy?, Es decir un server principal que corra por arriba de todo pero con el mismo node, y que redirija a los otros procesos?
    2. No se necesita un servidor de DNS o algo similar, solo con eso puedo poner el dominio.com en el browser y listo?

    • pjnovas

      Hola Vincent,
      1. Si, se puede totalmente, armé este post de esta manera porque fue el caso que viví yo y como me salió de investigarlo.
      2. Mmm, no entiendo bien, al registrar el dominio lo vas a apuntar a un DNS, si tenes un proceso node en el puerto 80 que escucha todo, si podrías hacer el direccionamiento.

      La verdad que suena interesante para probar, supongo que funcionaria bien sin problemas, en mi caso ya tenia mis express servers armados porque estaban hosteados en nodejitsu y nodester, me era mas facil poner un NGINX adelante sin tocar mucho.

      Saludos!

  • Brian eduardo Craig

    Pablo!
    Como andas ? Mira soy un pibe que a veces asiste a las reuniones del Meetup de Node.JS . Tu articulo esta excelente! , lastima que a mi no me funciono, algo habré hecho mal. Fuí probando muchos otros programas para solucionarlo, pero al final me encontré con el repositorio http-proxy de NPM, https://github.com/nodejitsu/node-http-proxy , el cual es excelente, ademas de estar escrito en node.js, y en solo unas pocas lineas podes configurarlo ( https://github.com/nodejitsu/node-http-proxy#proxy-requests-using-a-proxytable ).
    Lo que te comento es una alternativa, solo te quería comentarlo por que la verdad me sorprendió mucho.

    Un saludo y que siga creciendo tu Blog ! Es genial ! ( hasta el error 404 )

    • pjnovas

      Muy bueno!!, cuando tenga un rato lo voy a probar, gracias por el aporte!

    • pjnovas

      Brian, me acabo de cruzar con otro muy bueno configurable a través de un json: https://github.com/BlueJeansAndRain/proxima
      Me acordé de tu comentario y lo dejo acá.

      Saludos!

      • Brian eduardo Craig

        Genial Pablo ! Mientras estoy probando con el otro, pero cuando tenga un tiempo lo pruebo, es mucho mas configurable ( Estoy intentando hacer una App para hostear Apps )

        • pjnovas

          Copado proyecto, si lo haces open source pasate link y si tenes ganas armate un post tambien :)

          • Brian eduardo Craig

            Dale ! Igual no tengo Blog, pero si querés cuando lo termine, si es que lo hago, Te escribo una Entrada, y vos la Posteas !
            Por Ahora estoy haciendo Pruebas. Recién termine con Todo el quilombo de las DNS, y si te fijas
            http://node-js.com.ar/ te va a mi maquina al server 1, y http://a.a.node-js.com.ar/ va al server 3
            Cuando sea algo que por lo menos se pueda usar en forma privada ( Tiene muchos problemas de seguridad en el caso de que cada usuario suba su App ) lo subo a GitHub

          • Brian eduardo Craig

            Ya lo subí a GitHub, https://github.com/BrianCraig/vps , igual todavía le falta muuucho, cuando se pueda probar fácilmente te comento ( la idea es que tenga una interfaz web y mediante socket.io se maneja )
            Por ahora no mires el código mucho te vas a marear :3

          • pjnovas

            grosoooo … ;)

          • Brian eduardo Craig

            Ahí lo actualicé, tiene hasta Leeme ( funciona, pero hay que ser medio mago ) https://github.com/BrianCraig/vps