Как использовать 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(раздел под названием "Запросы прокси с использованием ProxyTable только для имени хоста")
Я заметил, что Connect (который, как я понимаю, входит в состав Express) имеет некоторую функциональность vhosts. Должен ли я использовать это? Если это так, каков будет правильный способ запустить его вместе с node-http-proxy?
http://www.senchalabs.org/connect/middleware-vhost.html
Я также заметил этот другой модуль под названием "Кластер", он, кажется, связан, но я не уверен, как:
http://learnboost.github.com/cluster/
Не желая перегружать, я также натолкнулся на одно из них, называемое "Haibu", которое, похоже, связано, но я не уверен, что это будет просто заменой использованию vhosts:
https://github.com/nodejitsu/haibu
Примечание: я работаю на переднем крае, поэтому я не очень знаком с серверной терминологией
4 ответа
Я никогда не понимал, Хайбу или Кластер. Но я нашел хорошее решение, которое решило мою проблему. К моему удивлению, это было на самом деле довольно просто. Тем не менее, я не знаю много о серверах, так что, хотя это работает, оно может быть неоптимальным.
Я настраиваю виртуальные хосты как обычно на Apache (http://httpd.apache.org/docs/2.0/vhosts/examples.html)
Я установил следующее на узле
- Экспресс (http://expressjs.com/)
- узел-http-прокси (https://github.com/nodejitsu/node-http-proxy)
Затем, исходя из личного стиля, я разместил все свои виртуальные хосты в общем каталоге (/ localhost).
Затем я переключил Apache для прослушивания порта, отличного от порта 80. Мне просто пришлось выбрать порт 9000, потому что я видел, что он где-то использовался. (В httpd.conf изменилось "Listen 80" на "Listen 9000"). Я также должен был убедиться, что все мои виртуальные хосты, как определено в extra/httpd-vhosts.conf, были установлены на основе имени IPVirtualHost (127.0.0.1) вместо использования порта (*:80).
Со стороны узла, я создал свое приложение / сервер (он же виртуальный хост узла), который прослушивал порт 8000 (несколько произвольно выбирая номер порта). См. Эту ссылку для создания сервера с помощью Express: http://expressjs.com/guide.html
В моем / 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
Конечно, мне также нужно будет создать фактический путь к хосту / файлам в моем каталоге / localhost.
Как только все это будет сделано, мне просто нужно запустить nodeHttpProxy.js:
node nodeHttpProxy.js
Вы можете получить странную ошибку "EACCESS", в этом случае просто запустите от имени sudo.
Он будет прослушивать порт 80, и если хост соответствует одному из имен в массиве nodeVhosts, он перенаправит запрос этому хосту на порт 8000, в противном случае он перенаправит запрос на этот хост на порт 9000.
В последнее время я размышлял над этим, решая те же проблемы в моей личной тестовой среде. Вы не сможете обойтись без того, чтобы каждое приложение узла работало на своем собственном порте, но вы можете абстрагироваться от этого процесса. Вот что я использую сейчас, но я надеюсь создать пакет 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, так и узлов. Я могу добавить новый узел и новые сайты 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);
В будущем я, вероятно, отделю путь от порта, который прослушивает приложение, но эта конфигурация позволяет мне автоматически строить карту прокси без особых усилий. Надеюсь, это поможет.
Я работаю над чрезвычайно минимальной библиотекой, которая может быть полностью отделена от ваших проектов. По сути, идея заключается в том, чтобы запускать это независимо на ваших серверах, и вам никогда не придется беспокоиться о том, чтобы связать это в своих проектах, как при подключении.
Взгляните на файл config.json, чтобы увидеть, насколько он прост в настройке.
Я искал это и нашел несколько вещей, но они не поддерживали все, что мне было нужно, а именно HTTPS, WS и WSS!
Сейчас написанная мной библиотека работает только для HTTP. Но в следующие несколько дней я надеюсь, что он будет завершен и будет работать для HTTPS, WS и WSS.
Я черпал вдохновение у @uglymunky и написал сценарий шеф-повара, чтобы сделать это в Ubuntu.
С помощью этого скрипта вы можете установить Express и Apache с поддержкой vhost на одном сервере, используя 1 строку после того, как вы загрузили мой проект chef из github.
https://github.com/toranb/ubuntu-web-server
Если у вас установлен git и вы потянете его вниз, вы можете запустить его так, как...
sudo ./install.sh configuration.json
Для этого требуется Ubuntu 12.04 или выше, поскольку я воспользовался сценарием upstart для запуска узла при перезагрузке компьютера.
Когда сценарий будет завершен, у вас будет рабочий веб-сервер Ubuntu с Express для запуска любых настроенных вами узловых приложений, а также Apache для запуска любых настроенных вами приложений wsgi.