¿Cómo usar vhosts junto con node-http-proxy?

Estoy ejecutando Nodejs y Apache uno junto al otro.

node-http-proxy está escuchando en el puerto 80 y luego reenviando solicitudes a Apache (: 9000) o a Express (: 8000).

Mis servidores virtuales en Apache se ven así:

 DocumentRoot "/localhost/myVhost" ServerName myVhost  

Mi pregunta es, ¿cuál es la forma “correcta” de tener funcionalidad vhost en el lado Express / Nodejs? Preferiría no tener que colocar cada aplicación de Nodejs en su propio puerto como se sugiere aquí:

https://github.com/nodejitsu/node-http-proxy (Sección titulada “Solicitudes de proxy usando una ‘ProxyTable’ ‘Hostname Only’ ‘)

Noté que Connect (que según tengo entendido, se incluye en Express) tiene alguna funcionalidad de vhosts. Debería estar usando eso? Si es así, ¿cuál sería la forma correcta de ejecutarlo junto con node-http-proxy?

http://www.senchalabs.org/connect/middleware-vhost.html

También noté que este otro módulo llamado “Cluster”, parece estar relacionado, pero no estoy seguro de cómo:

http://learnboost.github.com/cluster/

Aunque no quería abrumarme, también encontré uno llamado, “Haibu”, que parece estar relacionado, pero no estoy seguro de si sería un reemplazo completo para usar fantasmas:

https://github.com/nodejitsu/haibu

Nota: soy un tipo de front-end, así que no estoy muy familiarizado con mucha terminología de servidor

    Nunca descubrí Haibu o Cluster. Pero encontré una buena solución que abordó mi problema. Para mi sorpresa, en realidad fue bastante simple. Sin embargo, no sé mucho sobre los servidores, así que mientras esto funcione, puede que no sea óptimo.

    Configuré hosts virtuales como normal en Apache (http://httpd.apache.org/docs/2.0/vhosts/examples.html)

    Instalé lo siguiente en Node

    Luego, como una cuestión de estilo personal, puse todos mis hosts virtuales en un directorio común (/ localhost)

    Luego cambié Apache para escuchar en un puerto que no sea el puerto 80. Simplemente escogí el puerto 9000 porque lo había visto en alguna parte. (En httpd.conf, cambió “Listen 80” a “Listen 9000”). También tuve que asegurarme de que todos mis hosts virtuales, como se define en extra / httpd-vhosts.conf, se configuraron en un nombre basado en IPVirtualHost (127.0.0.1) en lugar de usar un puerto (*: 80).

    En el lado del Nodo, creé mi aplicación / servidor (también conocido como host virtual de nodo) que escuchaba en el puerto 8000 (elección del número de puerto de algún modo arbitraria). Vea este enlace sobre cómo crear un servidor con express: http://expressjs.com/guide. html

    En mi directorio / localhost, creé un archivo llamado “nodeHttpProxy.js”

    Utilizando node-http-proxy, en nodeHttpProxy.js, creé un servidor proxy que escucha en el puerto 80. Usando express, que wraps connect (http://www.senchalabs.org/connect/) Creé mis hosts virtuales.

    El archivo nodeHttpProxy.js se ve así:

     // Module dependancies var httpProxy = require('/usr/local/lib/node_modules/http-proxy/lib/node-http-proxy') , express = require('/usr/local/lib/node_modules/express/lib/express'); // Http proxy-server httpProxy.createServer(function (req, res, proxy) { // Array of node host names var nodeVhosts = [ 'vhost1' , 'vhost2' ] , host = req.header('host') , port = nodeVhosts.indexOf(host) > -1 ? 8000 : 9000; // Now proxy the request proxy.proxyRequest(req, res, { host: host , port: port }); }) .listen(80); // Vhosts server express.createServer() .use(express.vhost('vhost1', require('./vhost1/app'))) .use(express.vhost('vhost2', require('./vhost2/app'))) .app.listen(8000); 

    Como puede ver, tendré que hacer dos cosas cada vez que creo un nuevo host virtual Node:

    1. agregue el nombre de host virtual a mi matriz “nodeVhosts”
    2. definir un nuevo host virtual express usando el método .set

    Por supuesto, también tendré que crear la ruta / archivos de host reales en mi directorio / localhost.

    Una vez hecho todo esto, solo necesito ejecutar nodeHttpProxy.js:

     node nodeHttpProxy.js 

    Es posible que obtenga un error raro de “EACCESS”, en cuyo caso, simplemente ejecute como sudo.

    Escuchará en el puerto 80, y si el host coincide con uno de los nombres en la matriz nodeVhosts, reenviará la solicitud a ese host en el puerto 8000, de lo contrario enviará la solicitud a ese host en el puerto 9000.

    He estado reflexionando sobre esto últimamente ya que estoy abordando los mismos problemas en mi entorno de prueba personal. No podrá desplazarse para que cada aplicación de nodo se ejecute en su propio puerto, pero puede abstraer el dolor de ese proceso. Esto es lo que estoy usando ahora, pero espero construir un paquete de npm alrededor de esto para simplificar las cosas en el futuro.

    Cada una de mis aplicaciones node.js tiene un archivo de mapa que contiene el puerto en el que la aplicación está escuchando, así como un mapa que indica la ruta esperada en la que se está atendiendo la aplicación. El contenido del archivo se ve así:

     {"path": "domain.com/path", "port": 3001} 

    Cuando inicio mi aplicación, leerá el puerto del archivo map.json y escuchará en el puerto especificado.

     var map = fs.readFileSync('map.json', 'ascii'); app.listen(map.port); 

    Luego, en la configuración de mi proxy, itero sobre cada uno de los directorios de mi aplicación node.js y busco un archivo map.json que indique que el tráfico del puerto 80 debe enviarse a esta aplicación.

    Uso casi el mismo método para configurar el proxy para nuestras aplicaciones alojadas de apache también. Utilizamos una convención basada en carpetas en los sitios web de PHP a los que prestamos servicio y utiliza la siguiente configuración:

     VirtualDocumentRoot /var/www/%-2.0.%-1/%-3+/ VirtualScriptAlias /var/www/%-2.0.%-1/%-3+/cgi-bin/ 

    Esto esencialmente nos permite mapear dominios en carpetas usando la siguiente estructura.

     http://sub.domain.com/ = /var/www/domain.com/sub/ 

    No se necesita configuración adicional para agregar o eliminar sitios. Esto está muy cerca de lo que estoy usando actualmente para proxy tanto en los sitios apache como en los nodos. Puedo agregar un nuevo nodo y nuevos sitios de Apache sin modificar esta aplicación proxy.

    proxy.js

     var fs = require('fs'); var httpProxy = require('http-proxy'); var proxyTable = []; // Map apache proxies fs.readdirSync('/var/www/').forEach(function(domain) { fs.readdirSync('/var/www/' + domain).forEach(function(path) { var fqd = domain + '/' + path; var port = fs.readFileSync('port', 'ascii'); proxyTable[fqd] = fqd + ':' + 8080; }); }); // Map node proxies fs.readdirSync('/var/www-node/').forEach(function(domain) { var map = fs.readFileSync('map.json', 'ascii'); proxyTable.[map.path] = '127.0.0.1:' + map.port; }); var options = { router: proxyTable }; var proxyServer = httpProxy.createServer(options); proxyServer.listen(80); 

    En el futuro, probablemente desacople la ruta desde el puerto en el que la aplicación está escuchando, pero esta configuración me permite construir el mapa proxy automáticamente con muy poco trabajo. Espero que esto ayude.

    Me inspiré en @uglymunky y escribí un guión de cocinero para hacer esto en Ubuntu.

    Con este script puedes instalar express y apache con soporte de vhost en un solo servidor usando 1 línea después de que hagas un pull down de mi proyecto de chef de github

    https://github.com/toranb/ubuntu-web-server

    Si tienes instalado Git y lo retiras, puedes patearlo así …

     sudo ./install.sh configuration.json 

    Esto requiere Ubuntu 12.04 o superior, ya que aproveché un script upstart para iniciar el nodo cuando reinició la máquina

    Cuando la secuencia de comandos finalice, tendrá un servidor web ubuntu en funcionamiento con Express para ejecutar las aplicaciones de nodo que haya configurado, junto con apache para ejecutar cualquier aplicación wsgi que haya configurado

    Estoy trabajando en una biblioteca extremadamente minimalista y al punto que puede ser totalmente segregada de sus proyectos. Básicamente, la idea se ejecutará de forma independiente en sus servidores y no se preocupe de tener que agrupar esto en sus proyectos como lo haría con la conexión.

    Eche un vistazo al archivo config.json para ver qué tan simple es realmente configurarlo.

    Estaba buscando esto y encontré algunas cosas, pero no admitían todo lo que necesitaba, ¡específicamente HTTPS, WS y WSS!

    En este momento, la biblioteca que escribí solo funciona para HTTP. Pero en los próximos días espero tenerlo terminado y trabajando para HTTPS, WS y WSS también.