Как использовать vhosts вместе с node -http-proxy?
Я запускаю Nodejs и Apache рядом друг с другом.
node -http-proxy прослушивает порт 80, а затем перенаправляет запросы на Apache (: 9000) или в Express (: 8000).
Мои виртуальные хосты на Apache выглядят так:
<VirtualHost 127.0.0.1>
DocumentRoot "/localhost/myVhost"
ServerName myVhost
</VirtualHost>
Мой вопрос в том, что такое "правильный" способ иметь функции, подобные vhost на стороне Express/Nodejs? Я бы предпочел не размещать каждое приложение Nodejs на своем собственном порту, как предлагается здесь:
https://github.com/nodejitsu/node-http-proxy
(Раздел под названием "Запросы прокси, использующие только имя хоста" Прокси-сервер ")
Я заметил Connect (который, как я понимаю, получает в комплекте Express), имеет некоторые функции vhosts. Должен ли я использовать это? Если да, то каков был бы правильный способ запустить его вместе с node -http-proxy?
http://www.senchalabs.org/connect/middleware-vhost.html
Я также заметил этот другой модуль под названием "Cluster", он, похоже, связан, но я не уверен, как:
http://learnboost.github.com/cluster/
Не желая подавлять, я также наткнулся на одного из названных "Haibu", похоже, это связано, но я не уверен, что это будет просто замена для использования vhosts:
https://github.com/nodejitsu/haibu
Примечание. Я сторонний парень, поэтому я не очень хорошо знаком с терминологией сервера.
Ответы
Ответ 1
Я никогда не думал о Хайбу или Кластере. Но я нашел хорошее решение, которое касалось моей проблемы. К моему удивлению, на самом деле это было довольно просто. Тем не менее, я мало знаю о серверах, поэтому, пока это работает, оно может оказаться не оптимальным.
Я настроил виртуальные хосты, как обычно, на Apache
(Http://httpd.apache.org/docs/2.0/vhosts/examples.html)
Я установил следующее на Node
- Экспресс (http://expressjs.com/)
- node -http-proxy (https://github.com/nodejitsu/ node -http-proxy)
Затем, в личном стиле, я поместил все мои виртуальные хосты в общий каталог (/localhost)
Затем я переключил Apache для прослушивания на порт, отличный от порта 80. Мне просто удалось выбрать порт 9000, потому что я видел, что он где-то использовался. (В httpd.conf изменилось "Слушать 80" на "Слушать 9000" ). Я также должен был убедиться, что все мои виртуальные хосты, определенные в extra/httpd-vhosts.conf, были настроены на имя, основанное на IPVirtualHost (127.0.0.1), вместо использования порта (*: 80).
На стороне Node я создал мое приложение/сервер (aka Node виртуальный хост), который прослушивал порт 8000 (несколько произвольный выбор номера порта). См. эту ссылку при создании сервера с выражением: http://expressjs.com/guide.html
В каталоге my/localhost я создал файл с именем "nodeHttpProxy.js"
Используя node -http-proxy, в nodeHttpProxy.js я тогда создал прокси-сервер, который прослушивает порт 80. Использование express, с которым связано соединение (http://www.senchalabs.org/connect/), я создал мои виртуальные хосты.
Файл nodeHttpProxy.js выглядит следующим образом:
// 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);
Как вы можете видеть, мне придется делать две вещи каждый раз при создании нового виртуального хоста Node:
- добавить имя виртуального хоста в мой массив nodeVhosts
- определить новый экспресс-виртуальный хост с использованием метода .set
Конечно, мне также нужно будет создать фактический путь/файлы хоста в каталоге my/localhost.
Как только все это будет сделано, мне просто нужно запустить nodeHttpProxy.js:
node nodeHttpProxy.js
Вы можете получить какую-то странную ошибку "EACCESS", и в этом случае просто запустите sudo.
Он будет прослушивать порт 80, и если узел соответствует одному из имен в массиве nodeVhosts, он отправит запрос этому хосту на порт 8000, в противном случае он переадресует запрос на этот узел на порт 9000.
Ответ 2
В последнее время я размышлял над тем, как я решаю те же проблемы в своей личной тестовой среде. Вы не сможете обойтись тем, что каждое приложение node работает на своем собственном порту, но вы можете абстрагироваться от боли этого процесса. Вот что я сейчас использую, но я надеюсь построить пакет npm вокруг этого, чтобы упростить вещи в будущем.
В каждом из моих приложений node.js есть файл карты, содержащий порт, который прослушивает приложение, а также карту, которая указывает ожидаемый путь, на который выполняется приложение. Содержимое файла выглядит следующим образом:
{"path": "domain.com/path", "port": 3001}
Когда я запустил приложение, он прочитает порт из файла map.json и прослушает указанный порт.
var map = fs.readFileSync('map.json', 'ascii');
app.listen(map.port);
Затем в моей настройке прокси-сервера я перебираю все мои каталоги приложений node.js и проверяю файл map.json, который указывает, что трафик 80 порта должен быть проксирован этому приложению.
Я использую почти тот же самый метод для установки прокси-сервера для наших приложений, размещенных в apache. Мы используем соглашение на основе папок на веб-сайтах PHP, которые мы обслуживаем, и использует следующую конфигурацию:
VirtualDocumentRoot /var/www/%-2.0.%-1/%-3+/
VirtualScriptAlias /var/www/%-2.0.%-1/%-3+/cgi-bin/
Это существенно позволяет нам отображать домены в папки, используя следующую структуру.
http://sub.domain.com/ = /var/www/domain.com/sub/
Для добавления или удаления сайтов не требуется дополнительной настройки. Это очень близко к тому, что я сейчас использую для прокси-сервера как apache, так и node. Я могу добавить новые node и новые сайты apache без изменения этого прокси-приложения.
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);
В будущем я, вероятно, отключу путь от порта, который прослушивает приложение, но эта конфигурация позволяет мне автоматически создавать прокси-карту с очень небольшой работой. Надеюсь, это поможет.
Ответ 3
Я немного вдохновил @uglymunky и написал шеф-повар script, чтобы сделать это на Ubuntu.
С помощью этого script вы можете установить express и apache с поддержкой vhost на одном сервере, используя 1 строку после того, как вы отделите мой проект шеф-повара от github
https://github.com/toranb/ubuntu-web-server
Если у вас установлен git, и вы его вытаскиваете, вы можете отбросить его так...
sudo ./install.sh configuration.json
Это требует Ubuntu 12.04 или выше, поскольку я воспользовался выскочкой script для запуска node при перезагрузке машины
Когда закончится script, у вас будет рабочий веб-сервер ubuntu с выражением для запуска любых node приложений, которые вы настроили, на стороне apache для запуска любых настроенных вами приложений wsgi.
Ответ 4
Я работаю над чрезвычайно минимальной и точечной библиотекой, которая может быть полностью отделена от ваших проектов. В принципе, идея будет выполняться независимо на ваших серверах и никогда не беспокоится о том, чтобы связать это в ваших проектах с тем, как вы могли бы подключиться.
Взгляните на файл config.json, чтобы узнать, насколько просто настроить его.
Я искал это, и я нашел несколько вещей, но они не поддерживали все, что мне нужно, в частности HTTPS, WS и WSS!
Сейчас библиотека, которую я написал, работает только для HTTP. Но в ближайшие дни я надеюсь закончить работу и работать с HTTPS, WS и WSS.