Node.js + Nginx - что теперь?

1003

Я установил Node.js и Nginx на моем сервере. Сейчас я хочу его использовать, но перед тем, как начать, есть 2 вопроса:

  1. Как они должны работать вместе? Как я должен обрабатывать запросы?
  2. Для сервера Node.js есть 2 концепции, которые лучше:

    а. Создайте отдельный HTTP-сервер для каждого веб-сайта, который нуждается в этом. Затем загрузите весь код JavaScript в начале программы, чтобы код интерпретировался один раз.

    б. Создайте один сервер Node.js, который обрабатывает все запросы Node.js. Это читает запрошенные файлы и проверяет их содержимое. Таким образом, файлы интерпретируются при каждом запросе, но логика сервера намного проще.

Мне не понятно, как правильно использовать Node.js.

Ван Кодинг
источник

Ответы:

1306

Nginx работает как сервер переднего плана, который в этом случае передает запросы на сервер node.js. Поэтому вам нужно настроить конфигурационный файл nginx для узла.

Это то, что я сделал в своей коробке Ubuntu:

Создайте файл по yourdomain.comадресу /etc/nginx/sites-available/:

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

В нем должно быть что-то вроде:

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

Если вы хотите, чтобы nginx (> = 1.3.13) также обрабатывал запросы веб-сокетов, добавьте следующие строки в location /раздел:

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

Как только у вас есть эта настройка, вы должны включить сайт, определенный в конфигурационном файле выше:

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

Создайте свое приложение сервера узла на /var/www/yourdomain/app.jsи запустите его наlocalhost: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/');

Тест на синтаксические ошибки:

nginx -t

Перезапустите nginx:

sudo /etc/init.d/nginx restart

Наконец запустите сервер узла:

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

Теперь вы должны увидеть «Hello World» на yourdomain.com

Последнее замечание относительно запуска сервера узлов: вы должны использовать какую-то систему мониторинга для демона узла. На узле есть удивительное руководство с upstart и monit .

Жоао да Силва
источник
11
Спасибо за сообщение, будет ли nginx кеш node.js ответов для сервера выше или перезапускать их каждый раз.
Лайм
79
Есть ли причина, почему вы не можете просто сделать location / { proxy_pass http://127.0.0.1:3000; }? Зачем вам нужен весь upstreamбит конфигурации?
Робин Уинслоу
20
+1, очень простой и простой ответ на общий вопрос; отлично подходит для людей, которые хотят настроить виртуальные хосты, используя node и nginx. Единственное, что, я думаю, вы пропустили - это качественный ответ на вопрос, почему nginx-in-front-of-node-node лучше всего подходит для обслуживания нескольких vhosts (второй вопрос Аскера).
Поль д'Ауст
34
@Robin Winslow, если вы хотите добавить больше серверов для серверов для балансировки нагрузки.
Жоао да Силва
76
Следует отметить , что это (очень полезно) ответ относится к одному аромату Nginx , что, по умолчанию, поставляется с sites-enabledи sites-availableкаталогов внутри /etc/nginx. Если ваша версия поставляется без этих двух каталогов, скорее всего, conf.dвместо нее есть один каталог. В этом случае, следование этим инструкциям не будет иметь никакого эффекта, ЕСЛИ ВЫ не измените includeоператор внутри файла, nginx.confчтобы он указывал sites-enabledвместо значения по умолчанию conf.d. Надеюсь, что это имеет смысл. Это должно стать самоочевидным, как только вы увидите указанное includeутверждение внутри nginx.conf.
Meetamit
167

Вы также можете настроить несколько доменов с помощью nginx, перенаправив их на несколько процессов node.js.

Например, чтобы достичь этого:

  • domain1.com -> к процессу Node.js, работающему локально http://127.0.0.1:4000
  • domain2.com -> к процессу Node.js, работающему локально http://127.0.0.1:5000

Эти порты (4000 и 5000) должны использоваться для прослушивания запросов приложения в коде вашего приложения.

/ И т.д. / Nginx / сайты с поддержкой / 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/;
    }
}

В / 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
источник
5
Я использую свой метод proxy_pass, но по какой - то причине http://example.comстановится автоматически 302«цифро http://www.example.com. Это почему?
Кристиан
У вас есть Cloudflare или что-то подобное? Приведенная выше конфигурация вообще не должна перенаправляться.
ozzieisaacs
1
@Kristian Вам нужно будет добавить, proxy_set_header Host $hostчтобы избежать перенаправления HTTP 302.
Иван Шацкий
@IvanShatsky - Можете ли вы помочь с настройкой нескольких портов в нескольких поддоменах и
запретом работы
59

Вы также можете иметь разные URL для приложений в одной конфигурации сервера:

  • yourdomain.com/app1/* -> к процессу Node.js, работающему локально http://127.0.0.1:3000
  • yourdomain.com/app2/*-> к процессу Node.js, работающему локально http://127.0.0.1:4000

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

Перезапустите nginx:

sudo service nginx restart

Запуск приложений.

узел 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/');

узел 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
источник
3
Версия сообщества с открытым исходным кодом бесплатна, но у них есть версия с другими функциями, которые не являются бесплатными. nginx.com/products/feature-matrix
0x8BADF00D
Извините за мое невежество. Какова цель, преимущества такого обслуживания? у вас есть пример или случай использования? Заранее спасибо.
Мауро Агилар
2
@MauroAguilar Если вам нужно приложение 2 node.js на одном сервере, вы можете обслуживать их предложенным способом (используя разные порты). В моих случаях это были два разных тестовых приложения.
0x8BADF00D
Хорошо, но в чем разница между запуском двух приложений и одного? Я имею в виду, каковы преимущества, если они были предназначены для той же цели?
Мауро Агилар
2
@MauroAguilar, вы можете запустить их в одном, и нет никакой выгоды, если он может быть частью одного проекта и имеет ту же цель. Но если вам нужно запустить 2 разных проекта с разными целями и с разными конфигурациями на одном сервере, вы можете воспользоваться этой конфигурацией.
0x8BADF00D
35

Я прокси-независимые приложения Node Express через Nginx.

Таким образом, новые приложения легко монтируются, и я также могу запускать другие компоненты на одном сервере в разных местах.

Вот более подробная информация о моей настройке с примером конфигурации Nginx:

Разверните несколько приложений Node на одном веб-сервере в подпапках с помощью Nginx

С Node все усложняется, когда вам нужно переместить ваше приложение с локального хоста в Интернет.

Не существует общего подхода для развертывания Node.

Google может найти тонны статей на эту тему, но я изо всех сил пытался найти правильное решение для нужной мне установки.

По сути, у меня есть веб-сервер, и я хочу, чтобы приложения Node монтировались во вложенные папки (т . Е. Http: // myhost / demo / pet-project / ) без какой-либо зависимости конфигурации от кода приложения.

В то же время я хочу, чтобы другие вещи, такие как блог, работали на том же веб-сервере.

Звучит просто, а? Очевидно нет.

Во многих примерах на веб-узлах приложения либо запускаются через порт 80, либо через Nginx проксируются в корень.

Несмотря на то, что оба подхода действительны для определенных вариантов использования, они не соответствуют моим простым, но немного экзотическим критериям.

Вот почему я создал свою собственную конфигурацию Nginx и вот выдержка:

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

Из этого примера вы можете заметить, что я подключаю свое приложение Pet Project Node, работающее на порту 3000, к http: // myhost / demo / pet-project .

Сначала Nginx проверяет, является ли запрошенный ресурс статическим файлом, доступным по адресу / opt / demo / pet-project / public /, и в этом случае он работает очень эффективно, поэтому нам не нужен избыточный слой, такой как Connect. статическое промежуточное ПО.

Затем все другие запросы перезаписываются и передаются в приложение Pet Project Node , поэтому приложению Node не нужно знать, где оно фактически смонтировано, и, таким образом, его можно переместить куда угодно только посредством конфигурации.

proxy_redirect необходим для правильной обработки заголовка Location. Это чрезвычайно важно, если вы используете res.redirect () в своем приложении Node.

Вы можете легко скопировать эту настройку для нескольких приложений Node, работающих на разных портах, и добавить дополнительные обработчики местоположения для других целей.

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

skovalyov
источник
1
Почему и как вы должны сделать это в поддоменах: skovalyov.blogspot.dk/2012/10/…
сковалёв
Ответ только по ссылке ... не могли бы вы обобщить соответствующие части в своем ответе, если ваш блог исчез?
Кайзер
11

Node.js с конфигурацией Nginx.

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

добавьте следующую конфигурацию, чтобы Nginx выступал в качестве прокси-сервера перенаправления на порт 3000 трафика с сервера, когда мы пришли с «subdomain.your_domain.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
источник
9

отвечая на ваш вопрос 2:

Я бы использовал вариант b просто потому, что она потребляет гораздо меньше ресурсов. с опцией 'a' каждый клиент будет заставлять сервер потреблять много памяти, загружая все нужные вам файлы (хотя мне нравится php, это одна из проблем с ним). С опцией 'b' вы можете загружать свои библиотеки (повторно используемый код) и делиться ими между всеми клиентскими запросами.

Но имейте в виду, что если у вас несколько ядер, вам нужно настроить node.js, чтобы использовать их все.

Хьюго Мота
источник
2
Следуйте этому совету, если ресурсы - ваша самая важная проблема (маловероятно). Есть разные компромиссы между (а) и (б). Вариант (а), вероятно, предпочтительнее, если вы хотите, чтобы сайты были более независимыми, например, перезапуск или обслуживание сайтов, соединения базы данных, кодовая база, зависимости библиотек, перемещение сайтов между серверами и т. Д.
robocat
8

Я сделал репозиторий в Github, который вы можете клонировать, vagrant-node-nginx-шаблон

в основном node.js приложения на /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/');

и конфиг nginx в /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
источник
5

Вы также можете использовать node.js для генерации статических файлов в каталог, обслуживаемый nginx. Конечно, некоторые динамические части вашего сайта могут обслуживаться узлами, а некоторые - nginx (статическими).

Если некоторые из них обслуживаются nginx, это повышает вашу производительность.

Матей
источник
5

Мы можем легко настроить приложение Nodejs с помощью Nginx, действующего в качестве обратного прокси.
В следующей конфигурации предполагается, что приложение NodeJS работает на 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
     }
   } 

в приведенной выше настройке ваше приложение Nodejs будет,

  • получить HTTP_HOSTзаголовок, в котором вы можете применить доменную логику для ответа. '
  • Ваше приложение должно управляться менеджером процессов, таким как pm2 или супервизором, для обработки ситуаций / повторного использования сокетов или ресурсов и т. Д.

  • Настройка службы отчетов об ошибках для получения производственных ошибок, таких как сторожевой или роликовый

ПРИМЕЧАНИЕ: вы можете настроить логику для обработки маршрутов запросов к конкретному домену, создать промежуточное программное обеспечение для приложения expressjs

Ренджит Саячан
источник
1
Другая причина использования pm2 заключается в том, что вы можете запускать приложение «навсегда» после выхода из оболочки и автоматически запускать его, если вам когда-либо понадобится перезагрузить сервер, см. Pm2.keymetrics.io/docs/usage/startup
SeanQuinn781
3

Nginx может действовать как обратный прокси-сервер, который работает так же, как менеджер проекта. Когда он получает запрос, он анализирует его и направляет запрос в апстрим (участники проекта) или обрабатывает сам. У Nginx есть два способа обработки запроса в зависимости от его конфигурации.

  • обслуживать запрос
  • переслать запрос на другой сервер

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

    }

Сервер запрос

При такой конфигурации, когда URL-адрес запроса mydomain.com/static/myjs.jsвернет myjs.jsфайл в /my/static/files/pathпапку. Когда вы настраиваете nginx для обслуживания статических файлов, он обрабатывает сам запрос.

переслать запрос на другой сервер

Когда URL-адрес запроса равен mydomain.com/dothisnginx, он перенаправляет запрос на http://127.0.0.1:8000 . Служба, работающая на порте localhost 8000, получит запрос и вернет ответ nginx, а nginx вернет ответ клиенту.

Когда вы запускаете сервер node.js на порт 8000, nginx перенаправляет запрос на node.js. Напишите логику node.js и обработайте запрос. Вот и все, у вас есть сервер nodejs, работающий за сервером nginx.

Если вы хотите запускать любые другие сервисы, кроме nodejs, просто запустите другой сервис, такой как Django, flask, php, на разных портах и ​​настройте его в nginx.

Вкредди Коматиредды
источник
1

Вы можете запустить nodejs, используя pm2, если вы хотите управлять каждым средством микросервиса и запускать его. Узел будет работать в правом порту, просто настройте этот порт в 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;
    }
}

Проверьте, работает ли localhost или нет с помощью ping.

А также

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.

Это лучше, и, как вы сказали, тоже проще

Gokul Kandasamy
источник
1

Лучшая и более простая установка с Nginx и Nodejs - это использовать Nginx в качестве балансировщика нагрузки HTTP и TCP с включенным proxy_protocol. В этом контексте Nginx сможет проксировать входящие запросы к nodejs, а также разорвать SSL-соединения с внутренним сервером (ами) Nginx, а не с самим прокси-сервером. (SSL-Сквозной)

По моему мнению, нет смысла приводить примеры, не относящиеся к SSL, поскольку все веб-приложения (или должны) использовать безопасные среды.

Пример конфигурации для прокси-сервера в /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;
}

Теперь давайте разберемся с внутренним веб-сервером. /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;
}

Теперь давайте настроим виртуальный хост с этой конфигурацией с поддержкой SSL и proxy_protocol в /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;
    }
}

И, наконец, пример 2 веб- серверов nodejs : Первый сервер:

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

Второй сервер:

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

Теперь все должно быть идеально работающим и сбалансированным по нагрузке.

Некоторое время назад я писал о том, как настроить Nginx в качестве балансировщика нагрузки TCP в Docker . Проверьте это, если вы используете Docker.

скептик
источник