#!/bin/sh set -e echo "Applying database migrations..." alembic upgrade head echo "Starting Siftlode API..." # --timeout-keep-alive 75: keep idle upstream connections alive longer than the reverse # proxy's idle-reuse window. uvicorn's default (5s) is shorter than Caddy's pooled-keepalive # timeout, so Caddy would reuse a connection uvicorn had just closed -> broken pipe / reset # on the next request -> 502. Non-idempotent POSTs (the player's progress/state writes, # fired every 5s) can't be auto-retried by the proxy, so those 502s reached the user. # # SECURITY: do NOT add --proxy-headers / --forwarded-allow-ips here. ratelimit.client_key trusts # X-Forwarded-For only when the TRUE socket peer is a configured proxy (TRUSTED_PROXY_IPS); those # flags would make uvicorn overwrite request.client from the forgeable XFF, defeating that check and # reopening the rate-limit bypass (SA3). # # No --log-config: app/logs.py configures logging for every Siftlode process (api, worker, download # child, alembic) in one place, and it silences uvicorn's access log in favour of our own # `http.request` line (route template, no query string, request id). exec uvicorn app.main:app --host 0.0.0.0 --port 8000 --timeout-keep-alive 75