Обратный прокси: несколько приложений на одном адресе
Как раздать один публичный адрес VDS между несколькими приложениями по доменам и путям, правильно передать заголовки и не сломать WebSocket.
Обновлено 23 августа 2026 г.
У машины один публичный адрес IPv4, а приложений на ней обычно несколько. Обратный прокси принимает все запросы на 80 и 443 порты и раздаёт их внутренним сервисам по имени домена или пути. Заодно на нём живёт единственный сертификат и общие логи.
Схема
Каждое приложение слушает свой локальный порт и только 127.0.0.1:
- сайт-фронтенд —
127.0.0.1:3000; - API —
127.0.0.1:8000; - панель мониторинга —
127.0.0.1:9090.
Наружу торчит только Nginx. Проверить, что приложение не выставлено напрямую:
ss -tulpn | grep LISTEN
Строки вида 0.0.0.0:3000 означают, что сервис доступен из интернета в обход прокси и без шифрования.
По доменам
server {
listen 80;
server_name app.example.ru;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
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;
}
}
server {
listen 80;
server_name api.example.ru;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
Без X-Forwarded-For приложение будет видеть все запросы как пришедшие с 127.0.0.1, и любые ограничения по IP перестанут работать.
По путям
location /api/ {
proxy_pass http://127.0.0.1:8000/;
}
Здесь важна косая черта в конце proxy_pass: с ней префикс /api отрезается и приложение получает /users, без неё — /api/users. Половина «непонятных 404» на прокси растёт именно отсюда.
WebSocket и долгие ответы
location /ws/ {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600s;
}
Без пары Upgrade/Connection соединение рвётся сразу после рукопожатия, а без увеличенного таймаута — через минуту тишины.
Частые ошибки
| Симптом | Причина |
|---|---|
502 Bad Gateway | Приложение не запущено или слушает другой порт |
504 Gateway Time-out | Приложение отвечает дольше proxy_read_timeout |
| Бесконечный редирект | Приложение не знает про HTTPS — передайте X-Forwarded-Proto |
| Ломается загрузка файлов | Мал client_max_body_size, по умолчанию 1 МБ |
| В логах приложения один и тот же IP | Не передан X-Forwarded-For |
Дальше: несколько сайтов, сертификат, Caddy с автоматическим HTTPS.
Один сертификат на прокси покрывает все приложения за ним. Внутренние соединения по
127.0.0.1шифровать не нужно — они не покидают машину.