diff --git a/.env.example b/.env.example index 6723d69..54597f8 100644 --- a/.env.example +++ b/.env.example @@ -56,6 +56,10 @@ RABBITMQ_MGMT_PORT=15672 MINIO_PUBLIC_ENDPOINT=http://localhost:9000 MINIO_API_CORS_ALLOW_ORIGIN=* +# Redis for auth rate-limit (backlog) — 5/min/IP on /auth/login +REDIS_URL=redis://redis:6379/0 +REDIS_PORT=6379 + # App ports GATEWAY_PORT=8080 AUTH_PORT=8001 diff --git a/deploy/docker-compose.yml b/deploy/docker-compose.yml index e73dba0..8a81b95 100644 --- a/deploy/docker-compose.yml +++ b/deploy/docker-compose.yml @@ -99,6 +99,17 @@ services: MINIO_ROOT_PASSWORD: ${MINIO_SECRET_KEY:-minioadmin} VIDEO_STORAGE_BUCKET: ${VIDEO_STORAGE_BUCKET:-videos} + redis: + image: redis:7-alpine + ports: + - "${REDIS_PORT:-6379}:6379" + volumes: + - redisdata:/data + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 10s + retries: 5 + rabbitmq: image: rabbitmq:3-management-alpine environment: @@ -138,6 +149,7 @@ services: build: ../services/auth environment: DATABASE_URL: postgres://flowix:flowix@postgres:5432/flowix?sslmode=disable + REDIS_URL: redis://redis:6379/0 # Phase 15: set PGBOUNCER_ENABLED=true to route via pgbouncer:5432 (pooled) DATABASE_POOL_SIZE: ${DATABASE_POOL_SIZE:-5} DATABASE_MAX_OVERFLOW: ${DATABASE_MAX_OVERFLOW:-10} @@ -377,6 +389,7 @@ volumes: pgdata: miniodata: rabbitdata: + redisdata: promdata: grafanadata: lokidata: diff --git a/frontend/src/lib/api.ts b/frontend/src/lib/api.ts index 779a80a..bd27d92 100644 --- a/frontend/src/lib/api.ts +++ b/frontend/src/lib/api.ts @@ -155,6 +155,78 @@ export async function completeVideo(videoId: string): Promise