Перейти к содержанию

nginx на ragserver — reverse proxy для Open WebUI

Автоматически составлено агентом 06.08.2026 из rag-sync.md, openwebui.md, 00_INDEX.md, nginx-vps-configs.md (как эталон). Требует ревью: проверить /etc/nginx/sites-enabled/ на ragserver, актуальные server_name.

Быстрая справка

Параметр Значение
Сервер ragserver 192.168.1.200 (Ubuntu 22.04.5)
Конфиг /etc/nginx/sites-enabled/rag.alatyr-service.ru
Upstream http://127.0.0.1:3000 (rag-openwebui docker)
Доступ Только через LAN + VPN AmneziaWG
TLS Let's Encrypt через certbot

Роль

nginx на ragserver проксирует HTTPS-запросы к Open WebUI, работающему в docker-контейнере на порту 3000.

Внешний доступ невозможен из интернета — ragserver в LAN за домашним роутером. Доступ только: - Из LAN 192.168.1.0/24 (домашняя сеть) - Через VPN AmneziaWG (10.8.1.0/24)

Список активных сайтов

Site Server name Upstream Роль
rag.alatyr-service.ru rag.alatyr-service.ru 127.0.0.1:3000 Open WebUI

Конфиг rag.alatyr-service.ru (шаблон)

# /etc/nginx/sites-enabled/rag.alatyr-service.ru

server {
    listen 80;
    server_name rag.alatyr-service.ru;

    # Redirect на HTTPS
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name rag.alatyr-service.ru;

    # === TLS ===
    ssl_certificate     /etc/letsencrypt/live/rag.alatyr-service.ru/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/rag.alatyr-service.ru/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;

    # === Логи ===
    access_log /var/log/nginx/rag-access.log;
    error_log  /var/log/nginx/rag-error.log warn;

    # === Body size (для загрузки больших PDF в KB) ===
    client_max_body_size 100M;
    client_body_timeout 300s;

    # === Proxy на Open WebUI ===
    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_http_version 1.1;

        # WebSocket upgrade (важно для стриминга ответов LLM!)
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # Стандартные proxy headers
        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_set_header X-Forwarded-Host  $host;

        # Таймауты (стриминг может быть долгим)
        proxy_read_timeout  300s;
        proxy_send_timeout  300s;
        proxy_connect_timeout 60s;

        # Отключить буферизацию для стриминга
        proxy_buffering off;
        proxy_cache off;
    }
}

Ключевые моменты

WebSocket upgrade

Критично для стриминга ответов LLM — Open WebUI использует SSE (Server-Sent Events) и WebSocket. Без Upgrade / Connection заголовков стриминг сломается — пользователь увидит ответ только после полного завершения генерации.

client_max_body_size

По умолчанию nginx ставит 1MB. Для RAG нужно 100M — юзер может загружать большие PDF в knowledge collections через UI.

Отключение буферизации

proxy_buffering off + proxy_cache off — иначе nginx буферизирует стриминг и клиент не видит промежуточных токенов.

Таймауты

proxy_read_timeout 300s — генерация 7B LLM на CPU может занять 2-3 минуты. Без увеличения таймаута nginx закроет соединение раньше времени.

Security headers (✅ добавлены 07.08.2026 — задача 21)

В /etc/nginx/sites-available/rag.alatyr-service.ru, в HTTPS server-блоке сразу после ssl_dhparam:

# Security headers (задача 21, 07.08.2026)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "same-origin" always;
add_header X-Robots-Tag "noindex, nofollow" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=(), payment=(), usb=(), magnetometer=(), gyroscope=(), accelerometer=()" always;

Почему нет CSP: OpenWebUI активно использует inline scripts, WebSocket, blob URLs. Строгий CSP сломает интерфейс. При желании включить — сначала Content-Security-Policy-Report-Only, мониторить логи, потом включать в blocking.

Проверка:

curl -sI https://rag.alatyr-service.ru | grep -iE "strict|frame|content-type|referrer|robots|permissions"

TLS-сертификат

Let's Encrypt через certbot:

sudo certbot certonly --nginx -d rag.alatyr-service.ru

⚠ Осторожно: certbot должен пройти HTTP challenge на портах 80 → потребуется временно открыть проброс на роутере или использовать DNS-01 challenge через Reg.ru API.

Автообновление через systemd timer certbot.timer (см. certbot.md).

Команды на каждый день

# Проверить синтаксис
sudo nginx -t

# Reload без прерывания соединений
sudo systemctl reload nginx

# Смотреть логи в реальном времени
sudo tail -f /var/log/nginx/rag-access.log
sudo tail -f /var/log/nginx/rag-error.log

# Проверить что слушает
sudo ss -tlnp | grep nginx

# Обновить сертификат вручную
sudo certbot renew --dry-run
sudo certbot renew --force-renewal -d rag.alatyr-service.ru

DNS

Домен rag.alatyr-service.ru должен резолвиться в: - Извне LAN — публичный IP роутера (176.99.153.164) → проброс порта 443 - Но проброса нет и не будет — доступ только по VPN - Изнутри LAN — 192.168.1.200 (через локальный резолвер / hosts) - Через AmneziaWG — тоже 192.168.1.200 (VPN даёт доступ в LAN)

Проверить резолв:

dig rag.alatyr-service.ru
host rag.alatyr-service.ru

Если резолвится в публичный IP роутера — извне никогда не откроется (нет проброса).

Firewall

На ragserver:

# UFW (если включён)
sudo ufw allow 443/tcp
sudo ufw allow 80/tcp  # только для certbot challenge

# Проверить открыто ли
sudo ss -tlnp | grep -E ":80|:443"

Известные проблемы

  • DNS-запись rag.alatyr-service.ru — уточнить куда резолвится извне (может пропадать при смене IP роутера)
  • HTTP challenge через certbot — требует пробрасывать 80 порт на роутере, что не всегда удобно

Связанные файлы