Node.js + Nginx - E agora?

1003

Eu configurei o Node.js e o Nginx no meu servidor. Agora eu quero usá-lo, mas, antes de começar, existem duas perguntas:

  1. Como eles devem trabalhar juntos? Como devo lidar com os pedidos?
  2. Existem 2 conceitos para um servidor Node.js. Qual é o melhor:

    uma. Crie um servidor HTTP separado para cada site que precisar. Em seguida, carregue todo o código JavaScript no início do programa, para que o código seja interpretado uma vez.

    b. Crie um único servidor Node.js. que lida com todas as solicitações do Node.js. Isso lê os arquivos solicitados e avalia seu conteúdo. Portanto, os arquivos são interpretados em cada solicitação, mas a lógica do servidor é muito mais simples.

Não está claro para mim como usar o Node.js corretamente.

Van Coding
fonte

Respostas:

1306

O Nginx funciona como um servidor front-end, que nesse caso proxies as solicitações para um servidor node.js. Portanto, você precisa configurar um arquivo de configuração nginx para o nó.

Isto é o que eu fiz na minha caixa do Ubuntu:

Crie o arquivo yourdomain.comem /etc/nginx/sites-available/:

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

Nele você deve ter 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;
    }
 }

Se você deseja que o nginx (> = 1.3.13) também lide com solicitações de websocket, adicione as seguintes linhas na location /seção:

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

Depois de definir essa configuração, você deve ativar o site definido no arquivo de configuração acima:

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

Crie o aplicativo do servidor do nó em /var/www/yourdomain/app.jse execute-o emlocalhost: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/');

Teste para erros de sintaxe:

nginx -t

Reinicie o nginx:

sudo /etc/init.d/nginx restart

Por fim, inicie o servidor do nó:

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

Agora você deve ver "Olá mundo" em seudominio.com

Uma última observação em relação à inicialização do servidor do nó: você deve usar algum tipo de sistema de monitoramento para o daemon do nó. Há um tutorial incrível no nó com upstart e monit .

Joao Da Silva
fonte
11
Obrigado pela postagem, o nginx armazena em cache as respostas node.js do servidor acima ou as executa novamente a cada vez.
cal
79
Existe alguma razão pela qual você não pode simplesmente fazer location / { proxy_pass http://127.0.0.1:3000; }? Por que você precisa de todo o upstreambit de configuração?
Robin Winslow
20
+1, resposta muito direta e simples a uma pergunta comum; ótimo para pessoas que desejam configurar hosts virtuais usando node e nginx. A única coisa que acho que você perdeu foi uma resposta qualitativa para o porquê o nginx-in-front-of-node é melhor para atender a vários vhosts (segunda pergunta do solicitante).
Paul d'Aoust 6/03/12
34
@Robin Winslow, caso você queira adicionar mais servidores para servidores para balanceamento de carga.
Joao Da Silva
76
Deve-se notar que esta resposta (muito útil) se refere a um tipo de nginx que, por padrão, vem com diretórios sites-enablede sites-availabledentro dele /etc/nginx. Se a sua versão veio sem esses dois diretórios, provavelmente ela possui um único conf.ddiretório. Nesse caso, seguir estas instruções não terá efeito, a menos que você modifique a includeinstrução dentro do arquivo nginx.confpara apontar para em sites-enabledvez do padrão conf.d. Espero que isso faça sentido. Deve tornar-se auto-explicativo quando você ver a includedeclaração em questão nginx.conf.
Meetamit 18/10/12
167

Você também pode configurar vários domínios com nginx, encaminhando para vários processos node.js.

Por exemplo, para obter estes:

Essas portas (4000 e 5000) devem ser usadas para escutar as solicitações de aplicativos em seu código.

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

Em / 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
fonte
5
Estou usando o seu método proxy_pass, mas por algum motivo http://example.comé automaticamente 302necessário http://www.example.com. Por que é que?
Kristian
Você tem Cloudflare ou algo semelhante? A configuração acima não deve ser redirecionada.
ozzieisaacs
1
@ Kristian Você precisará adicionar proxy_set_header Host $hostpara evitar o redirecionamento HTTP 302.
precisa
@IvanShatsky - Você pode fornecer qualquer ajuda como configurar várias portas com sub-domínio múltiplo e evitar que outras portas que funcionam em outro domínio nginx v 1.14.1?
151.291
59

Você também pode ter diferentes URLs para aplicativos em uma configuração de servidor:

Em / 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 o nginx:

sudo service nginx restart

Iniciando aplicativos.

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

nó 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
fonte
3
A versão da comunidade de código aberto é gratuita, mas eles têm versão com outros recursos que não são gratuitos. nginx.com/products/feature-matrix
0x8BADF00D 7/16
Desculpe pela minha ignorância. Qual é o propósito, os benefícios de servi-lo dessa maneira? você tem algum exemplo ou caso de uso? Desde já, obrigado.
Mauro Aguilar
2
@MauroAguilar Se você precisar de um aplicativo 2 node.js em um servidor, poderá servi-los da maneira sugerida (usando portas diferentes). Nos meus casos, eram dois aplicativos de teste diferentes.
0x8BADF00D
Ok, mas qual é a diferença entre executar 2 aplicativos e um único? Quero dizer, quais são os benefícios se eles foram projetados para o mesmo objetivo?
Mauro Aguilar
2
@MauroAguilar, você pode executá-los em um único e não há benefício se ele puder fazer parte de um projeto e tiver o mesmo objetivo. Mas se você precisar executar 2 projetos diferentes com finalidades diferentes e configurações diferentes em um servidor, terá o benefício de usar essa configuração.
0x8BADF00D
35

Procuro aplicativos Node Express independentes por meio do Nginx.

Assim, novos aplicativos podem ser facilmente montados e também posso executar outras coisas no mesmo servidor em locais diferentes.

Aqui estão mais detalhes sobre minha instalação com o exemplo de configuração do Nginx:

Implante vários aplicativos Nó em um servidor Web em subpastas com Nginx

As coisas ficam complicadas com o Node quando você precisa mover seu aplicativo do host local para a Internet.

Não há uma abordagem comum para a implantação do nó.

O Google pode encontrar vários artigos sobre esse tópico, mas eu estava lutando para encontrar a solução adequada para a instalação necessária.

Basicamente, eu tenho um servidor web e quero que os aplicativos Node sejam montados em subpastas (por exemplo, http: // myhost / demo / pet-project / ) sem introduzir nenhuma dependência de configuração no código do aplicativo.

Ao mesmo tempo, quero que outras coisas, como o blog, sejam executadas no mesmo servidor da web.

Parece simples né? Aparentemente não.

Em muitos exemplos, os aplicativos do nó da web são executados na porta 80 ou são proxy pelo Nginx na raiz.

Embora ambas as abordagens sejam válidas para certos casos de uso, elas não atendem aos meus critérios simples, mas um pouco exóticos.

Por isso, criei minha própria configuração do Nginx e aqui está um extrato:

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

Neste exemplo, você pode perceber que eu monto meu aplicativo Nó do Projeto Pet em execução na porta 3000 para http: // myhost / demo / pet-project .

Primeiro, o Nginx verifica se o recurso solicitado é um arquivo estático disponível em / opt / demo / pet-project / public / e, se for o caso, serve como altamente eficiente, portanto, não precisamos ter uma camada redundante como o Connect middleware estático.

Todas as outras solicitações são substituídas e submetidas a proxy no aplicativo Pet Project Node , para que o aplicativo Node não precise saber onde ele está realmente montado e, portanto, pode ser movido para qualquer lugar apenas pela configuração.

proxy_redirect é necessário para manipular o cabeçalho do local corretamente. Isso é extremamente importante se você usar res.redirect () no aplicativo Node.

Você pode replicar facilmente essa configuração para vários aplicativos Node em execução em portas diferentes e adicionar mais manipuladores de local para outros fins.

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

skovalyov
fonte
1
Por que e como você deve fazer isso em subdomínios: skovalyov.blogspot.dk/2012/10/…
skovalyov
Responder apenas ao link ... você pode resumir as partes relevantes da sua resposta, caso o seu blog não seja publicado?
kaiser
11

Node.js com configuração do Nginx.

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

adicione a seguinte configuração para que o Nginx, que atua como um proxy, redirecione para o tráfego da porta 3000 do servidor quando viermos de "subdomínio.seu_domínio.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
fonte
9

respondendo sua pergunta 2:

Eu usaria a opção bsimplesmente porque consome muito menos recursos. com a opção 'a', todo cliente fará com que o servidor consuma muita memória, carregando todos os arquivos que você precisa (mesmo que eu goste de php, este é um dos problemas). Com a opção 'b', você pode carregar suas bibliotecas (código reutilizável) e compartilhá-las entre todas as solicitações de clientes.

Mas lembre-se de que, se você tiver vários núcleos, deverá ajustar o node.js para usar todos eles.

Hugo Mota
fonte
2
Siga este conselho se os recursos forem o problema mais importante (improvável). Existem diferentes compromissos entre (a) e (b). Opção (a) é provavelmente melhor se você quiser os locais para ser restart mais independente por exemplo, site ou manutenção, conexões db, base de código, dependências de bibliotecas, locais móveis entre servidores, etc.
robocat
8

Eu criei um repositório no Github que você pode clonar, vagrant-node-nginx-boilerplate

basicamente, o aplicativo node.js /var/www/nodeappé

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

e a configuração nginx em /etc/nginx/sites-available/é

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

Você também pode usar o node.js para gerar arquivos estáticos em um diretório servido pelo nginx. Obviamente, algumas partes dinâmicas do seu site podem ser veiculadas por nó e outras por nginx (estático).

Ter alguns deles servidos pelo nginx aumenta seu desempenho.

Matej
fonte
5

Podemos configurar facilmente um aplicativo Nodejs, usando o Nginx como um proxy reverso.
A configuração a seguir assume que o aplicativo NodeJS está sendo executado em 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
     }
   } 

na configuração acima, seu aplicativo Nodejs irá,

  • obtenha o HTTP_HOSTcabeçalho no qual você pode aplicar a lógica específica do domínio para servir a resposta. "
  • Seu aplicativo deve ser gerenciado por um gerente de processo como pm2 ou supervisor para lidar com situações / reutilizar soquetes ou recursos etc.

  • Configure um serviço de relatório de erros para obter erros de produção, como sentinela ou barra de rolagem

NOTA: você pode configurar a lógica para entregar rotas de solicitação específicas do domínio, criar um middleware para o aplicativo expressjs

Renjith Thankachan
fonte
1
Outro motivo para usar o pm2 é para que você possa executar seu aplicativo 'para sempre' após sair do shell e iniciá-lo automaticamente se precisar reiniciar o servidor, consulte: pm2.keymetrics.io/docs/usage/startup
SeanQuinn781
3

O Nginx pode atuar como um servidor proxy reverso, que funciona como um gerente de projeto. Quando recebe uma solicitação, ela a analisa e encaminha a solicitação para o upstream (membros do projeto) ou se auto-administra. O Nginx tem duas maneiras de lidar com uma solicitação com base em como ela é configurada.

  • servir o pedido
  • encaminhar a solicitação para outro 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 da solicitação

Com essa configuração, quando o URL da solicitação é, mydomain.com/static/myjs.jsele retorna o myjs.jsarquivo na /my/static/files/pathpasta Quando você configura o nginx para servir arquivos estáticos, ele lida com a própria solicitação.

encaminhar a solicitação para outro servidor

Quando o URL da solicitação for mydomain.com/dothisnginx, a solicitação será encaminhada para http://127.0.0.1:8000 . O serviço que está sendo executado na porta localhost 8000 receberá a solicitação e retornará a resposta para nginx e nginx retornará a resposta para o cliente.

Quando você executa o servidor node.js na porta 8000, o nginx encaminha a solicitação para o node.js. Escreva a lógica node.js e manipule a solicitação. É isso que você tem no servidor nodejs executando atrás do servidor nginx.

Se você deseja executar qualquer outro serviço que não seja o nodejs, execute outro serviço como Django, flask, php em portas diferentes e configure-o no nginx.

Vkreddy Komatireddy
fonte
1

Você pode executar o nodejs usando o pm2 se desejar gerenciar cada meio de microsserviço e executá-lo. O nó estará sendo executado em uma porta, apenas configure-a no 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;
    }
}

Verifique se o host local está sendo executado ou não usando o ping.

E

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.

É melhor e, como você disse, mais fácil também

gokul kandasamy
fonte
1

A melhor e mais simples configuração com o Nginx e o Nodejs é usar o Nginx como um balanceador de carga HTTP e TCP com o proxy_protocol ativado. Nesse contexto, o Nginx poderá fazer proxy de solicitações de entrada para nodejs e também finalizar conexões SSL com os servidores Nginx de back-end, e não com o próprio servidor proxy. (Passagem SSL)

Na minha opinião, não faz sentido dar exemplos não SSL, pois todos os aplicativos da Web estão (ou deveriam estar) usando ambientes seguros.

Exemplo de configuração para o servidor proxy, em /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;
}

Agora, vamos lidar com o servidor da web de back-end. /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;
}

Agora, vamos configurar o host virtual com esta configuração habilitada para SSL e proxy_protocol em /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;
    }
}

E, finalmente, uma amostra de 2 servidores web nodejs : Primeiro 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/');

Agora tudo deve estar funcionando perfeitamente e com balanceamento de carga.

Há um tempo atrás, escrevi sobre Como configurar o Nginx como um balanceador de carga TCP no Docker . Confira se você estiver usando o Docker.

Cético
fonte