Node.js + Nginx - Was jetzt?

1003

Ich habe Node.js und Nginx auf meinem Server eingerichtet. Jetzt möchte ich es verwenden, aber bevor ich anfange, gibt es zwei Fragen:

  1. Wie sollen sie zusammenarbeiten? Wie soll ich mit den Anfragen umgehen?
  2. Es gibt zwei Konzepte für einen Node.js-Server, welches ist besser:

    ein. Erstellen Sie einen separaten HTTP-Server für jede Website, die ihn benötigt. Laden Sie dann den gesamten JavaScript-Code zu Beginn des Programms, damit der Code einmal interpretiert wird.

    b. Erstellen Sie einen einzelnen Node.js-Server, der alle Node.js-Anforderungen verarbeitet. Dies liest die angeforderten Dateien und wertet deren Inhalt aus. Die Dateien werden also bei jeder Anforderung interpretiert, aber die Serverlogik ist viel einfacher.

Mir ist nicht klar, wie ich Node.js richtig verwenden soll.

Van Coding
quelle

Antworten:

1306

Nginx arbeitet als Front-End-Server, der in diesem Fall die Anforderungen an einen node.js-Server weiterleitet. Daher müssen Sie eine Nginx-Konfigurationsdatei für den Knoten einrichten.

Folgendes habe ich in meiner Ubuntu-Box getan:

Erstellen Sie die Datei yourdomain.comunter /etc/nginx/sites-available/:

vim /etc/nginx/sites-available/yourdomain.com

Darin sollten Sie etwas haben wie:

# the IP(s) on which your node server is running. I chose port 3000.
upstream app_yourdomain {
    server 127.0.0.1:3000;
    keepalive 8;
}

# the nginx server instance
server {
    listen 80;
    listen [::]:80;
    server_name yourdomain.com www.yourdomain.com;
    access_log /var/log/nginx/yourdomain.com.log;

    # pass the request to the node.js server with the correct headers
    # and much more can be added, see nginx config options
    location / {
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_set_header X-NginX-Proxy true;

      proxy_pass http://app_yourdomain/;
      proxy_redirect off;
    }
 }

Wenn Sie möchten, dass nginx (> = 1.3.13) auch Websocket-Anforderungen verarbeitet, fügen Sie die folgenden Zeilen in den location /Abschnitt ein:

proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

Sobald Sie dieses Setup haben, müssen Sie die in der obigen Konfigurationsdatei definierte Site aktivieren:

cd /etc/nginx/sites-enabled/ 
ln -s /etc/nginx/sites-available/yourdomain.com yourdomain.com

Erstellen Sie Ihre Knotenserver-App unter /var/www/yourdomain/app.jsund führen Sie sie unter auslocalhost:3000

var http = require('http');

http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello World\n');
}).listen(3000, "127.0.0.1");
console.log('Server running at http://127.0.0.1:3000/');

Test auf Syntaxfehler:

nginx -t

Starten Sie nginx neu:

sudo /etc/init.d/nginx restart

Zuletzt starten Sie den Knotenserver:

cd /var/www/yourdomain/ && node app.js

Jetzt sollten Sie "Hello World" auf yourdomain.com sehen

Ein letzter Hinweis zum Starten des Knotenservers: Sie sollten eine Art Überwachungssystem für den Knoten-Daemon verwenden. Es gibt ein fantastisches Tutorial zu Node mit Upstart und Monit .

Joao Da Silva
quelle
11
Vielen Dank für den Beitrag, werden die Antworten von nginx node.js für den oben genannten Server zwischengespeichert oder jedes Mal erneut ausgeführt.
Kalk
79
Gibt es einen Grund, warum Sie das nicht einfach tun können location / { proxy_pass http://127.0.0.1:3000; }? Warum brauchst du das ganze upstreamKonfigurationsbit?
Robin Winslow
20
+1, sehr einfache und einfache Antwort auf eine häufig gestellte Frage; Ideal für Leute, die virtuelle Hosts mit Node und Nginx einrichten möchten. Das einzige, was Sie meiner Meinung nach verpasst haben, ist eine qualitative Antwort darauf, warum Nginx vor dem Knoten am besten geeignet ist, um mehrere Vhosts zu bedienen (zweite Frage des Fragestellers).
Paul d'Aoust
34
@Robin Winslow für den Fall, dass Sie weitere Server für Server zum Lastenausgleich hinzufügen möchten.
Joao Da Silva
76
Es sollte beachtet werden, dass sich diese (sehr hilfreiche) Antwort auf eine Nginx-Variante bezieht, die standardmäßig mit sites-enabledund sites-availableVerzeichnissen darin enthalten ist /etc/nginx. Wenn Ihre Version ohne diese beiden Verzeichnisse geliefert wurde, verfügt sie wahrscheinlich conf.dstattdessen über ein einziges Verzeichnis. In diesem Fall hätte das Befolgen dieser Anweisungen keine Auswirkung, es sei denn, Sie ändern die includeAnweisung in der Datei so nginx.conf, dass sie sites-enabledanstelle der Standardeinstellung verweist conf.d. Hoffe das macht Sinn. Es sollte selbsterklärend werden, sobald Sie die besagte includeAussage darin sehen nginx.conf.
Treffen
167

Sie können mit nginx auch mehrere Domänen einrichten und an mehrere Prozesse von node.js weiterleiten.

Zum Beispiel, um diese zu erreichen:

Diese Ports (4000 und 5000) sollten verwendet werden, um die App-Anforderungen in Ihrem App-Code abzuhören.

/ etc / nginx / sites-enabled / domain1

server {
    listen 80;
    listen [::]:80;
    server_name domain1.com;
    access_log /var/log/nginx/domain1.access.log;
    location / {
        proxy_pass    http://127.0.0.1:4000/;
    }
}

In / etc / nginx / sites-enabled / domain2

server {
    listen 80;
    listen [::]:80;
    server_name domain2.com;
    access_log /var/log/nginx/domain2.access.log;
    location / {
        proxy_pass    http://127.0.0.1:5000/;
    }
}
250R
quelle
5
Ich verwende Ihre Methode von proxy_pass, aber aus irgendeinem Grund http://example.comwird automatisch 302dazu http://www.example.com. Warum ist das so?
Kristian
Haben Sie Cloudflare oder ähnliches? Die obige Konfiguration sollte überhaupt nicht umleiten.
Ozzieisaacs
1
@Kristian Sie müssen hinzufügen proxy_set_header Host $host, um eine HTTP 302-Umleitung zu vermeiden.
Ivan Shatsky
@IvanShatsky - Können Sie uns helfen, wie Sie mehrere Ports mit mehreren Subdomänen konfigurieren und verhindern können, dass andere Ports in einer anderen Domain ausgeführt werden? Nginx v 1.14.1
151291
59

Sie können auch verschiedene URLs für Apps in einer Serverkonfiguration haben:

In / etc / nginx / sites-enabled / yourdomain :

server {
    listen 80;
    listen [::]:80;
    server_name yourdomain.com;

    location ^~ /app1/{
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_pass    http://127.0.0.1:3000/;
    }

    location ^~ /app2/{
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_pass    http://127.0.0.1:4000/;
    }
}

Starten Sie nginx neu:

sudo service nginx restart

Anwendungen starten.

Knoten app1.js

var http = require('http');
http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello from app1!\n');
}).listen(3000, "127.0.0.1");
console.log('Server running at http://127.0.0.1:3000/');

Knoten app2.js

var http = require('http');
http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello from app2!\n');
}).listen(4000, "127.0.0.1");
console.log('Server running at http://127.0.0.1:4000/');
0x8BADF00D
quelle
3
Die Open Source Community-Version ist kostenlos, es gibt jedoch eine Version mit anderen Funktionen, die nicht kostenlos sind. nginx.com/products/feature-matrix
0x8BADF00D
Entschuldigung für meine Unwissenheit. Was ist der Zweck, die Vorteile einer solchen Bedienung? Haben Sie ein Beispiel oder einen Anwendungsfall? Danke im Voraus.
Mauro Aguilar
2
@MauroAguilar Wenn Sie 2 node.js App auf einem Server benötigen, können Sie diese auf vorgeschlagene Weise (über verschiedene Ports) bedienen. In meinen Fällen waren es zwei verschiedene Test-Apps.
0x8BADF00D
Ok, aber was ist der Unterschied zwischen zwei Apps und einer einzigen? Ich meine, was sind die Vorteile, wenn sie für den gleichen Zweck bestimmt waren?
Mauro Aguilar
2
@MauroAguilar, Sie können sie in einem einzigen ausführen und es gibt keinen Vorteil, wenn es Teil eines Projekts sein könnte und denselben Zweck hat. Wenn Sie jedoch zwei verschiedene Projekte mit unterschiedlichen Zwecken und Konfigurationen auf einem Server ausführen müssen, können Sie diese Konfiguration verwenden.
0x8BADF00D
35

Ich vertrete unabhängige Node Express-Anwendungen über Nginx.

Auf diese Weise können neue Anwendungen einfach bereitgestellt werden, und ich kann auch andere Inhalte auf demselben Server an verschiedenen Standorten ausführen.

Hier finden Sie weitere Details zu meinem Setup mit dem Nginx-Konfigurationsbeispiel:

Stellen Sie mit Nginx mehrere Knotenanwendungen auf einem Webserver in Unterordnern bereit

Mit Node wird es schwierig, wenn Sie Ihre Anwendung von localhost ins Internet verschieben müssen.

Es gibt keinen gemeinsamen Ansatz für die Knotenbereitstellung.

Google kann unzählige Artikel zu diesem Thema finden, aber ich hatte Probleme, die richtige Lösung für das von mir benötigte Setup zu finden.

Grundsätzlich habe ich einen Webserver und möchte, dass Knotenanwendungen in Unterordnern (dh http: // myhost / demo / pet-project / ) bereitgestellt werden, ohne dass Konfigurationsabhängigkeiten zum Anwendungscode eingeführt werden.

Gleichzeitig möchte ich, dass andere Dinge wie Blogs auf demselben Webserver ausgeführt werden.

Klingt einfach, oder? Scheinbar nicht.

In vielen Beispielen im Web werden Knotenanwendungen entweder auf Port 80 ausgeführt oder von Nginx an den Stamm übertragen.

Obwohl beide Ansätze für bestimmte Anwendungsfälle gültig sind, erfüllen sie nicht meine einfachen, aber ein wenig exotischen Kriterien.

Deshalb habe ich meine eigene Nginx-Konfiguration erstellt und hier ist ein Auszug:

upstream pet_project {
  server localhost:3000;
}

server {
  listen 80;
  listen [::]:80;
  server_name frontend;

  location /demo/pet-project {
    alias /opt/demo/pet-project/public/;
    try_files $uri $uri/ @pet-project;
  }

  location @pet-project {
    rewrite /demo/pet-project(.*) $1 break;

    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $proxy_host;
    proxy_set_header X-NginX-Proxy true;

    proxy_pass http://pet_project;
    proxy_redirect http://pet_project/ /demo/pet-project/;
  }
}

An diesem Beispiel können Sie erkennen, dass ich meine Pet Project Node-Anwendung, die auf Port 3000 ausgeführt wird, unter http: // myhost / demo / pet-project einbinde .

Zuerst prüft Nginx, ob es sich bei der angeforderten Ressource um eine statische Datei handelt, die unter / opt / demo / pet-project / public / verfügbar ist, und wenn ja, dient sie als hocheffizient, sodass wir keine redundante Schicht wie Connect benötigen statische Middleware.

Dann werden alle anderen Anforderungen überschrieben und an die Pet Project Node- Anwendung weitergeleitet, sodass die Node-Anwendung nicht wissen muss, wo sie tatsächlich bereitgestellt ist, und daher nur durch Konfiguration an einen beliebigen Ort verschoben werden kann.

proxy_redirect ist ein Muss, um den Location-Header richtig zu behandeln. Dies ist äußerst wichtig, wenn Sie res.redirect () in Ihrer Knotenanwendung verwenden .

Sie können dieses Setup problemlos für mehrere Knotenanwendungen replizieren, die an verschiedenen Ports ausgeführt werden, und weitere Standorthandler für andere Zwecke hinzufügen.

Von: http://skovalyov.blogspot.dk/2012/07/deploy-multiple-node-applications-on.html

skovalyov
quelle
1
Warum und wie Sie es stattdessen in Subdomains tun sollten: skovalyov.blogspot.dk/2012/10/…
skovalyov
Nur Link-Antwort… können Sie bitte die relevanten Teile in Ihrer Antwort zusammenfassen, falls Ihr Blog weg ist?
Kaiser
11

Node.js mit Nginx-Konfiguration.

$ sudo nano /etc/nginx/sites-available/subdomain.your_domain.com

Fügen Sie die folgende Konfiguration hinzu, damit Nginx als Proxy-Umleitung zum Port 3000-Verkehr vom Server fungiert, wenn wir von "subdomain.your_domain.com" kommen.

upstream subdomain.your_domain.com {
  server 127.0.0.1:3000;
}
server {
  listen 80;
  listen [::]:80;
  server_name subdomain.your_domain.com;
  access_log /var/log/nginx/subdomain.your_domain.access.log;
  error_log /var/log/nginx/subdomain.your_domain.error.log debug;
  location / {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarder-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-NginX-Proxy true;
    proxy_pass http://subdomain.your_domain.com;
    proxy_redirect off;
  }
}
Aquadir
quelle
9

Beantwortung Ihrer Frage 2:

Ich würde die Option beinfach verwenden, weil sie viel weniger Ressourcen verbraucht. Mit der Option 'a' wird jeder Client dazu führen, dass der Server viel Speicher verbraucht und alle benötigten Dateien lädt (obwohl ich PHP mag, ist dies eines der Probleme damit). Mit der Option 'b' können Sie Ihre Bibliotheken (wiederverwendbarer Code) laden und für alle Clientanforderungen freigeben.

Beachten Sie jedoch, dass Sie bei mehreren Kernen die Datei node.js optimieren sollten, um alle zu verwenden.

Hugo Mota
quelle
2
Befolgen Sie diese Hinweise, wenn Ressourcen Ihr wichtigstes Problem sind (unwahrscheinlich). Es gibt verschiedene Kompromisse zwischen (a) und (b). Option (a) ist wahrscheinlich besser, wenn Sie möchten, dass die Sites unabhängiger sind, z. B. Neustart oder Wartung der Sites,
Datenbankverbindungen
8

Ich habe in Github ein Repository erstellt, das Sie klonen können, Vagrant-Node-Nginx-Boilerplate

im Grunde die node.js app bei /var/www/nodeappIS

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World\n');
}).listen(4570, '127.0.0.1');

console.log('Node Server running at 127.0.0.1:4570/');

und die nginx config at /etc/nginx/sites-available/ist

server {
        listen 80 default_server;
        listen [::]:80 default_server;

        root /var/www/nodeapp;
        index index.html index.htm;

        server_name localhost;

        location / {
          proxy_pass http://127.0.0.1:4570;
          proxy_http_version 1.1;
          proxy_set_header Upgrade $http_upgrade;
          proxy_set_header Connection 'upgrade';
          proxy_set_header Host $host;
          proxy_cache_bypass $http_upgrade;
        }
}
svnm
quelle
5

Sie können auch node.js verwenden, um statische Dateien in einem von nginx bereitgestellten Verzeichnis zu generieren. Natürlich können einige dynamische Teile Ihrer Site vom Knoten und einige von Nginx (statisch) bedient werden.

Wenn einige von ihnen von Nginx bedient werden, erhöht sich Ihre Leistung.

Matej
quelle
5

Wir können problemlos eine Nodejs-App von Nginx einrichten, die als Reverse-Proxy fungiert.
In der folgenden Konfiguration wird davon ausgegangen, dass die NodeJS-Anwendung unter 127.0.0.1:8080 ausgeführt wird.

  server{
     server_name domain.com sub.domain.com; # multiple domains

     location /{ 
      proxy_pass http://127.0.0.1:8080;  
      proxy_set_header Host $host;
      proxy_pass_request_headers on;  
     }

     location /static/{
       alias /absolute/path/to/static/files; # nginx will handle js/css
     }
   } 

im obigen Setup wird Ihre Nodejs App,

  • HTTP_HOSTHolen Sie sich den Header, in dem Sie domänenspezifische Logik anwenden können, um die Antwort zu liefern. '
  • Ihre Anwendung muss von einem Prozessmanager wie pm2 oder einem Supervisor verwaltet werden, um Situationen zu behandeln / Sockets oder Ressourcen wiederzuverwenden usw.

  • Richten Sie einen Fehlerberichtsservice ein, um Produktionsfehler wie Wachposten oder Überrollbügel abzurufen

HINWEIS: Sie können eine Logik für die Übergabe domänenspezifischer Anforderungsrouten einrichten und eine Middleware für die ExpressJS-Anwendung erstellen

Renjith Thankachan
quelle
1
Ein weiterer Grund für die Verwendung von pm2 besteht darin, dass Sie Ihre App nach dem Beenden der Shell "für immer" ausführen und automatisch starten können, wenn Sie Ihren Server jemals neu starten müssen. Siehe: pm2.keymetrics.io/docs/usage/startup
SeanQuinn781
3

Nginx kann als Reverse-Proxy-Server fungieren, der genau wie ein Projektmanager funktioniert. Wenn es eine Anfrage erhält, analysiert es diese und leitet die Anfrage an Upstream (Projektmitglieder) weiter oder bearbeitet sich selbst. Nginx bietet zwei Möglichkeiten, eine Anfrage basierend auf ihrer Konfiguration zu bearbeiten.

  • die Anfrage bedienen
  • Leiten Sie die Anfrage an einen anderen Server weiter

    server{
     server_name mydomain.com sub.mydomain.com;
    
     location /{ 
      proxy_pass http://127.0.0.1:8000;  
      proxy_set_header Host $host;
      proxy_pass_request_headers on;  
     }
    
     location /static/{
       alias /my/static/files/path;
     }

    }}

Server die Anfrage

Wenn bei dieser Konfiguration die Anforderungs-URL lautet mydomain.com/static/myjs.js, wird die myjs.jsDatei im /my/static/files/pathOrdner zurückgegeben. Wenn Sie nginx so konfigurieren, dass statische Dateien bereitgestellt werden, wird die Anforderung selbst verarbeitet.

Leiten Sie die Anfrage an einen anderen Server weiter

Wenn die Anforderungs-URL mydomain.com/dothisnginx lautet, wird die Anforderung an http://127.0.0.1:8000 weitergeleitet . Der Dienst, der auf dem localhost 8000-Port ausgeführt wird, empfängt die Anforderung und gibt die Antwort an nginx zurück, und nginx gibt die Antwort an den Client zurück.

Wenn Sie den Server node.js auf Port 8000 ausführen, leitet nginx die Anforderung an node.js weiter. Schreiben Sie die Logik von node.js und bearbeiten Sie die Anforderung. Sie haben Ihren nodejs-Server hinter dem nginx-Server ausgeführt.

Wenn Sie andere Dienste als nodejs ausführen möchten, führen Sie einfach einen anderen Dienst wie Django, flask, php an verschiedenen Ports aus und konfigurieren Sie ihn in nginx.

Vkreddy Komatireddy
quelle
1

Sie können nodejs mit pm2 ausführen, wenn Sie jedes Microservice-Mittel verwalten und ausführen möchten. Der Knoten wird in einem Port ausgeführt. Konfigurieren Sie diesen Port einfach in nginx (/etc/nginx/sites-enabled/domain.com).

server{
    listen 80;
    server_name domain.com www.domain.com;

  location / {
     return 403;
  }
    location /url {
        proxy_pass http://localhost:51967/info;
    }
}

Überprüfen Sie mithilfe von Ping, ob localhost ausgeführt wird.

Und

Create one single Node.js server which handles all Node.js requests. This reads the requested files and evals their contents. So the files are interpreted on each request, but the server logic is much simpler.

Das ist am besten und wie gesagt auch einfacher

Gokul Kandasamy
quelle
1

Die beste und einfachere Einrichtung mit Nginx und Nodejs ist die Verwendung von Nginx als HTTP- und TCP-Load-Balancer mit aktiviertem Proxy-Protokoll. In diesem Zusammenhang kann Nginx eingehende Anforderungen an NodeJS weiterleiten und auch SSL-Verbindungen zu den Back-End-Nginx-Servern und nicht zum Proxy-Server selbst beenden. (SSL-PassThrough)

Meiner Meinung nach macht es keinen Sinn, Nicht-SSL-Beispiele zu nennen, da alle Web-Apps sichere Umgebungen verwenden (oder verwenden sollten).

Beispielkonfiguration für den Proxyserver in /etc/nginx/nginx.conf

user  nginx;
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
events {
    worker_connections  1024;
}
http {
  upstream webserver-http {
    server 192.168.1.4; #use a host port instead if using docker
    server 192.168.1.5; #use a host port instead if using docker
  }
  upstream nodejs-http {
    server 192.168.1.4:8080; #nodejs listening port
    server 192.168.1.5:8080; #nodejs listening port
  }
  server {
    server_name example.com;
    location / {
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_set_header Host $http_host;
      proxy_set_header X-Forwarded-Host $server_name;
      proxy_set_header Connection "";
      add_header       X-Upstream $upstream_addr;
      proxy_redirect     off;
      proxy_connect_timeout  300;
      proxy_http_version 1.1;
      proxy_buffers 16 16k;
      proxy_buffer_size 16k;
      proxy_cache_background_update on;
      proxy_pass http://webserver-http$request_uri;
    }
  }
  server {
    server_name node.example.com;
    location / {
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_set_header Host $http_host;
      proxy_set_header X-Forwarded-Host $server_name;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "Upgrade";
      add_header       X-Upstream $upstream_addr;
      proxy_redirect     off;
      proxy_connect_timeout  300;
      proxy_http_version 1.1;
      proxy_buffers 16 16k;
      proxy_buffer_size 16k;
      proxy_cache_background_update on;
      proxy_pass http://nodejs-http$request_uri;
    }
  }
}
stream {
  upstream webserver-https {
    server 192.168.1.4:443; #use a host port instead if using docker
    server 192.168.1.5:443; #use a host port instead if using docker
  }

  server {
    proxy_protocol on;
    tcp_nodelay on;
    listen 443;
    proxy_pass webserver-https;
  }
  log_format proxy 'Protocol: $protocol - $status $bytes_sent $bytes_received $session_time';
  access_log  /var/log/nginx/access.log proxy;
  error_log /var/log/nginx/error.log debug;
}

Lassen Sie uns nun den Backend-Webserver behandeln. /etc/nginx/nginx.conf :

user  nginx;
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
load_module /etc/nginx/modules/ngx_http_geoip2_module.so; # GeoIP2
events {
    worker_connections  1024;
}
http {
    variables_hash_bucket_size 64;
    variables_hash_max_size 2048;
    server_tokens off;
    sendfile    on;
    tcp_nopush  on;
    tcp_nodelay on;
    autoindex off;
    keepalive_timeout  30;
    types_hash_bucket_size 256;
    client_max_body_size 100m;
    server_names_hash_bucket_size 256;
    include         mime.types;
    default_type    application/octet-stream;
    index  index.php index.html index.htm;
    # GeoIP2
    log_format  main    'Proxy Protocol Address: [$proxy_protocol_addr] '
                        '"$request" $remote_addr - $remote_user [$time_local] "$request" '
                        '$status $body_bytes_sent "$http_referer" '
                        '"$http_user_agent" "$http_x_forwarded_for"';

    # GeoIP2
    log_format  main_geo    'Original Client Address: [$realip_remote_addr]- Proxy Protocol Address: [$proxy_protocol_addr] '
                            'Proxy Protocol Server Address:$proxy_protocol_server_addr - '
                            '"$request" $remote_addr - $remote_user [$time_local] "$request" '
                            '$status $body_bytes_sent "$http_referer" '
                            '$geoip2_data_country_iso $geoip2_data_country_name';

    access_log  /var/log/nginx/access.log  main_geo; # GeoIP2
#===================== GEOIP2 =====================#
    geoip2 /usr/share/geoip/GeoLite2-Country.mmdb {
        $geoip2_metadata_country_build  metadata build_epoch;
        $geoip2_data_country_geonameid  country geoname_id;
        $geoip2_data_country_iso        country iso_code;
        $geoip2_data_country_name       country names en;
        $geoip2_data_country_is_eu      country is_in_european_union;
    }
    #geoip2 /usr/share/geoip/GeoLite2-City.mmdb {
    #   $geoip2_data_city_name city names en;
    #   $geoip2_data_city_geonameid city geoname_id;
    #   $geoip2_data_continent_code continent code;
    #   $geoip2_data_continent_geonameid continent geoname_id;
    #   $geoip2_data_continent_name continent names en;
    #   $geoip2_data_location_accuracyradius location accuracy_radius;
    #   $geoip2_data_location_latitude location latitude;
    #   $geoip2_data_location_longitude location longitude;
    #   $geoip2_data_location_metrocode location metro_code;
    #   $geoip2_data_location_timezone location time_zone;
    #   $geoip2_data_postal_code postal code;
    #   $geoip2_data_rcountry_geonameid registered_country geoname_id;
    #   $geoip2_data_rcountry_iso registered_country iso_code;
    #   $geoip2_data_rcountry_name registered_country names en;
    #   $geoip2_data_rcountry_is_eu registered_country is_in_european_union;
    #   $geoip2_data_region_geonameid subdivisions 0 geoname_id;
    #   $geoip2_data_region_iso subdivisions 0 iso_code;
    #   $geoip2_data_region_name subdivisions 0 names en;
   #}

#=================Basic Compression=================#
    gzip on;
    gzip_disable "msie6";
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_buffers 16 8k;
    gzip_http_version 1.1;
    gzip_types text/css text/xml text/plain application/javascript image/jpeg image/png image/gif image/x-icon image/svg+xml image/webp application/font-woff application/json application/vnd.ms-fontobject application/vnd.ms-powerpoint;
    gzip_static on;

    include /etc/nginx/sites-enabled/example.com-https.conf;
}

Jetzt konfigurieren wir den virtuellen Host mit dieser SSL- und Proxy-Protokoll-fähigen Konfiguration unter /etc/nginx/sites-available/example.com-https.conf :

server {
    real_ip_header proxy_protocol;
    set_real_ip_from 192.168.1.1; #proxy server ip address
    #set_real_ip_from proxy; #proxy container hostname if you are using docker
    server_name 192.168.1.4; #Your current server ip address. It will redirect to the domain name.
    listen 80;
    listen 443 ssl http2;
    listen [::]:80;
    listen [::]:443 ssl http2;
    ssl_certificate     /etc/nginx/certs/example.com.crt;
    ssl_certificate_key /etc/nginx/certs/example.com.key;
    ssl_dhparam /etc/nginx/ssl/dhparam.pem;
    return 301 https://example.com$request_uri;
}
server {
    real_ip_header proxy_protocol;
    set_real_ip_from 192.168.1.1; #proxy server ip address
    #set_real_ip_from proxy; #proxy container hostname if you are using docker
    server_name  example.com;
    listen       *:80;
    return 301   https://example.com$request_uri;
}
server {
    real_ip_header proxy_protocol;
    set_real_ip_from 192.168.1.1; #proxy server ip address
    #set_real_ip_from proxy; #proxy container hostname if you are using docker
    server_name www.example.com;
    listen 80;
    listen 443 http2;
    listen [::]:80;
    listen [::]:443 ssl http2 ;
    ssl_certificate     /etc/nginx/certs/example.com.crt;
    ssl_certificate_key /etc/nginx/certs/example.com.key;
    ssl_dhparam /etc/nginx/ssl/dhparam.pem;
    return 301 https://example.com$request_uri;
}
server {
    real_ip_header proxy_protocol;
    set_real_ip_from 192.168.1.1; #proxy server ip address
    #set_real_ip_from proxy; #proxy container hostname if you are using docker
    server_name example.com;
    listen 443 proxy_protocol ssl http2;
    listen [::]:443 proxy_protocol ssl http2;
    root /var/www/html;
    charset UTF-8;
    add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload';
    add_header X-Frame-Options SAMEORIGIN;
    add_header X-Content-Type-Options nosniff;
    add_header X-XSS-Protection "1; mode=block";
    add_header Referrer-Policy no-referrer;
    ssl_prefer_server_ciphers on;
    ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
    ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
    ssl_session_cache   shared:SSL:10m;
    ssl_session_timeout 10m;
    keepalive_timeout   70;
    ssl_buffer_size 1400;
    ssl_dhparam /etc/nginx/ssl/dhparam.pem;
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4 valid=86400;
    resolver_timeout 10;
    ssl_certificate     /etc/nginx/certs/example.com.crt;
    ssl_certificate_key /etc/nginx/certs/example.com.key;
    ssl_trusted_certificate /etc/nginx/certs/example.com.crt;
location ~* \.(jpg|jpe?g|gif|png|ico|cur|gz|svgz|mp4|ogg|ogv|webm|htc|css|js|otf|eot|svg|ttf|woff|woff2)(\?ver=[0-9.]+)?$ {
    expires modified 1M;
    add_header Access-Control-Allow-Origin '*';
    add_header Pragma public;
    add_header Cache-Control "public, must-revalidate, proxy-revalidate";
    access_log off;
    }
    location ~ /.well-known { #For issuing LetsEncrypt Certificates
        allow all;
    }
location / {
    index index.php;
    try_files $uri $uri/ /index.php?$args;
    }
error_page  404    /404.php;

location ~ \.php$ {
    try_files       $uri =404;
    fastcgi_index   index.php;
    fastcgi_pass    unix:/tmp/php7-fpm.sock;
    #fastcgi_pass    php-container-hostname:9000; (if using docker)
    fastcgi_pass_request_headers on;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_param   SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    fastcgi_intercept_errors on;
    fastcgi_ignore_client_abort off;
    fastcgi_connect_timeout 60;
    fastcgi_send_timeout 180;
    fastcgi_read_timeout 180;
    fastcgi_request_buffering on;
    fastcgi_buffer_size 128k;
    fastcgi_buffers 4 256k;
    fastcgi_busy_buffers_size 256k;
    fastcgi_temp_file_write_size 256k;
    include fastcgi_params;
}
location = /robots.txt {
    access_log off;
    log_not_found off;
    }
location ~ /\. {
    deny  all;
    access_log off;
    log_not_found off;
    }
}

Und zum Schluss eine Probe von Schluss noch 2 NodeJS-Webservern : Erster Server:

var http = require('http');

http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello From Nodejs\n');
}).listen(8080, "192.168.1.4");
console.log('Server running at http://192.168.1.4:8080/');

Zweiter Server:

var http = require('http');

http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('Hello From Nodejs\n');
}).listen(8080, "192.168.1.5");
console.log('Server running at http://192.168.1.5:8080/');

Jetzt sollte alles perfekt funktionieren und ausgeglichen sein.

Vor einiger Zeit schrieb ich über das Einrichten von Nginx als TCP-Load-Balancer in Docker . Probieren Sie es aus, wenn Sie Docker verwenden.

Skeptiker
quelle