Nginx как reverse proxy: настройка, заголовки и SSL
Когда несколько приложений живут на одном сервере и нужно отдавать их через единый домен и порт 443 — на сцену выходит Nginx в роли reverse proxy. Он принимает запросы извне и перенаправляет их нужному backend-сервису, скрывая внутреннюю структуру инфраструктуры.
Зачем нужен reverse proxy
- Единая точка входа — один домен и один порт наружу, сервисы внутри на разных портах.
- SSL в одном месте — терминируешь HTTPS на Nginx, backend остаётся на HTTP.
- Балансировка нагрузки — распределяешь запросы между несколькими инстансами.
- Доп. безопасность — backend не торчит наружу напрямую.
Базовая конфигурация
Минимальный конфиг, который проксирует запросы на локальное приложение:
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:3000;
}
}
proxy_pass указывает, куда Nginx перенаправит запрос. Этого достаточно для старта, но без передачи заголовков backend не увидит реальный IP клиента и оригинальный хост.
Передача заголовков
Чтобы backend получал корректную информацию о клиенте:
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
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;
}
Что делают заголовки:
Host— передаёт оригинальный домен запроса.X-Real-IP— реальный IP клиента вместо адреса Nginx.X-Forwarded-For— цепочка прокси, через которые прошёл запрос.X-Forwarded-Proto— исходный протокол (http/https), важно для приложений, которые формируют ссылки на себя.
Несколько сервисов через один домен
Маршрутизация по путям:
server {
listen 80;
server_name example.com;
location /api/ {
proxy_pass http://127.0.0.1:4000/;
}
location /app/ {
proxy_pass http://127.0.0.1:5000/;
}
location / {
proxy_pass http://127.0.0.1:3000;
}
}
Завершающий слэш в proxy_pass важен — он определяет, обрезается ли совпавший префикс пути перед отправкой на backend.
Поддержка WebSocket
Для приложений, использующих WebSocket (чаты, live-обновления, dev-серверы фронтенда), нужны дополнительные заголовки апгрейда соединения:
location /ws/ {
proxy_pass http://127.0.0.1:6000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
Без proxy_http_version 1.1 и заголовков Upgrade/Connection соединение не апгрейдится с HTTP до WebSocket.
Балансировка нагрузки
Если backend представлен несколькими инстансами, описываешь их через upstream:
upstream backend_pool {
server 127.0.0.1:3001;
server 127.0.0.1:3002;
server 127.0.0.1:3003;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://backend_pool;
}
}
По умолчанию Nginx распределяет запросы по кругу (round-robin). Для других стратегий есть директивы least_conn (на наименее загруженный сервер) и ip_hash (привязка клиента к одному серверу по IP — полезно для сессий).
SSL через Let's Encrypt
Проще всего получить и подключить сертификат через certbot:
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
Certbot сам найдёт нужный server блок, выпустит сертификат, добавит в конфиг директивы listen 443 ssl и редирект с HTTP на HTTPS, и настроит автопродление.
Проверить, что автопродление работает:
sudo certbot renew --dry-run
Проверка конфигурации и применение изменений
Перед перезапуском всегда стоит проверить синтаксис:
sudo nginx -t
Если всё ок — применяешь изменения без полного рестарта:
sudo systemctl reload nginx
Reverse proxy на Nginx — основа большинства продакшен-инфраструктур: один вход, множество сервисов внутри, SSL в одном месте и гибкая маршрутизация. Базовой конфигурации из этого гайда хватит для старта почти любого проекта — дальше добавляешь кэширование, лимиты запросов и прочую тонкую настройку по мере роста нагрузки.
Если хочешь обсудить похожую задачу — пиши на [email protected] или заходи на 1it.pro.