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:
@@ -25,6 +25,12 @@ type Config struct {
|
||||
// expiry and refresh rotation. Keep it only as long as a viewing session
|
||||
// plausibly lasts — it is a bearer credential for that one file until expiry.
|
||||
ContentTokenTTL time.Duration
|
||||
// ShutdownTimeout bounds how long a graceful shutdown waits for in-flight
|
||||
// requests to finish after a SIGINT/SIGTERM before the process exits. Keep it
|
||||
// in step with the container's stop grace period — docker-compose.yml reads
|
||||
// the same SHUTDOWN_TIMEOUT for `stop_grace_period`, so Docker doesn't SIGKILL
|
||||
// mid-drain. A long upload/stream can still be cut if it outlasts this window.
|
||||
ShutdownTimeout time.Duration
|
||||
// TrustedProxies lists the reverse-proxy hops (CIDRs or IPs) whose
|
||||
// X-Forwarded-For header is trusted. The auth rate limiter keys on the
|
||||
// client IP, so this must match the proxy in front of the app — otherwise
|
||||
@@ -162,6 +168,8 @@ func Load() (*Config, error) {
|
||||
|
||||
ContentTokenTTL: parseDuration("CONTENT_TOKEN_TTL", "6h"),
|
||||
|
||||
ShutdownTimeout: parseDuration("SHUTDOWN_TIMEOUT", "15s"),
|
||||
|
||||
TrustedProxies: parseCSV("TRUSTED_PROXIES", "127.0.0.1/32,::1/128,172.16.0.0/12"),
|
||||
|
||||
AdminUsername: defaultStr("ADMIN_USERNAME", "admin"),
|
||||
|
||||
Reference in New Issue
Block a user