Nginx: reverse proxy
Nginx в роли reverse proxy принимает внешние HTTP/HTTPS-запросы и перенаправляет их к внутреннему приложению (Node.js, Python, несколько upstream-серверов), добавляя SSL, кэширование и балансировку нагрузки.
Зачем нужно
Node.js нежелательно выставлять напрямую на 80/443 порт: это небезопасно, не поддерживает несколько доменов и не умеет обслуживать статику эффективно. Nginx выступает фасадом: принимает HTTPS, раздаёт статику, проксирует API на Node.js и балансирует нагрузку между несколькими инстансами.
Где используется
- Node.js/Python API за Nginx: HTTPS-терминация + проксирование
- Несколько приложений на одном сервере (разные домены)
- Балансировка нагрузки между несколькими backend-серверами
- Раздача статических файлов напрямую без обращения к приложению
Основной контент
Базовый reverse proxy для Node.js
# /etc/nginx/sites-available/myapp
server {
listen 80;
server_name api.example.com;
return 301 https://$host$request_uri; # редирект HTTP → HTTPS
}
server {
listen 443 ssl http2;
server_name api.example.com;
# SSL (Let's Encrypt через certbot)
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
# Проксирование на Node.js
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
# WebSocket поддержка
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
# Передача реального IP клиента
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;
proxy_cache_bypass $http_upgrade;
proxy_read_timeout 90s;
}
# Статические файлы — Nginx отдаёт напрямую
location /static/ {
alias /var/www/myapp/public/;
expires 1y;
add_header Cache-Control "public, immutable";
}
}
Балансировка нагрузки
upstream api_backend {
least_conn; # алгоритм: наименее нагруженный
server 127.0.0.1:3001;
server 127.0.0.1:3002;
server 127.0.0.1:3003;
keepalive 32; # переиспользовать соединения
}
server {
listen 443 ssl http2;
server_name api.example.com;
location / {
proxy_pass http://api_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
Несколько приложений на одном сервере
# Frontend (React)
server {
listen 443 ssl http2;
server_name example.com www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
root /var/www/frontend/dist;
index index.html;
# SPA: все маршруты → index.html
location / {
try_files $uri $uri/ /index.html;
}
}
# API
server {
listen 443 ssl http2;
server_name api.example.com;
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
location / {
proxy_pass http://127.0.0.1:3000;
}
}
Полезные команды
nginx -t # проверить конфиг (без применения)
nginx -s reload # перезагрузить конфиг без рестарта
systemctl status nginx
tail -f /var/log/nginx/access.log
tail -f /var/log/nginx/error.log
Частые ошибки
- Не передавать
X-Forwarded-For— приложение видит IP Nginx, не реального клиента - Не настроить
proxy_read_timeout— Nginx разрывает соединение при долгих запросах (дефолт 60s) - HTTPS-конфиг без
ssl_protocols TLSv1.2 TLSv1.3— поддержка устаревших TLS 1.0/1.1 - Забыть
nginx -tпередnginx -s reload— синтаксическая ошибка в конфиге роняет Nginx