Skip to content

Production Hardening

Secrets

All secrets must be set before deploying to production:

  • JWT_SECRET — Minimum 32 characters, generate with openssl rand -base64 48
  • POSTGRES_PASSWORD — Strong password, never the default
  • REDIS_PASSWORD — Required if Redis is exposed beyond localhost

In k8s/config.yaml: update stringData in the slozy-secrets Secret. For Docker: set in .env.

PostgreSQL SSL

Always enable SSL in production:

POSTGRES_SSL_MODE=require

The production docker-compose.prod.yml defaults to POSTGRES_SSL_MODE=require. In K8s, the ConfigMap sets it under POSTGRES_SSL_MODE.

Application Settings

VariableProduction Value
DEV_MODEfalse
GIN_MODErelease
LOG_LEVELinfo
LOG_FORMATjson
ENVIRONMENTproduction

CORS

Restrict origins to your domain(s). Edit CORS_ORIGINS in the ConfigMap or .env:

CORS_ORIGINS=https://app.slozy.net,https://admin.slozy.net

Rate Limiting

Configure in .env.production or environment variables:

RATE_LIMIT_REQUESTS_PER_SECOND=10
RATE_LIMIT_SLO_CREATES_PER_SECOND=5

The middleware (internal/middleware/security.go) implements a token-bucket rate limiter with per-IP tracking, blacklist/whitelist support, and X-RateLimit-* response headers.

Health Checks

Both Docker and K8s deployments use the /health endpoint. It returns service status for cache, notifications, and WebSocket subsystems:

json
{"status":"ok","timestamp":"...","services":{"cache":true,"notifications":true,"websocket":true}}
  • Liveness probe: GET /health, initial delay 10s, period 30s
  • Readiness probe: GET /health, initial delay 5s, period 10s

Metrics are exposed on :9090/metrics when METRICS_ENABLED=true. See prometheus/prometheus.yml for scrape config.