Пошук уроків, статей та іншого контенту
Чому реальні застосунки майже завжди стоять за Nginx, а не приймають трафік напряму — і що саме робить reverse proxy.
Ці два терміни легко переплутати, бо слово «proxy» те саме, а роль — протилежна. Forward proxy стоїть на боці клієнтів і приховує їх від сервера (корпоративний proxy, VPN) — сервер не знає, хто саме за ним звертається. Reverse proxy стоїть на боці сервера й приховує внутрішню інфраструктуру від клієнтів — клієнт звертається до proxy, не знаючи (і не маючи потреби знати), скільки реальних серверів обробляють запит за ним.
Приймає весь вхідний трафік на одному загальнодоступному порту (зазвичай 80/443) і перенаправляє його на внутрішні сервіси, що самі не виставлені назовні напряму.
TLS termination — обробляє HTTPS-шифрування один раз на рівні proxy, а до внутрішніх сервісів трафік може йти вже звичайним HTTP усередині приватної мережі (наприклад, докерівської — стаття «Docker networking»/урок «Networks: як контейнери спілкуються між собою»).
Балансування навантаження — розподіляє запити між кількома однаковими інстансами застосунку, якщо один сервер не витримує все навантаження сам.
Роздає статичні файли (зображення, CSS, JS) напряму, не витрачаючи на це ресурси застосунку — Nginx робить це значно ефективніше за Node.js-процес.
Rate limiting та базовий захист — обмеження кількості запитів з однієї IP-адреси, блокування явно шкідливих запитів ще до того, як вони дійдуть до застосунку.
server {
listen 80;
server_name example.com;
location /api/ {
proxy_pass http://app:3000; # перенаправити на застосунок усередині мережі
proxy_set_header Host $host; # передати оригінальні заголовки далі
proxy_set_header X-Real-IP $remote_addr;
}
location /static/ {
alias /var/www/static/; # статичні файли — напряму від Nginx
expires 30d;
}
}location /api/ пересилає запити застосунку, тоді як /static/ Nginx обслуговує сам, без жодного звернення до застосунку — типовий поділ обов'язків: застосунок відповідає лише за динамічну логіку, Nginx — за все, що можна віддати швидше й дешевше в обхід нього.
У контейнеризованому застосунку Nginx зазвичай — ще один сервіс у docker-compose.yml (курс Docker, уроки «Docker Compose: оркеструвати кілька контейнерів» та «Практичний docker-compose.yml для веб-застосунку»), який приймає зовнішній трафік на порт 80/443 і проксує його до внутрішнього сервісу застосунку за іменем контейнера — контейнери в одній мережі Compose бачать одне одного за назвою сервіса, тож proxy_pass http://app:3000 працює без жодної IP-адреси.
Виставляти порт застосунку назовні напряму «для простоти», а Nginx додавати пізніше «якщо знадобиться» — в результаті доводиться змінювати всю мережеву конфігурацію заднім числом замість того, щоб із самого початку проєктувати з одним публічним входом.
Забувати передавати заголовок X-Real-IP чи X-Forwarded-For — без нього застосунок за reverse proxy бачить IP-адресу самого Nginx як адресу всіх клієнтів, що ламає rate limiting, геолокацію та логування на рівні застосунку.
Тримати TLS-сертифікати лише в конфігурації Nginx, забуваючи про їхнє автоматичне оновлення (наприклад, через Let's Encrypt/certbot) — прострочений сертифікат ламає доступ до всього застосунку одразу.
Reverse proxy — проміжний шар між зовнішнім світом і внутрішньою інфраструктурою застосунку: він приймає весь вхідний трафік, обробляє TLS, роздає статику, балансує навантаження між кількома інстансами й приховує реальну структуру бекенду від клієнтів. Nginx — найпоширеніша реалізація цієї ролі, і в контейнеризованих застосунках зазвичай стає ще одним сервісом у docker-compose.yml поруч із самим застосунком і базою даних.