Это распространённый метод использования NGINX в качестве прокси-сервера HTTP для PM2. NGINX позволит быстро обслуживать статические файлы, управлять протоколом SSL и перенаправлять трафик в ваше приложение Node.js.
Вот пример приложения Node.js, прослушивающего порт 3001, и NGINX, перенаправляющего трафик с порта 443 (HTTPS) на 3001. Этот пример также будет обрабатывать соединения Websocket.
Конфигурационный файл для виртуального хоста nginx.conf:
upstream my_nodejs_upstream {
server 127.0.0.1:3001;
keepalive 64;
}
server {
listen 443 ssl;
server_name www.my-website.com;
ssl_certificate_key /etc/ssl/main.key;
ssl_certificate /etc/ssl/main.crt;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_pass http://my_nodejs_upstream/;
proxy_redirect off;
proxy_read_timeout 240s;
}
}
Узнайте больше об этих параметрах в документации Nginx! После этого всё, что вам понадобится, — это связанный с PM2 сервер Node.js, работающий на порту 3001, и у вас будет готовый к работе HTTP-сервер!
Директива proxy_http_version
Ссылка: https://nginx.org/ru/docs/http/ngx_http_proxy_module.html#proxy_http_version
Синтаксис: | proxy_http_version 1.0 | 1.1; |
---|---|
Умолчание: |
proxy_http_version 1.0; |
Контекст: | http , server , location |
Эта директива появилась в версии 1.1.4.
Задаёт версию протокола HTTP для проксирования. По умолчанию используется версия 1.0. Для работы постоянных соединений и проверки подлинности NTLM рекомендуется версия 1.1.
Директива proxy_set_header
Ссылка: https://nginx.org/ru/docs/http/ngx_http_proxy_module.html#proxy_set_header
Синтаксис: | proxy_set_header поле значение; |
---|---|
Умолчание: |
proxy_set_header Host $proxy_host; proxy_set_header Connection close; |
Контекст: | http , server , location |
Позволяет переопределять или добавлять поля заголовка запроса, передаваемые проксируемому серверу. В качестве значения можно использовать текст, переменные и их комбинации. Директивы наследуются с предыдущего уровня конфигурации при условии, что на данном уровне не описаны свои директивы proxy_set_header
. По умолчанию переопределяются только два поля:
proxy_set_header Host $proxy_host; proxy_set_header Connection close;
Если включено кэширование, поля заголовка “If-Modified-Since”, “If-Unmodified-Since”, “If-None-Match”, “If-Match”, “Range” и “If-Range” исходного запроса не передаются на проксируемый сервер.
Неизменённое поле заголовка запроса “Host” можно передать так:
proxy_set_header Host $http_host;
Однако, если это поле отсутствует в заголовке запроса клиента, то ничего передаваться не будет. В этом случае лучше воспользоваться переменной $host
— её значение равно имени сервера в поле “Host” заголовка запроса, или же основному имени сервера, если поля нет:
proxy_set_header Host $host;
Кроме того, можно передать имя сервера вместе с портом проксируемого сервера:
proxy_set_header Host $host:$proxy_port;
Если значение поля заголовка — пустая строка, то поле вообще не будет передаваться проксируемому серверу:
proxy_set_header Accept-Encoding "";
Директива proxy_pass
Ссылка: https://nginx.org/ru/docs/http/ngx_http_proxy_module.html#proxy_pass
Синтаксис: | proxy_pass URL; |
---|---|
Умолчание: | — |
Контекст: | location , if в location , limit_except |
Задаёт протокол и адрес проксируемого сервера, а также необязательный URI, на который должен отображаться location. В качестве протокола можно указать “http
” или “https
”. Адрес может быть указан в виде доменного имени или IP-адреса, и необязательного порта:
proxy_pass http://localhost:8000/uri/;
или в виде пути UNIX-сокета, который указывается после слова “unix
” и заключается в двоеточия:
proxy_pass http://unix:/tmp/backend.socket:/uri/;
Если доменному имени соответствует несколько адресов, то все они будут использоваться по очереди (round-robin). Кроме того, в качестве адреса можно указать группу серверов.
В значении параметра можно использовать переменные. В этом случае, если адрес указан в виде доменного имени, имя ищется среди описанных групп серверов и если не найдено, то определяется с помощью resolver’а.
URI запроса передаётся на сервер так:
- Если директива
proxy_pass
указана с URI, то при передаче запроса серверу часть нормализованного URI запроса, соответствующая location, заменяется на URI, указанный в директиве:
location /name/ { proxy_pass http://127.0.0.1/remote/; }
- Если директива
proxy_pass
указана без URI, то при обработке первоначального запроса на сервер передаётся URI запроса в том же виде, в каком его прислал клиент, а при обработке изменённого URI — нормализованный URI запроса целиком:
location /some/path/ { proxy_pass http://127.0.0.1; }
До версии 1.1.12, если
proxy_pass
указана без URI, в ряде случаев при изменении URI на сервер мог передаваться URI первоначального запроса вместо изменённого URI.
В ряде случаев часть URI запроса, подлежащую замене, выделить невозможно:
- Если location задан регулярным выражением, а также в именованных location’ах.В этих случаях
proxy_pass
следует указывать без URI. - Если внутри проксируемого location с помощью директивы rewrite изменяется URI, и именно с этой конфигурацией будет обрабатываться запрос (
break
):
location /name/ { rewrite /name/([^/]+) /users?name=$1 break; proxy_pass http://127.0.0.1; }
В этом случае URI, указанный в директиве, игнорируется, и на сервер передаётся изменённый URI запроса целиком.
- При использовании переменных в
proxy_pass
:
location /name/ { proxy_pass http://127.0.0.1$request_uri; }
В этом случае если в директиве указан URI, он передаётся на сервер как есть, заменяя URI первоначального запроса.
Проксирование WebSocket требует особой настройки и поддерживается начиная с версии 1.3.13.
Директива proxy_redirect
Ссылка: https://nginx.org/ru/docs/http/ngx_http_proxy_module.html#proxy_redirect
Синтаксис: | proxy_redirect default; proxy_redirect off; proxy_redirect перенаправление замена; |
---|---|
Умолчание: |
proxy_redirect default; |
Контекст: | http , server , location |
Задаёт текст, который нужно изменить в полях заголовка “Location” и “Refresh” в ответе проксируемого сервера. Предположим, проксируемый сервер вернул поле заголовка “Location: http://localhost:8000/two/some/uri/
”. Директива
proxy_redirect http://localhost:8000/two/ http://frontend/one/;
перепишет эту строку в виде “Location: http://frontend/one/some/uri/
”.
В заменяемой строке можно не указывать имя сервера:
proxy_redirect http://localhost:8000/two/ /;
тогда будут подставлены основное имя сервера и порт, если он отличен от 80.
Стандартная замена, задаваемая параметром default
, использует параметры директив location и proxy_pass. Поэтому две нижеприведённые конфигурации одинаковы:
location /one/ { proxy_pass http://upstream:port/two/; proxy_redirect default;
location /one/ { proxy_pass http://upstream:port/two/; proxy_redirect http://upstream:port/two/ /one/;
Параметр default
недопустим, если в proxy_pass используются переменные.
В строке замена
можно использовать переменные:
proxy_redirect http://localhost:8000/ http://$host:$server_port/;
В строке перенаправление
тоже можно использовать (1.1.11) переменные:
proxy_redirect http://$proxy_host:8000/ /;
Директиву также можно задать (1.1.11) при помощи регулярных выражений. При этом перенаправление
должно начинаться либо с символа “~
”, если при сравнении следует учитывать регистр символов, либо с символов “~*
”, если регистр символов учитывать не нужно. Регулярное выражение может содержать именованные и позиционные выделения, а замена
ссылаться на них:
proxy_redirect ~^(http://[^:]+):\d+(/.+)$ $1$2; proxy_redirect ~*/user/([^/]+)/(.+)$ http://$1.example.com/$2;
На одном уровне может быть указано несколько директив proxy_redirect
:
proxy_redirect default; proxy_redirect http://localhost:8000/ /; proxy_redirect http://www.example.com/ /;
Если к полям заголовка в ответе проксируемого сервера могут быть применены несколько директив, будет выбрана первая из них.
Параметр off
отменяет действие унаследованных с предыдущего уровня конфигурации директив proxy_redirect
.
С помощью этой директивы можно также добавлять имя хоста к относительным перенаправлениям, выдаваемым проксируемым сервером:
proxy_redirect / /;
Директива proxy_read_timeout
Ссылка: https://nginx.org/ru/docs/http/ngx_http_proxy_module.html#proxy_read_timeout
Синтаксис: | proxy_read_timeout время; |
---|---|
Умолчание: |
proxy_read_timeout 60s; |
Контекст: | http , server , location |
Задаёт таймаут при чтении ответа проксированного сервера. Таймаут устанавливается не на всю передачу ответа, а только между двумя операциями чтения. Если по истечении этого времени проксируемый сервер ничего не передаст, соединение закрывается.
Информационные ссылки
Документация PM2 — Раздел «Nginx as a HTTP proxy» — https://pm2.keymetrics.io/docs/tutorials/pm2-nginx-production-setup