Node.js + Nginx: ¿y ahora qué?

1003

He configurado Node.js y Nginx en mi servidor. Ahora quiero usarlo, pero, antes de comenzar, hay 2 preguntas:

  1. ¿Cómo deberían trabajar juntos? ¿Cómo debo manejar las solicitudes?
  2. Hay 2 conceptos para un servidor Node.js, cuál es mejor:

    a. Cree un servidor HTTP separado para cada sitio web que lo necesite. Luego cargue todo el código JavaScript al inicio del programa, para que el código se interprete una vez.

    si. Cree un único servidor Node.js que maneje todas las solicitudes de Node.js. Esto lee los archivos solicitados y evalúa sus contenidos. Por lo tanto, los archivos se interpretan en cada solicitud, pero la lógica del servidor es mucho más simple.

No está claro para mí cómo usar Node.js correctamente.

Van Coding
fuente

Respuestas:

1306

Nginx funciona como un servidor front-end, que en este caso envía las solicitudes a un servidor node.js. Por lo tanto, debe configurar un archivo de configuración nginx para el nodo.

Esto es lo que he hecho en mi caja de Ubuntu:

Crea el archivo yourdomain.comen /etc/nginx/sites-available/:

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

En él deberías tener algo como:

# 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;
    }
 }

Si desea que nginx (> = 1.3.13) también maneje solicitudes de websocket, agregue las siguientes líneas en la location /sección:

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

Una vez que tenga esta configuración, debe habilitar el sitio definido en el archivo de configuración anterior:

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

Cree su aplicación de servidor de nodo en /var/www/yourdomain/app.jsy ejecútela enlocalhost: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/');

Prueba de errores de sintaxis:

nginx -t

Reinicie nginx:

sudo /etc/init.d/nginx restart

Por último, inicie el servidor de nodo:

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

Ahora debería ver "Hello World" en yourdomain.com

Una última nota con respecto al inicio del servidor de nodo: debe usar algún tipo de sistema de monitoreo para el demonio de nodo. Hay un tutorial increíble sobre nodo con arranque y monitoreo .

Joao Da Silva
fuente
11
Gracias por la publicación, nginx cache node.js respuestas para el servidor anterior, o las volverá a ejecutar cada vez.
Lima
79
¿Hay alguna razón por la que no puedes hacerlo location / { proxy_pass http://127.0.0.1:3000; }? ¿Por qué necesitas todo el upstreambit de configuración?
Robin Winslow
20
+1, respuesta muy directa y simple a una pregunta común; ideal para personas que desean configurar hosts virtuales utilizando node y nginx. Lo único que creo que te perdiste es una respuesta cualitativa a por qué nginx-in-front-of-node es mejor para servir múltiples vhosts (segunda pregunta del autor de la pregunta).
Paul d'Aoust
34
@Robin Winslow en caso de que desee agregar más servidores para servidores para el equilibrio de carga.
Joao Da Silva el
76
Cabe señalar que esta (muy útil) respuesta se refiere a una sabor de nginx que, por defecto, viene con sites-enabledy sites-availabledirectorios dentro /etc/nginx. Si su versión vino sin estos dos directorios, es probable que tenga un solo conf.ddirectorio. En ese caso, seguir estas instrucciones no tendría ningún efecto, A MENOS QUE modifique la includedeclaración dentro del archivo nginx.confpara apuntar en sites-enabledlugar de la predeterminada conf.d. Espero que tenga sentido. Debería volverse explicativo una vez que vea dicha includedeclaración en su interior nginx.conf.
meetamit
167

También puede configurar múltiples dominios con nginx, reenviando a múltiples procesos node.js.

Por ejemplo para lograr estos:

Estos puertos (4000 y 5000) deben usarse para escuchar las solicitudes de la aplicación en su código de aplicación.

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

En / 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
fuente
55
Estoy utilizando el método de PROXY_PASS, pero por alguna razón http://example.comobtiene automáticamente 302'd a http://www.example.com. ¿Porqué es eso?
Kristian
¿Tienes Cloudflare o algo similar? La configuración anterior no debería redirigir en absoluto.
ozzieisaacs
1
@ Kristian Deberá agregar proxy_set_header Host $hostpara evitar la redirección HTTP 302.
Ivan Shatsky
@IvanShatsky: ¿puede proporcionar ayuda para configurar múltiples puertos con múltiples subdominios y evitar que otros puertos se ejecuten en otro dominio? Nginx v 1.14.1
151291
59

También puede tener diferentes URL para aplicaciones en una configuración de servidor:

En / 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/;
    }
}

Reinicie nginx:

sudo service nginx restart

Iniciando aplicaciones.

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

nodo 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
fuente
3
La versión de comunidad de código abierto es gratuita, pero tienen una versión con otras características que no son gratuitas. nginx.com/products/feature-matrix
0x8BADF00D
Perdón por mi ignorancia. ¿Cuál es el propósito, los beneficios de servirlo de esta manera? ¿Tienes algún ejemplo o caso de uso? Gracias por adelantado.
Mauro Aguilar
2
@MauroAguilar Si necesita la aplicación 2 node.js en un servidor, puede servirlos de la manera sugerida (usando diferentes puertos). En mis casos fueron dos aplicaciones de prueba diferentes.
0x8BADF00D
Ok, pero ¿cuál es la diferencia entre ejecutar 2 aplicaciones y una sola? Quiero decir, ¿cuáles son los beneficios si tuvieran el mismo propósito?
Mauro Aguilar
2
@MauroAguilar, puede ejecutarlos en uno solo y no hay ningún beneficio si podría ser parte de un proyecto y tiene el mismo propósito. Pero si necesita ejecutar 2 proyectos diferentes con diferentes propósitos y con diferentes configuraciones en un servidor, entonces tiene la ventaja de usar esta configuración.
0x8BADF00D
35

Proxy aplicaciones Node Express independientes a través de Nginx.

Por lo tanto, las nuevas aplicaciones se pueden montar fácilmente y también puedo ejecutar otras cosas en el mismo servidor en diferentes ubicaciones.

Aquí hay más detalles sobre mi configuración con el ejemplo de configuración de Nginx:

Implemente múltiples aplicaciones de Nodo en un servidor web en subcarpetas con Nginx

Las cosas se ponen difíciles con Node cuando necesita mover su aplicación de localhost a internet.

No existe un enfoque común para la implementación de Nodo.

Google puede encontrar toneladas de artículos sobre este tema, pero estaba luchando por encontrar la solución adecuada para la configuración que necesito.

Básicamente, tengo un servidor web y quiero que las aplicaciones Node se monten en subcarpetas (es decir, http: // myhost / demo / pet-project / ) sin introducir ninguna dependencia de configuración en el código de la aplicación.

Al mismo tiempo, quiero que otras cosas como el blog se ejecuten en el mismo servidor web.

Suena simple ¿eh? Aparentemente no.

En muchos ejemplos en la web, las aplicaciones de Nodo se ejecutan en el puerto 80 o son enviadas por Nginx a la raíz.

Aunque ambos enfoques son válidos para ciertos casos de uso, no cumplen con mi criterio simple pero un poco exótico.

Es por eso que creé mi propia configuración de Nginx y aquí hay un extracto:

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

A partir de este ejemplo, puede observar que monte mi aplicación Pet Project Node ejecutándose en el puerto 3000 en http: // myhost / demo / pet-project .

First Nginx verifica si el recurso solicitado es un archivo estático disponible en / opt / demo / pet-project / public / y si es así, es muy eficiente, por lo que no necesitamos tener una capa redundante como Connect middleware estático

Luego, todas las demás solicitudes se sobrescriben y se envían a la aplicación Pet Project Node , por lo que la aplicación Node no necesita saber dónde está realmente montada y, por lo tanto, se puede mover a cualquier lugar únicamente por configuración.

proxy_redirect es imprescindible para manejar el encabezado de ubicación correctamente. Esto es extremadamente importante si usa res.redirect () en su aplicación Node.

Puede replicar fácilmente esta configuración para múltiples aplicaciones de Nodo que se ejecutan en diferentes puertos y agregar más controladores de ubicación para otros fines.

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

skovalyov
fuente
1
Por qué y cómo debería hacerlo en subdominios: skovalyov.blogspot.dk/2012/10/…
skovalyov
Enlace solo respuesta ... ¿puede resumir las partes relevantes en su respuesta en caso de que su blog desaparezca?
kaiser
11

Node.js con configuración Nginx.

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

agregue la siguiente configuración para que Nginx actúe como proxy redirigido al tráfico del puerto 3000 desde el servidor cuando venimos de "subdominio.su_dominio.com"

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
fuente
9

respondiendo a tu pregunta 2:

Usaría la opción bsimplemente porque consume muchos menos recursos. con la opción 'a', cada cliente hará que el servidor consuma mucha memoria, cargando todos los archivos que necesita (aunque me gusta php, este es uno de los problemas con él). Con la opción 'b' puede cargar sus bibliotecas (código reutilizable) y compartirlas entre todas las solicitudes de los clientes.

Pero tenga en cuenta que si tiene múltiples núcleos, debe ajustar node.js para usarlos todos.

Hugo Mota
fuente
2
Siga este consejo si los recursos son su problema más importante (poco probable). Existen diferentes compromisos entre (a) y (b). Opción (a) es probablemente mejor si lo desea a los sitios a ser más independiente reinicio por ejemplo, un sitio o en mantenimiento, conexiones db, base de código, las dependencias de bibliotecas, sitios móviles entre los servidores, etc.
robocat
8

Hice un repositorio en Github que puedes clonar, vagrant-node-nginx-boilerplate

básicamente la aplicación node.js en /var/www/nodeappes

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

y la configuración de nginx en /etc/nginx/sites-available/es

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
fuente
5

También podría usar node.js para generar archivos estáticos en un directorio servido por nginx. Por supuesto, algunas partes dinámicas de su sitio podrían ser atendidas por el nodo, y algunas por nginx (estático).

Tener algunos de ellos atendidos por nginx aumenta su rendimiento.

Matej
fuente
5

Podemos configurar fácilmente una aplicación Nodejs por Nginx actuando como un proxy inverso.
La siguiente configuración asume que la aplicación NodeJS se ejecuta en 127.0.0.1:8080,

  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
     }
   } 

en la configuración anterior, su aplicación Nodejs lo hará,

  • obtener el HTTP_HOSTencabezado donde puede aplicar la lógica específica del dominio para servir la respuesta. '
  • Su solicitud debe ser administrada por un administrador de procesos como pm2 o un supervisor para manejar situaciones / reutilizar sockets o recursos, etc.

  • Configure un servicio de informes de errores para obtener errores de producción como centinela o barra antivuelco

NOTA: puede configurar la lógica para administrar rutas de solicitud específicas del dominio, crear un middleware para la aplicación expressjs

Renjith Thankachan
fuente
1
Otra razón para usar pm2 es para que pueda ejecutar su aplicación 'para siempre' después de salir del shell, e iniciarla automáticamente si alguna vez necesita reiniciar su servidor, vea: pm2.keymetrics.io/docs/usage/startup
SeanQuinn781
3

Nginx puede actuar como un servidor proxy inverso que funciona igual que un administrador de proyectos. Cuando recibe una solicitud, la analiza y la reenvía a la parte superior (miembros del proyecto) o se maneja sola. Nginx tiene dos formas de manejar una solicitud en función de cómo está configurada.

  • atender la solicitud
  • reenviar la solicitud a otro servidor

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

    }

Servidor de la solicitud

Con esta configuración, cuando la url de solicitud es mydomain.com/static/myjs.js, devuelve el myjs.jsarchivo en la /my/static/files/pathcarpeta. Cuando configura nginx para servir archivos estáticos, maneja la solicitud en sí.

reenviar la solicitud a otro servidor

Cuando la url de solicitud es mydomain.com/dothisnginx reenviará la solicitud a http://127.0.0.1:8000 . El servicio que se ejecuta en el puerto localhost 8000 recibirá la solicitud y devolverá la respuesta a nginx y nginx devuelve la respuesta al cliente.

Cuando ejecuta el servidor node.js en el puerto 8000, nginx reenviará la solicitud a node.js. Escriba la lógica de node.js y maneje la solicitud. Eso es todo, tiene su servidor nodejs ejecutándose detrás del servidor nginx.

Si desea ejecutar cualquier otro servicio que no sea nodejs, simplemente ejecute otro servicio como Django, flask, php en diferentes puertos y configúrelo en nginx.

Vkreddy Komatireddy
fuente
1

Puede ejecutar nodejs usando pm2 si desea administrar cada medio de microservicio y ejecutarlo. El nodo se ejecutará en un puerto, solo configure ese puerto en 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;
    }
}

Compruebe si localhost se está ejecutando o no mediante ping.

Y

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.

Esto es lo mejor y, como dijiste, también es más fácil

gokul kandasamy
fuente
1

La configuración mejor y más simple con Nginx y Nodejs es usar Nginx como un equilibrador de carga HTTP y TCP con proxy_protocol habilitado. En este contexto, Nginx podrá enviar solicitudes entrantes por proxy a nodejs, y también finalizar las conexiones SSL a los servidores Nginx de fondo, y no al servidor proxy en sí. (SSL-PassThrough)

En mi opinión, no tiene sentido dar ejemplos que no sean SSL, ya que todas las aplicaciones web están (o deberían estar) usando entornos seguros.

Ejemplo de configuración para el servidor proxy, en /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;
}

Ahora, manejemos el servidor web de fondo. /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;
}

Ahora, configuremos el host virtual con esta configuración habilitada para SSL y proxy_protocol en /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;
    }
}

Y, por último, una muestra de 2 servidores web de nodejs : primer servidor:

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

Segundo servidor:

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

Ahora todo debería funcionar perfectamente y equilibrar la carga.

Hace un tiempo escribí sobre Cómo configurar Nginx como un equilibrador de carga TCP en Docker . Compruébalo si estás usando Docker.

Escéptico
fuente