feat(backend): graceful shutdown on SIGTERM/SIGINT

Run the HTTP server in a goroutine and, on SIGINT/SIGTERM, call
srv.Shutdown so it stops accepting connections and lets in-flight
requests finish before exiting (ErrServerClosed is a clean exit). This
stops uploads/streams being cut when the container is stopped or
recreated on deploy.

The drain deadline is configurable via SHUTDOWN_TIMEOUT (default 15s).
docker-compose.yml feeds the same variable into the app's
stop_grace_period, so Docker won't SIGKILL mid-drain and the two values
can't drift.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-03 08:12:10 +03:00
parent bf7fa49a16
commit a6a46af12e
4 changed files with 55 additions and 3 deletions
+9
View File
@@ -62,6 +62,15 @@ JWT_REFRESH_TTL=720h
# long as a viewing session lasts.
CONTENT_TOKEN_TTL=6h
# How long a graceful shutdown waits for in-flight requests to finish after the
# app receives SIGTERM/SIGINT (e.g. on `docker compose up --build`, which
# recreates the container). This SAME value is fed to the container's
# `stop_grace_period` in docker-compose.yml, so Docker won't SIGKILL the app
# mid-drain — set it in one place here and both stay in sync. A single upload or
# video stream that outlasts this window is still cut; raise it if you routinely
# move very large files. Accepts Go/Compose durations (s, m, h).
SHUTDOWN_TIMEOUT=15s
# Reverse-proxy hops (comma-separated CIDRs/IPs) whose X-Forwarded-For is trusted,
# so the auth rate limiter sees real client IPs instead of the proxy's. The default
# covers loopback and the Docker bridge ranges a host nginx reaches the container