Files

412 lines
16 KiB
Nginx Configuration File
Raw Permalink Normal View History

2026-11-14 20:23:59 +01:00
worker_processes auto;
pid /tmp/nginx.pid;
events { worker_connections 1024; }
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /dev/stdout;
error_log /dev/stderr warn;
client_body_temp_path /tmp/client_body;
proxy_temp_path /tmp/proxy;
fastcgi_temp_path /tmp/fastcgi;
uwsgi_temp_path /tmp/uwsgi;
scgi_temp_path /tmp/scgi;
sendfile on;
server_tokens off;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
map $http_x_forwarded_proto $forwarded_proto {
default $http_x_forwarded_proto;
'' $scheme;
}
include /tmp/codexpi-upstreams.conf;
upstream browser_gui { server browser:7900; }
server {
listen 8080;
server_name _;
client_max_body_size 11m;
location @codexpi_updating {
default_type text/html;
add_header Cache-Control "no-store" always;
add_header Retry-After "3" always;
return 200 '<!doctype html><html lang="fr"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"><meta http-equiv="refresh" content="3"><title>Mise à jour CodexPi</title><style>body{margin:0;min-height:100vh;display:grid;place-items:center;background:#090c0f;color:#e9eee9;font:16px system-ui}main{text-align:center;padding:28px}b{display:block;margin-bottom:10px;font-size:22px;color:#8ed69e}p{color:#9ca59f}</style></head><body><main><b>CodexPi se met à jour</b><p>Reconnexion automatique dans quelques secondes…</p></main></body></html>';
}
location = /proxy-health {
access_log off;
add_header Content-Type text/plain;
return 200 'ok';
}
location = /api/bootstrap {
proxy_pass http://django_ui;
proxy_intercept_errors on;
error_page 502 503 504 = @codexpi_updating;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $forwarded_proto;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
location = /version.json {
proxy_pass http://fastapi_api/version.json;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
add_header Cache-Control "no-store" always;
}
location = /browser-auth {
internal;
proxy_pass http://django_ui/api/auth/me;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header Cookie $http_cookie;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $forwarded_proto;
}
location ^~ /browser/ {
auth_request /browser-auth;
proxy_pass http://browser_gui/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $forwarded_proto;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_buffering off;
proxy_read_timeout 24h;
proxy_send_timeout 24h;
}
location ^~ /api/auth/ {
proxy_pass http://django_ui;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $forwarded_proto;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
location ^~ /ws/ {
proxy_pass http://fastapi_api;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $forwarded_proto;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 24h;
proxy_send_timeout 24h;
}
location ^~ /api/conversations/ {
client_max_body_size 101m;
proxy_request_buffering off;
proxy_buffering off;
proxy_pass http://fastapi_api;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $forwarded_proto;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 180s;
}
location ^~ /api/ {
proxy_pass http://fastapi_api;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $forwarded_proto;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 180s;
}
location = /loutre-app-store/share.js {
proxy_pass http://fastapi_api;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $forwarded_proto;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
location = /loutre-app-store/pwa-status.js {
proxy_pass http://fastapi_api;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $forwarded_proto;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
location ^~ /loutre-app-store/known-icons/ {
proxy_pass http://fastapi_api;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $forwarded_proto;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
location ^~ /loutre-app-store/app-icons/ {
proxy_pass http://fastapi_api;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $forwarded_proto;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
location = /autonomous-dev-studio/app.js {
proxy_pass http://fastapi_api;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $forwarded_proto;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
location = /codex-commander/app.js {
proxy_pass http://fastapi_api;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $forwarded_proto;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
# LoutreOS runs as an isolated application container on the private
# CodexPi network. Keep the public surface under its explicit app prefix.
location = /loutre-os { return 308 /loutre-os/; }
location ^~ /loutre-os/ {
proxy_pass http://loutreos-preview:8000/;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header Cookie $http_cookie;
proxy_set_header X-Forwarded-Proto $forwarded_proto;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 15s;
add_header Cache-Control "no-store" always;
add_header X-Content-Type-Options nosniff always;
add_header X-Frame-Options DENY always;
add_header Referrer-Policy no-referrer always;
add_header X-Robots-Tag "noindex, nofollow" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; connect-src 'self'; img-src 'self' data:; object-src 'none'; frame-ancestors 'none'; base-uri 'self'" always;
}
# LoutreFinance validates the existing CodexPi session server-side and
# serves its portal build under this fixed prefix.
location = /loutre-finance { return 308 /loutre-finance/; }
location ^~ /loutre-finance/ {
proxy_pass http://loutre-finance:8000;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header Cookie $http_cookie;
proxy_set_header X-Forwarded-Proto $forwarded_proto;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 30s;
add_header Cache-Control "no-store" always;
add_header X-Robots-Tag "noindex, nofollow" always;
}
# Smart Inventory uses the central CodexPi session and stores data in an
# isolated persistent volume. Strip only the public application prefix;
# Uvicorn advertises it through ASGI root_path for generated URLs.
location = /smart-inventory { return 308 /smart-inventory/; }
location ^~ /smart-inventory/ {
proxy_pass http://smart-inventory:8000/;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header Cookie $http_cookie;
proxy_set_header X-Forwarded-Proto $forwarded_proto;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 30s;
add_header Cache-Control "no-store" always;
add_header X-Robots-Tag "noindex, nofollow" always;
}
# AutoCare consumes the full /auto-care prefix and validates the central
# CodexPi identity for every private request.
location = /auto-care { return 308 /auto-care/; }
location ^~ /auto-care/ {
proxy_pass http://auto-care:8000;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header Cookie $http_cookie;
proxy_set_header X-Forwarded-Proto $forwarded_proto;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_read_timeout 30s;
add_header Cache-Control "no-store" always;
add_header X-Robots-Tag "noindex, nofollow" always;
}
# PrintPilot keeps its application prefix and delegates identity and CSRF
# decisions to the existing CodexPi Django service.
location = /print-pilot { return 308 /print-pilot/; }
location ^~ /print-pilot/ {
proxy_pass http://print-pilot:8000;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header Cookie $http_cookie;
proxy_set_header X-Forwarded-Proto $forwarded_proto;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-User "";
proxy_set_header X-Role "";
proxy_read_timeout 30s;
client_max_body_size 21m;
add_header Cache-Control "no-store" always;
add_header X-Robots-Tag "noindex, nofollow" always;
}
# LoutreHome keeps its fixed prefix and performs server-side CodexPi
# identity checks. No device-control capability is added by this route.
location = /loutre-home { return 308 /loutre-home/; }
location ^~ /loutre-home/ {
proxy_pass http://loutre-home:8017;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header Cookie $http_cookie;
proxy_set_header X-Forwarded-Proto $forwarded_proto;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-User "";
proxy_set_header X-Role "";
proxy_read_timeout 30s;
add_header Cache-Control "no-store" always;
add_header X-Robots-Tag "noindex, nofollow" always;
}
# NetworkGuardian is deployed in an explicitly labelled demonstration
# mode until a private CIDR is approved. Identity still comes from CodexPi.
location = /network-guardian { return 308 /network-guardian/; }
location ^~ /network-guardian/ {
proxy_pass http://network-guardian:8897/;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header Cookie $http_cookie;
proxy_set_header X-Forwarded-Proto $forwarded_proto;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-User "";
proxy_set_header X-Role "";
proxy_read_timeout 30s;
add_header Cache-Control "no-store" always;
add_header X-Robots-Tag "noindex, nofollow" always;
}
# Reverse Proxy Manager preserves its prefix and remains disconnected from
# QNAP until an explicit read-only connector is configured and verified.
location = /reverse-proxy-manager { return 308 /reverse-proxy-manager/; }
location ^~ /reverse-proxy-manager/ {
proxy_pass http://reverse-proxy-manager:8000;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header Cookie $http_cookie;
proxy_set_header X-Forwarded-Proto $forwarded_proto;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-User "";
proxy_set_header X-Role "";
proxy_hide_header Set-Cookie;
proxy_read_timeout 30s;
client_max_body_size 2m;
add_header Cache-Control "no-store" always;
add_header X-Robots-Tag "noindex, nofollow" always;
}
# LoutreBrain keeps its application prefix and validates every request
# against the existing CodexPi application grant.
location = /loutre-brain { return 308 /loutre-brain/; }
location ^~ /loutre-brain/ {
proxy_pass http://loutre-brain:8000;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header Cookie $http_cookie;
proxy_set_header X-Forwarded-Proto $forwarded_proto;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-User "";
proxy_set_header X-Role "";
proxy_read_timeout 60s;
client_max_body_size 21m;
add_header Cache-Control "no-store" always;
add_header X-Robots-Tag "noindex, nofollow" always;
}
# Knowledge Graph is served by its prefix-confined ASGI entry point.
location = /knowledge-graph { return 308 /knowledge-graph/; }
location ^~ /knowledge-graph/ {
proxy_pass http://knowledge-graph:8017;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header Cookie $http_cookie;
proxy_set_header X-Forwarded-Proto $forwarded_proto;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-User "";
proxy_set_header X-Role "";
proxy_read_timeout 30s;
client_max_body_size 10m;
add_header Cache-Control "no-store" always;
add_header X-Robots-Tag "noindex, nofollow" always;
}
# TripOrganizer owns this exact prefix and uses CodexPi for identity.
location = /trip-organizer { return 308 /trip-organizer/; }
location ^~ /trip-organizer/ {
proxy_pass http://trip-organizer:8000;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header Cookie $http_cookie;
proxy_set_header X-Forwarded-Proto $forwarded_proto;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-User "";
proxy_set_header X-Role "";
proxy_read_timeout 30s;
client_max_body_size 21m;
add_header Cache-Control "no-store" always;
add_header X-Robots-Tag "noindex, nofollow" always;
}
# Stable PWA bookmark endpoints such as /loutre-os/. Reserved CodexPi
# namespaces remain handled by their dedicated locations above.
location ~ ^/(?<loutre_app_slug>(?!api(?:/|$)|ws(?:/|$)|browser(?:/|$)|icons(?:/|$)|static(?:/|$)|admin(?:/|$)|media(?:/|$))[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)/(?:manifest\.webmanifest|icon-(?:192|512)\.png|apple-touch-icon\.png)?$ {
proxy_pass http://fastapi_api;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $forwarded_proto;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
location / {
proxy_pass http://django_ui;
proxy_intercept_errors on;
error_page 502 503 504 = @codexpi_updating;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto $forwarded_proto;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}
}
}