| # ============================================================== |
| # OPTIM AI BRE Engine — Nginx Reverse Proxy Configuration |
| # Routes: / → Frontend (Next.js) | /api/ → Backend (.NET) |
| # Port 80 → HTTP | Port 443 → HTTPS (SSL-ready) |
| # ============================================================== |
|
|
| worker_processes auto; |
| error_log /var/log/nginx/error.log warn; |
| pid /var/run/nginx.pid; |
|
|
| events { |
| worker_connections 4096; |
| use epoll; |
| multi_accept on; |
| } |
|
|
| http { |
| include /etc/nginx/mime.types; |
| default_type application/octet-stream; |
|
|
| # |
| log_format main '$remote_addr - $remote_user [$time_local] ' |
| '"$request" $status $body_bytes_sent ' |
| '"$http_referer" "$http_user_agent" ' |
| 'rt=$request_time uct=$upstream_connect_time ' |
| 'uht=$upstream_header_time urt=$upstream_response_time'; |
|
|
| access_log /var/log/nginx/access.log main; |
|
|
| # |
| sendfile on; |
| tcp_nopush on; |
| tcp_nodelay on; |
| keepalive_timeout 75s; |
| types_hash_max_size 2048; |
| client_max_body_size 50M; |
|
|
| # |
| gzip on; |
| gzip_vary on; |
| gzip_proxied any; |
| gzip_comp_level 6; |
| gzip_types |
| text/plain text/css text/xml text/javascript |
| application/json application/javascript application/xml |
| application/rss+xml font/truetype font/opentype |
| application/vnd.ms-fontobject image/svg+xml; |
|
|
| # |
| add_header X-Frame-Options "SAMEORIGIN" always; |
| add_header X-XSS-Protection "1; mode=block" always; |
| add_header X-Content-Type-Options "nosniff" always; |
| add_header Referrer-Policy "no-referrer-when-downgrade" always; |
| add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always; |
| server_tokens off; |
|
|
| # |
| limit_req_zone $binary_remote_addr zone=api_limit:10m rate=60r/m; |
| limit_req_zone $binary_remote_addr zone=auth_limit:10m rate=10r/m; |
|
|
| # |
| upstream backend { |
| server bre-backend:8080; |
| keepalive 32; |
| } |
|
|
| upstream frontend { |
| server bre-frontend:3000; |
| keepalive 16; |
| } |
|
|
| # ============================================================== |
| # HTTP SERVER (Port 80) |
| # If SSL is configured, this redirects to HTTPS. |
| # Without SSL, this serves the full application on port 80. |
| # ============================================================== |
| server { |
| listen 80; |
| server_name _; |
|
|
| # Uncomment the next 2 lines to force HTTPS redirect (requires SSL setup): |
| # return 301 https://$host$request_uri; |
| |
| |
| location /nginx-health { |
| access_log off; |
| return 200 "healthy\n"; |
| add_header Content-Type text/plain; |
| } |
| |
| |
| location /api/ { |
| limit_req zone=api_limit burst=30 nodelay; |
| |
| proxy_pass http://backend; |
| proxy_http_version 1.1; |
| proxy_set_header Connection ""; |
| 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_connect_timeout 10s; |
| proxy_send_timeout 60s; |
| proxy_read_timeout 60s; |
| |
| proxy_buffer_size 16k; |
| proxy_buffers 8 32k; |
| proxy_busy_buffers_size 64k; |
| } |
| |
| |
| location /api/v1/auth/ { |
| limit_req zone=auth_limit burst=5 nodelay; |
| |
| proxy_pass http://backend/api/v1/auth/; |
| proxy_http_version 1.1; |
| proxy_set_header Connection ""; |
| 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 /swagger { |
| proxy_pass http://backend/swagger; |
| 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; |
| } |
| |
| |
| location /health { |
| proxy_pass http://backend/health; |
| proxy_http_version 1.1; |
| proxy_set_header Host $host; |
| access_log off; |
| } |
| |
| |
| location /_next/static/ { |
| proxy_pass http://frontend/_next/static/; |
| proxy_http_version 1.1; |
| proxy_set_header Connection ""; |
| |
| |
| expires 1y; |
| add_header Cache-Control "public, immutable"; |
| access_log off; |
| } |
| |
| |
| location / { |
| proxy_pass http://frontend; |
| proxy_http_version 1.1; |
| proxy_set_header Upgrade $http_upgrade; |
| proxy_set_header Connection "upgrade"; |
| 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_connect_timeout 10s; |
| proxy_send_timeout 30s; |
| proxy_read_timeout 30s; |
| } |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| } |
| |