# Serves the API from the same origin as the SPA, replacing the 404 stub the # image ships. Traefik routes on the Host header, which a bare IP never # matches, so this is what makes http://: a complete app: the # client asks for /api/v1/... on whatever origin served it, and never needs a # resolvable api.${DOMAIN} or a CORS allowance. location /api { # Docker's embedded DNS, re-resolved: nginx otherwise pins the backend's # address at startup and 502s for good once that container is recreated. resolver 127.0.0.11 valid=10s ipv6=off; set $backend_upstream http://backend:8000; proxy_pass $backend_upstream$request_uri; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; # The flow websocket (/api/v1/flows/ws) upgrades through here; passing the # client's own Connection header covers both it and ordinary requests. proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $http_connection; # A live socket outlives the 60s default by design. proxy_read_timeout 1d; } # Unchanged from the stub: the API docs stay off the frontend's origin. location /docs { return 404; } location /redoc { return 404; }