З розвитком мікросервісної архітектури та контейнеризації, розробники часто стикаються з необхідністю налаштування reverse proxy. Nginx є чудовим вибором для цієї ролі, але неправильна конфігурація може призвести до проблем з продуктивністю, безпекою та складнощами в дебагінгу. У цій статті ми розглянемо, як правильно налаштувати Nginx reverse proxy для containerized application, використовуючи Docker та Docker Compose, щоб мінімізувати потенційні проблеми.
Практична реалізація та приклад коду
Ось як виглядає правильне рішення. Припустимо, у нас є два сервіси: веб-сервер (http://web-app:8080) та API (http://api-app:3000), обидва працюють у Docker контейнерах. Ми хочемо, щоб Nginx приймав вхідні запити на порт 80 та перенаправляв їх на відповідні сервіси.
events {
worker_connections 1024;
}
http {
upstream web_app {
server web-app:8080;
}
upstream api_app {
server api-app:3000;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://web_app;
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;
}
location /api/ {
proxy_pass http://api_app$request_uri;
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;
}
}
}
Приклад Docker Compose файлу для простоти:
version: "3.9"
services:
nginx:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
- web-app
- api-app
web-app:
image: your-web-app-image:latest
ports:
- "8080:8080"
api-app:
image: your-api-app-image:latest
ports:
- "3000:3000"
Розбір логіки та підводні камені
- Upstream блоки: Використання upstream блоків робить конфігурацію більш читабельною та дозволяє легко змінювати бекенди без зміни інших частин конфігурації. Зверніть увагу на використання імен контейнерів (web-app, api-app) – це ключове для Docker networking.
- proxy_set_header: Ці заголовки необхідні для передачі інформації про клієнта на бекенд. `Host` – важливий для правильної роботи веб-серверів, `X-Real-IP` – для логування реальної IP-адреси клієнта, `X-Forwarded-For` – для відстеження ланцюжка проксі-серверів, `X-Forwarded-Proto` – для визначення протоколу (http/https).
- Location блоки: Location блоки визначають, які запити перенаправляються на які бекенди. Використання `/api/` для API сервісу дозволяє налаштувати різні правила для різних частин вашого додатку. Зверніть увагу на `$request_uri` в другому location блоці.
- Зв’язування імен контейнерів: В Docker Compose файлі, `depends_on` гарантує, що Nginx запуститься лише після запуску web-app та api-app. Це важливо, щоб уникнути проблем з недоступними сервісами.
- Безпека: Обов’язково налаштуйте SSL/TLS для шифрування трафіку між клієнтом та Nginx. Використовуйте сертифікати Let’s Encrypt для автоматизованого отримання та оновлення сертифікатів.
- Моніторинг: Інтегруйте Nginx з системою моніторингу (Prometheus, Grafana) для відстеження продуктивності та виявлення проблем.
- Автоматизація деплою: Використовуйте CI/CD інструменти (GitLab CI, Jenkins, GitHub Actions) для автоматизації процесу деплою Nginx конфігурацій та оновлення Docker образів. Це забезпечить швидке та надійне розгортання змін.