Files
2026-06-07 23:40:50 +03:00

211 lines
11 KiB
Nginx Configuration File

events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
# ── DNS resolver for dynamic upstream hostname resolution ─────────────────────
# Docker's embedded DNS server (allows upstream hostnames to be re-resolved
# when containers are recreated with new IPs, avoiding stale cache issues).
resolver 127.0.0.11:53 valid=10s;
resolver_timeout 5s;
# ── Upstreams ──────────────────────────────────────────────────────────────
upstream portal_upstream { server portal:5001; }
upstream digiserver_upstream { server digiserver-app:5000; }
upstream itassets_upstream { server itassets-app:5000; }
upstream srvmonitor_upstream { server srvmonitor-app:5000; }
upstream nv_backend_upstream { server networkview-backend:3001; }
upstream nv_frontend_upstream { server networkview-frontend:80; }
# ── Rate limiting ──────────────────────────────────────────────────────────
limit_req_zone $binary_remote_addr zone=login:10m rate=10r/m;
server {
listen 80;
server_name _;
# ── Internal: portal JWT verification (used by auth_request) ──────────
location = /portal-verify {
internal;
proxy_pass http://portal_upstream/api/verify-token;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header Cookie $http_cookie;
proxy_set_header X-Original-URI $request_uri;
proxy_set_header X-Real-IP $remote_addr;
}
# ── Health check (unauthenticated, used by Docker healthcheck) ─────────
location = /health {
proxy_pass http://portal_upstream/health;
proxy_set_header Host $host;
}
# ── Portal — main dashboard & auth (no auth_request, it IS the auth) ──
location / {
limit_req zone=login burst=20 nodelay;
proxy_pass http://portal_upstream;
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_read_timeout 60s;
}
# ── DigiServer — Player device API (no portal auth) ──────────────────
# Players use their own Bearer token auth; portal JWT is not involved.
# This block MUST be declared before the broader /digiserver/ block.
location /digiserver/api/ {
proxy_pass http://digiserver_upstream/api/;
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-Script-Name /digiserver;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# player-edit-media endpoint accepts binary uploads from devices
client_max_body_size 256M;
proxy_connect_timeout 300s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
}
# ── DigiServer — Static media downloads (no portal auth) ───────────────
# Content URLs built by DigiServer include this path; players must be
# able to fetch media files without a portal session cookie.
location /digiserver/static/uploads/ {
proxy_pass http://digiserver_upstream/static/uploads/;
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-Script-Name /digiserver;
expires 60d;
add_header Cache-Control "public";
}
# ── DigiServer v2 — /digiserver/ ──────────────────────────────────────
location /digiserver/ {
auth_request /portal-verify;
auth_request_set $auth_user_id $upstream_http_x_auth_user_id;
auth_request_set $auth_username $upstream_http_x_auth_username;
auth_request_set $auth_role $upstream_http_x_auth_role;
proxy_pass http://digiserver_upstream/;
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-Script-Name /digiserver;
proxy_set_header X-Auth-User-Id $auth_user_id;
proxy_set_header X-Auth-Username $auth_username;
proxy_set_header X-Auth-Role $auth_role;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
proxy_connect_timeout 300s;
# Large content uploads by admins (images, videos, presentations)
client_max_body_size 2048M;
# WebSocket support (for any live-reload / realtime features)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
# ── IT Asset Management — /itassets/ ──────────────────────────────────
location /itassets/ {
auth_request /portal-verify;
auth_request_set $auth_user_id $upstream_http_x_auth_user_id;
auth_request_set $auth_username $upstream_http_x_auth_username;
auth_request_set $auth_role $upstream_http_x_auth_role;
proxy_pass http://itassets_upstream/;
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-Script-Name /itassets;
proxy_set_header X-Auth-User-Id $auth_user_id;
proxy_set_header X-Auth-Username $auth_username;
proxy_set_header X-Auth-Role $auth_role;
proxy_read_timeout 120s;
# Allow larger uploads (for asset documents)
client_max_body_size 50M;
}
# ── Server Monitor — /srvmonitor/ ─────────────────────────────────────
location /srvmonitor/ {
auth_request /portal-verify;
auth_request_set $auth_user_id $upstream_http_x_auth_user_id;
auth_request_set $auth_username $upstream_http_x_auth_username;
auth_request_set $auth_role $upstream_http_x_auth_role;
proxy_pass http://srvmonitor_upstream/;
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-Script-Name /srvmonitor;
proxy_set_header X-Auth-User-Id $auth_user_id;
proxy_set_header X-Auth-Username $auth_username;
proxy_set_header X-Auth-Role $auth_role;
# Ansible playbook runs can take a while to stream output
proxy_read_timeout 300s;
client_max_body_size 50M;
}
# ── NetworkView API — /networkview/api/ ────────────────────────────────
# Must be declared BEFORE the broader /networkview/ location
location /networkview/api/ {
auth_request /portal-verify;
auth_request_set $auth_user_id $upstream_http_x_auth_user_id;
auth_request_set $auth_username $upstream_http_x_auth_username;
proxy_pass http://nv_backend_upstream/api/;
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;
# NetworkView backend already reads these headers for actor tracking
proxy_set_header X-User-Id $auth_user_id;
proxy_set_header X-Username $auth_username;
}
# ── NetworkView Frontend SPA — /networkview/ ───────────────────────────
location /networkview/ {
auth_request /portal-verify;
proxy_pass http://nv_frontend_upstream/;
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;
}
# ── Auth failure handlers ──────────────────────────────────────────────
# 401: not authenticated → redirect to portal login
error_page 401 = @login_redirect;
location @login_redirect {
return 302 /login?next=$request_uri;
}
# 403: authenticated but no access to this app → portal access denied
error_page 403 = @access_denied;
location @access_denied {
return 302 /access-denied;
}
}
}