Wie hoste ich mehrere Node.js-Sites auf derselben IP / demselben Server mit unterschiedlichen Domänen?


91

Ich habe einen Linux-Server mit einer einzigen IP-Adresse. Ich möchte mehrere Node.js-Sites auf diesem Server unter dieser IP hosten, jede (offensichtlich) mit einer eindeutigen Domain oder Subdomain. Ich möchte sie alle auf Port 80 haben.

Welche Möglichkeiten habe ich dazu?

Eine naheliegende Lösung scheint darin zu bestehen, dass alle Domänen von einer node.js-Webanwendung bedient werden, die als Proxy fungiert und einen Durchgang zu den anderen node.js-Apps durchführt, die auf eindeutigen Ports ausgeführt werden.


4
Ich mache dies und Upstream mit Nginx, namenbasiertem virtuellem Hosting. Als Bonus kann
Nginx

Antworten:


82

Wählen Sie eine der folgenden Optionen:

  • Verwenden Sie einen anderen Server ( wie nginx ) als Reverse-Proxy.
  • Verwenden Sie den Node-http-Proxy als Reverse-Proxy.
  • Verwenden Sie die vhost-Middleware, wenn jede Domäne von derselben Connect / Express-Codebasis und derselben node.js-Instanz aus bedient werden kann.

3
Das ist eine sehr gute und kurze Liste der Optionen, die ich an anderer Stelle gelesen habe. Wissen Sie zufällig für jede dieser Lösungen, welche Prozesse neu gestartet werden müssen, wenn eine neue Domäne hinzugefügt wird? Für 1) keine. Für 2) nur den Node-http-Proxy. Für 3) müsste der gesamte Thread aller Sites neu gestartet werden. Ist das richtig?
Flion

1
@Flion: Sie können die knotenbasierten Proxys so schreiben, dass Sie die Domänenkonfiguration neu laden können, ohne dass ein Prozessneustart erforderlich ist. Es hängt wirklich von den genauen Anforderungen Ihrer App ab.
Josh3736

Nicht was gefragt wurde.
Patrick Sturm

52

Diet.js bietet eine sehr schöne und einfache Möglichkeit, mehrere Domänen mit derselben Serverinstanz zu hosten. Sie können einfachserver()für jede Ihrer Domainseine neue aufrufen.

Ein einfaches Beispiel

// 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')
})

Trennen Sie Ihre Apps

Wenn Sie verschiedene Ordner für Ihre Apps haben möchten, können Sie eine Ordnerstruktur wie die folgende haben:

/server
   /yourApp
       /node_modules
       index.js
   /yourOtherApp
       /node_modules
       index.js
   /node_modules
   index.js

In /server/index.jswürden Sie jede App nach ihrem Ordner benötigen:

require('./yourApp')
require('./yourOtherApp')

In /server/yourApp/index.jswürden Sie Ihre erste Domain einrichten wie:

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

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

Und in /server/yourOtherApp/index.jswürden Sie Ihre zweite Domain einrichten wie:

// 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 ')
});

Weiterlesen:


Dieser Kommentar hat alle meine Probleme gerettet :) ... auch im Jahr 2016
myTerminal

Wird dies automatisch neu geladen? Ich habe angefangen, PM2 zu verwenden, aber es erlaubt mir nicht, mehrere Domains und Reverse Proxys zu hosten
Pini Cheyni

Ersetzt dies Express oder arbeitet es daneben? Meine Vermutung ist entweder. Aber ich möchte sicher sein, bevor ich einen Frankenstein erstelle.
Mardok

1
Zu Ihrer Information Ab Juli 2019 ist dietjs.com nicht mehr verfügbar und es wurde seit ~ 2 Jahren kein Update der Github-Codebasis mehr durchgeführt.
Sirclesam

20

Hm ... warum denkst du, dass nodejs als Proxy fungieren sollten? Ich werde vorschlagen, mehrere Knoten-Apps auszuführen, die an verschiedenen Ports lauschen. Verwenden Sie dann nginx, um die Anforderung an den richtigen Port weiterzuleiten. Wenn Sie einen einzelnen Knoten verwenden, haben Sie auch einen einzelnen Fehlerpunkt. Wenn diese App abstürzt, fallen alle Websites aus.



12

Ich habe eine API, die ich auf einer Site verwende, und unten ist meine Konfiguration aufgeführt. Ich habe es auch mit SSL und GZIP, wenn jemand es braucht, kommentiere mich einfach.

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);

7

Wenn Sie einen Connect / Express-Server verwenden, wird die vhostMiddleware angezeigt. Damit können mehrere Domänen (Subdomänen) für die Serveradresse verwendet werden.

Sie können dem hier gegebenen Beispiel folgen , das genau so aussieht, wie Sie es benötigen.




3

Zuerst für immer und federnd installieren .

Dann schreiben Sie ein Startskript. Fügen Sie in diesem Skript dem iptables-Firewall-Dienstprogramm eine Regel hinzu, um den Datenverkehr auf Port 80 an Port 8000 (oder an eine andere von Ihnen ausgewählte Option) weiterzuleiten. In meinem Beispiel ist 8000 der Ort, an dem ich Bouncy laufen lasse

sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8000

Lassen Sie uns das Skript für immer anweisen, Bouncy auf Port 8000 auszuführen

forever start --spinSleepTime 10000 /path/to/bouncy /path/to/bouncy/routes.json 8000

Die route.json würde so etwas gerne

{
    subdomain1.domain.com" : 5000,
    subdomain2.domain.com" : 5001,
    subdomain3.domain.com" : 5002
}

NodeJS-Anwendung1, -Anwendung2 und -Anwendung3 werden auf Port 5000, 5001 bzw. 5002 ausgeführt.

Das Skript, das ich in meinem Fall verwende, finden Sie hier. Möglicherweise müssen Sie ein wenig ändern, um es in Ihre Umgebung zu integrieren.

Ich habe auch ausführlicher darüber geschrieben und Sie können es hier finden .


Sie sollten PM2
Pini Cheyni

ok das ist toll, aber wie kann ich http-> https in bouncy erzwingen ??

2

So geht's mit 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}`)
})

Ziemlich einfach, oder?


1

Wenn Sie das Anforderungs- und Antwortobjekt erhalten, können Sie die Domain über "request.headers.host" abrufen ... (nicht die IP, sondern die Domain)


0

Dieser Leitfaden vom digitalen Ozean ist ein ausgezeichneter Weg. Es verwendet das pm2-Modul, das Ihre App dämonisiert (als Dienst ausführt). Es sind keine zusätzlichen Module wie Forever erforderlich, da Ihre App bei einem Absturz automatisch neu gestartet wird. Es verfügt über viele Funktionen, mit denen Sie die verschiedenen Anwendungen überwachen können, die auf Ihrem Server ausgeführt werden. Es ist ziemlich großartig!

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.