如何在具有不同域的同一IP /服务器上托管多个Node.js站点?

Guy*_*Guy 83 node.js

我有一个绑定了单个IP的Linux服务器.我想在此IP服务器上托管多个Node.js站点,每个站点(显然)都有一个唯一的域或子域.我希望他们都在80端口.

我有什么选择呢?

一个显而易见的解决方案似乎是让一个node.js网络应用程序服务的所有域都充当代理,并传递给在唯一端口上运行的其他node.js应用程序.

jos*_*736 77

选择以下之一:

  • 使用其他服务器(如nginx)作为反向代理.
  • 使用node-http-proxy作为反向代理.
  • 如果可以从同一个Connect/Express代码库和node.js实例提供每个域,请使用vhost中间件.

  • 这是我在其他地方读过的选项的非常好的简短列表.您是否碰巧知道每个解决方案在添加新域时需要重新启动哪些流程?1)没有.对于2)只有node-http-proxy.对于3)需要重新启动所有站点的整个线程.它是否正确? (3认同)

Ada*_*dam 48

Diet.js有一个非常好用且简单的方法来托管具有相同服务器实例的多个域.您只需server()为每个域调用一个新的.

一个简单的例子

// Require diet
var server = require('diet');

// Main domain
var app = server()
app.listen('http://example.com/')
app.get('/', function($){
    $.end('hello world ')
})

// Sub domain
var sub = server()
sub.listen('http://subdomain.example.com/')
sub.get('/', function($){
    $.end('hello world at sub domain!')
})

// Other domain
var other = server()
other.listen('http://other.com/')
other.get('/', function($){
    $.end('hello world at other domain')
})
Run Code Online (Sandbox Code Playgroud)

分离您的应用

如果您想为您的应用设置不同的文件夹,那么您可以拥有如下文件夹结构:

/server
   /yourApp
       /node_modules
       index.js
   /yourOtherApp
       /node_modules
       index.js
   /node_modules
   index.js
Run Code Online (Sandbox Code Playgroud)

/server/index.js你需要每个应用程序的文件夹:

require('./yourApp')
require('./yourOtherApp')
Run Code Online (Sandbox Code Playgroud)

/server/yourApp/index.js你将设置你的第一个域,例如:

// Require diet
var server = require('diet')

// Create app
var app = server()
app.listen('http://example.com/')
app.get('/', function($){
    $.end('hello world ')
})
Run Code Online (Sandbox Code Playgroud)

/server/yourOtherApp/index.js您将设置您的第二个域,如:

// Require diet
var server = require('diet')

// Create app
var app = server()
app.listen('http://other.com/')
app.get('/', function($){
    $.end('hello world at other.com ')
});
Run Code Online (Sandbox Code Playgroud)

阅读更多:

  • 仅供参考,截至 2019 年 7 月,dietjs.com 已不再运行,并且 github 代码库已有约 2 年没有更新。 (4认同)

Kra*_*mir 19

嗯...为什么你认为nodejs应该充当代理.我建议运行几个节点应用程序在不同的端口上侦听.然后使用nginx将请求转发到正确的端口.如果使用单个节点,您也会遇到单点故障.如果该应用程序崩溃,那么所有网站都会崩溃.


Sco*_*leo 13

使用nginx作为反向代理.

http://www.nginxtips.com/how-to-setup-nginx-as-proxy-for-nodejs/

Nginx以缓存,静态文件处理,ssl和负载平衡的形式为您的应用程序带来了许多好处.


fue*_*mar 12

我有一个我在网站上使用的API,下面是我的配置.我也有SSL和GZIP,如果有人需要它,请评论我.

var http = require('http'),
    httpProxy = require('http-proxy');

var proxy_web = new httpProxy.createProxyServer({
        target: {
            host: 'localhost',
            port: 8080
        }
    });

    var proxy_api = new httpProxy.createProxyServer({
        target: {
            host: 'localhost',
            port: 8081
        }
    });

    http.createServer(function(req, res) {
        if (req.headers.host === 'http://www.domain.com') {
            proxy_web.proxyRequest(req, res);
            proxy_web.on('error', function(err, req, res) {
                if (err) console.log(err);
                res.writeHead(500);
                res.end('Oops, something went very wrong...');
            });
        } else if (req.headers.host === 'http://api.domain.com') {
            proxy_api.proxyRequest(req, res);
            proxy_api.on('error', function(err, req, res) {
                if (err) console.log(err);
                res.writeHead(500);
                res.end('Oops, something went very wrong...');
            });
        }
    }).listen(80);
Run Code Online (Sandbox Code Playgroud)


use*_*109 7

如果您使用的是connect/express服务器,则可以看到vhost中间件.它将允许多个域(子域)用于服务器地址.

您可以按照此处给出的示例进行操作,该示例与您的需求完全相同.


pap*_*iro 6

以下是使用 vanilla Node.js 的方法:

const http = require('http')
const url = require('url')
const port = 5555
const sites = {
  exampleSite1: 544,
  exampleSite2: 543
}

const proxy = http.createServer( (req, res) => {
  const { pathname:path } = url.parse(req.url)
  const { method, headers } = req
  const hostname = headers.host.split(':')[0].replace('www.', '')
  if (!sites.hasOwnProperty(hostname)) throw new Error(`invalid hostname ${hostname}`)

  const proxiedRequest = http.request({
    hostname,
    path,
    port: sites[hostname],
    method,
    headers 
  })

  proxiedRequest.on('response', remoteRes => {
    res.writeHead(remoteRes.statusCode, remoteRes.headers)  
    remoteRes.pipe(res)
  })
  proxiedRequest.on('error', () => {
    res.writeHead(500)
    res.end()
  })

  req.pipe(proxiedRequest)
})

proxy.listen(port, () => {
  console.log(`reverse proxy listening on port ${port}`)
})
Run Code Online (Sandbox Code Playgroud)

很简单吧?