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>