proxy_pass в nginx: как передать запросы приложению
Директива proxy_pass передаёт запросы из блока location другому серверу — например, приложению на Node.js или Python, которое слушает порт 3000 на том же VPS. nginx принимает посетителей на портах 80 и 443 и отдаёт им ответ приложения.
Содержание 8
Что сделать прямо сейчас
- Команды вводятся на сервере: подключитесь к нему по SSH ([как подключиться](/instrukcii/kak-podklyuchitsya-k-vps-po-ssh/)) и набирайте их в том же окне.
- Проверьте, что приложение отвечает:
curl -I http://127.0.0.1:3000. Вместо 3000 — порт приложения. Если в первой строке ответа есть код, например 200 или 404, приложение работает. Если curl не может подключиться, приложение не запущено или слушает другой порт — как запустить. - Откройте файл сайта:
sudo nano /etc/nginx/sites-available/example.com. Вместо example.com — имя файла вашего сайта: список покажетls /etc/nginx/sites-enabled/. Если система спросит пароль, введите пароль своего пользователя на сервере. Символы при вводе не видны — наберите пароль и нажмите Enter. - В блоке server замените блок
location /тем, что ниже. Второй блокlocation /не добавляйте. - Сохраните файл — Ctrl+O, Enter, затем Ctrl+X — и проверьте настройки:
sudo nginx -t. В ответе должны быть слова syntax is ok и test is successful. Тогда примените их:sudo systemctl reload nginx. Если команда ничего не ответила, настройки применены.
Если проверка нашла ошибку, nginx назовёт файл и номер строки, а сайт продолжит работать на старых настройках. Что значит сообщение — Все ошибки nginx.
Приложение на том же сервере
location / {
proxy_pass http://127.0.0.1:3000;
include proxy_params;
}Вместо 3000 — порт вашего приложения. nginx передаёт приложению адрес запроса в том виде, в каком его прислал посетитель.
Строка include proxy_params подключает файл из пакета nginx в Ubuntu. В нём четыре строки:
| Строка | Что узнаёт приложение |
|---|---|
proxy_set_header Host $http_host; | имя сайта из запроса, например example.com |
proxy_set_header X-Real-IP $remote_addr; | IP-адрес посетителя |
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | цепочку адресов: к тому, что пришло в запросе, через запятую добавляется IP посетителя |
proxy_set_header X-Forwarded-Proto $scheme; | протокол: http или https |
Без этих строк приложение видит вместо имени сайта адрес из proxy_pass — 127.0.0.1:3000, а вместо IP посетителя — 127.0.0.1.
Запускайте приложение на адресе 127.0.0.1: тогда до него не достучаться снаружи в обход nginx, и порт 3000 в фаерволе открывать не нужно. Как поставить nginx перед приложением с самого начала — в инструкции по размещению сайта.
Слэш после порта меняет адрес
Важно, есть ли что-то после адреса и порта в proxy_pass, — даже один слэш:
location /api/ {
proxy_pass http://127.0.0.1:3000;
}location /api/ {
proxy_pass http://127.0.0.1:3000/;
}| Строка proxy_pass в location /api/ | Адрес в браузере | Что получит приложение |
|---|---|---|
http://127.0.0.1:3000 | /api/users?id=5 | /api/users?id=5 |
http://127.0.0.1:3000/ | /api/users?id=5 | /users?id=5 |
http://127.0.0.1:3000/v2/ | /api/users?id=5 | /v2/users?id=5 |
Правило такое. Если после порта ничего нет, адрес уходит приложению как пришёл. Если есть путь, nginx заменяет им часть адреса, совпавшую с location.
Пишите слэш в конце одинаково у location и proxy_pass. Блок location /api со строкой proxy_pass http://127.0.0.1:3000/ отдаст приложению адрес //users с двумя слэшами.
В location с регулярным выражением и в именованном location с @ после порта ничего писать нельзя: проверка sudo nginx -t выдаст ошибку "proxy_pass" cannot have URI part.
Если location записан со слэшем в конце, на адрес без слэша — /api — nginx ответит переадресацией 301 на /api/. Как этого избежать — в разделе про слэш.
WebSocket
Если приложение использует WebSocket — чат, уведомления без перезагрузки страницы, — добавьте в его location ещё три строки:
location / {
proxy_pass http://127.0.0.1:3000;
include proxy_params;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}Заголовки Upgrade и Connection nginx приложению сам не передаёт — их задают явно. Строка proxy_http_version 1.1 нужна в nginx из Ubuntu 24.04 и 26.04: он по умолчанию обращается к приложению по HTTP/1.0, а сменить протокол на WebSocket через заголовок Upgrade можно только в HTTP/1.1.
Пишите эти строки в том же блоке, где include proxy_params. Если в location есть хоть одна своя строка proxy_set_header, строки proxy_set_header из server и http в нём не действуют.
Если по WebSocket 60 секунд не идут данные, nginx закрывает соединение. Чтобы держать его дольше, поднимите таймаут, например proxy_read_timeout 1h;, или настройте в приложении периодическую отправку ping.
Таймауты
| Директива | По умолчанию | Сколько nginx ждёт |
|---|---|---|
proxy_connect_timeout | 60s | подключения к приложению |
proxy_send_timeout | 60s | между двумя отправками запроса приложению |
proxy_read_timeout | 60s | между двумя порциями ответа приложения |
Таймауты считаются не на весь ответ, а на паузу между порциями данных. Если приложение молчит дольше proxy_read_timeout, посетитель получит 504 — какие таймауты за это отвечают и как поднять.
Ошибки и как их исправить
| Что видите | Что делать |
|---|---|
502, в журнале connect() failed (111: Connection refused) while connecting to upstream | приложение не запущено или слушает другой порт |
502, в журнале upstream prematurely closed connection | приложение оборвало ответ |
| 504 Gateway Time-out | приложение отвечает дольше таймаута |
host not found in upstream при проверке nginx -t | nginx не нашёл IP для имени из proxy_pass |
"proxy_pass" cannot have URI part in location given by regular expression… | уберите всё после порта: в таком location адрес пишут без пути |
| приложение получает адрес без /api или с двумя слэшами | проверьте слэш после порта |
| WebSocket не подключается | добавьте три строки |
| приложение видит IP 127.0.0.1 вместо адреса посетителя | добавьте include proxy_params; в тот же location, где proxy_pass |
Источники
- Документация nginx: proxy_pass — адрес с путём и без, location с регулярным выражением и именованный.
- Документация nginx: proxy_set_header — по умолчанию Host $proxy_host и Connection close; строки из внешнего блока не действуют, если в блоке есть свои.
- Документация nginx: proxy_read_timeout — по умолчанию 60s, считается между двумя операциями чтения; так же устроены proxy_send_timeout и proxy_connect_timeout.
- Документация nginx: проксирование WebSocket — заголовки Upgrade и Connection передаются явно, без данных соединение закрывается через 60 секунд.
- Файл proxy_params из пакета nginx в Ubuntu 24.04 — заголовки Host, X-Real-IP, X-Forwarded-For и X-Forwarded-Proto.
- Исходный код nginx 1.24.0: ngx_http_proxy_module.c — текст ошибки cannot have URI part in location given by regular expression; по умолчанию proxy_http_version 1.0.
Сверено 14 октября 2026 года.
Что почитать дальше
- Настройки nginxкак устроены файлы и блоки, главные директивы.
- Как установить Node.js на Ubuntuустановка и запуск приложения службой systemd.
- Python, pip и venv на Ubuntuокружение для приложения на Python.
- 502 Bad Gatewayвсе причины и как найти нужную по журналу.
- 504 Gateway Timeoutесли приложение отвечает слишком долго.
- try_files в nginxфайлы отдаёт nginx, остальное — приложение.