# 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. # /hooks is where the flows' webhooks and served sockets live, next to the API # on the backend. One regex takes both, and a regex outranks `location /`, # which would otherwise answer /hooks with the SPA. location ~ ^/(api|hooks) { # 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; # The container name, which only the dev API carries. The test stack's # backend answers to the service name `backend` on the shared proxy # network too. set $backend_upstream http://fluksio-api:8000; proxy_pass $backend_upstream$request_uri; proxy_http_version 1.1; proxy_set_header Host $host; # Replaced, not appended to: whatever the client sent would otherwise sit # in front of the one hop the backend believes, and anything reading the # header naively would take it for the caller. proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Forwarded-Proto $scheme; # The flow websocket (/api/v1/flows/ws) and a served socket upgrade through # here; passing the client's own Connection header covers both 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; # nginx's 1 MB default would 413 any larger artifact upload; the backend # enforces MAX_ARTIFACT_BYTES itself, so the body streams through as is. client_max_body_size 0; proxy_request_buffering off; } # Unchanged from the stub: the API docs stay off the frontend's origin. location /docs { return 404; } location /redoc { return 404; }