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 'Mise à jour CodexPi
CodexPi se met à jour

Reconnexion automatique dans quelques secondes…

'; } 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 ~ ^/(?(?!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; } } }