Node.js

Hacer proxy con Apache para aplicaciones node.js

Tenemos una app desarrollada en nodejs que corre en el puerto 4000 de nuestro servidor y queremos exponerla por el puerto 80 para que la gente pueda usarla. El problema obvio es que por lo general tenemos corriendo un apache, nginx o cualquier otro servidor http.

La solución es usar los módulos de proxy que incluyen cada uno de estos servidores web. Hoy puntualmente lo vamos a hacer con Apache.

Habilitamos los modulos proxy y proxy_http para permitir el reenvío de peticiones HTTP y HTTPS:

sudo a2enmod proxy
sudo a2enmod proxy_http

Luego nos queda crear un vhost:

sudo nano /etc/apache2/sites-available/mipaginaweb.com

Y ponerle lo siguiente:

<virtualhost *:80>
    ServerName mipaginaweb.com
    ServerAlias www.mipaginaweb.com
    ProxyRequests off
    <proxy *>
        Order deny,allow
        Allow from all
    </proxy>
    <location "/">
        ProxyPass http://localhost:4000/ retry=0
        ProxyPassReverse http://localhost:4000/
    </location>
</virtualhost>

Habilitamos nuestro nuevo vhost:

sudo a2ensite mipaginaweb.com

Hemos terminado. reiniciamos apache y a correr!

sudo service apache2 restart

Bonus: si estas en un entorno de desarrollo y quieres acceder a mipaginaweb.com, edita tu archivo hosts (sudo nano /etc/hosts) y añade tu nuevo dominio:

127.0.0.1 localhost
127.0.0.1 mipaginaweb.com www.mipaginaweb.com

Comentarios

  1. jorge

    tengo una pregunta
    es posible reescribir las urls antes de pasarlas a nuestro servidor node js?
    algo así como un rewriteRule, para acceder desde node solo a los querystring y no tener que procesar demasiado la url
    Espero sus comentarios

    Responder
      1. jorge

        Algo así:
        Sabemos que tenemos dos dominios, mipaginaweb1.com y mipaginaweb2.com
        Se supone que mipaginaweb2.com es nuestra app en node (la otra, un index html común y corriente)
        Un usuario trata de acceder a http://www.mipaginaweb2.com
        Apache lo redirecciona a http://localhost:4000/
        La pregunta es, si un usuario tratara de acceder (por ejemplo) a la página http://www.mipaginaweb2.com/users/fulanodetal
        ¿existiría alguna forma de reescribir esa url antes de redirigir, para que esta quede del siguiente modo?: mipaginaweb2.com?location=users&search=fulanodetal
        Algo así como lo que hacemos con htaccess
        Saludos, y gracias por su atención

        Responder
  2. Capy Autor

    aaaaaaaa ya te entendí. Bueno acá Apache es transparente, y lo único que esta haciendo reenviar la petición. no cumple ningún rol a demás de ese, ni debe hacerlo ya que el día de mañana puede que tu proxy sea nginx o varnish. Quiero decir con esto que ni si quiera deberías plantear hacer algo así desde apache, déjale eso a tu app.

    Si tu app esta hecha en express ya tenes un sistema de ruteo mucho mas fácil que la reescritura de urls.

    por ejemplo:

    function buscar(donde, quecosa, callback) {
        //implementa la logica de tu busqueda aqui
        callback(null, "aqui va el contenido a devolver")
    }
    server.get('/users/:usuario', function (req, res) {
        buscar("users", req.params.usuario, function (err, respuesta) {
            if (err) throw err;
            return  res.send(respuesta);
        });
    });
    

    Esto ya te permitiría usar url del tipo “http://www.mipaginaweb2.com/users/fulanodetal”, “http://www.mipaginaweb2.com/users/fulanodecual”

    Las reescrituras de url son pasado en nodejs, básicamente porque frameworks como expressjs ya traen de serie sistemas de routing.

    Para terminar por si no ha quedado claro: las reescrituras de url nacieron porque no era posible a nivel de aplicación definir urls del tipo /usuario/pedro y mapearla a una funcion. (PHP por ejemplo) Para lograrlo habia que pedirle al servidor web que re interpretara esa url a parámetros que se pudieran pasar a un archivo que los leyera y que llamara a una función en consecuencia.
    Y la cosa con nodejs es distinta, ya que node al ser servidor web y aplicación web al mismo tiempo es capaz de mapear directamente urls a funciones (como el ejemplo que dejé arriba).

    Saludos.

    Responder
  3. David Hernandez

    Disculpe, soy nuevo en este mundo de node.js queria saber si tengo una pagina hecha en frames por ejemplo, y contiene un index.html en una frame y otro index.jade en otro frame, como puedo hacer para correr dicha pagina principal donde corran ambas paginas? Ya que por un servidor apache no correria los websockets del index.jade, y no tengo idea como ejecutar un html desde node.js, Gracias por su atencion

    Responder
    1. Capy Autor

      Hola David. Suponiendo que estas usando expressjs, fa forma de servir documentos con extensión .html es esta: http://www.hacksparrow.com/how-to-server-static-html-files-in-express-js.html

      Frames… a ver, supongamos que tenes tupagina.com/home y en esa home se renderiza una pagina que tiene dos iframe. pues lo único que tendrías que hacer es apuntar la url de cada uno de los frame a una url que hayas definido en express, y en cada una de esas nuevas rutas entregas el el .jade o .html que quieras…

      Perdón por dar una respuesta tan poco precisa, pero es que no se muy bien qué necesitas.

      Un saludo.

      Responder
  4. Dave Olvera

    Hola que tal me preguntaba si esto del proxy es lo que necesito para redireccionar una petición a otro dominio. Por ejemplo digamos que yo tengo mi aplicación en el dominio a.com (node.js) desde esta aplicación yo hago un request a mi propio dominio, entonces desde node.js ¿Puedo hacer una segunda petición a mi dominio b.com?

    Pregunto esto porque no quiero hacer la petición directamente desde el cliente ya que es necesario que la url b.com no se mantenga expuesta.

    Saludos!!!

    Responder
    1. Capy Autor

      Bueno según entiendo, quieres que la gente entre en a.com y que internamente esa petición se mande a b.com para que b.com la responda y tu la devuelvas finalmente por a.com

      En ese caso es algo parecido a lo que se menciona en este post:
      mipaginaweb.com = a.com
      http://localhost:4000 = b.com

      A resumidas cuentas un dominio se esconde detrás del otro.

      Espero que lo consigas. Un saludo.

      Responder

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *

Puedes usar las siguientes etiquetas y atributos HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>