Files
LiveServer-M1/docker-compose.prod.yml
joylessorchid a42ec96965 perf: Redis pub/sub, PgBouncer, optimistic UI for high concurrency
- Add Redis 7 for pub/sub (lobby + chat real-time), rate limiting, caching
- Replace SSE DB polling with Redis pub/sub (lobby: instant approval, chat: instant delivery)
- Add PgBouncer (transaction mode, 500 client → 25 pool connections)
- Chat SSE stream via Redis pub/sub instead of 3s polling
- Optimistic UI in ChatPanel (messages appear before server confirms)
- Redis-based rate limiter (works across multiple app replicas)
- Prisma query optimization (select only needed fields)
- Chat message cache in Redis (10s TTL)
- Docker Compose: add redis, pgbouncer services with healthchecks
- Production: resource limits, 2 app replicas behind Traefik
- Update CLAUDE.md, README.md, .env.example, setup.sh

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-22 14:17:25 +03:00

76 lines
2.3 KiB
YAML

# Продакшен — Traefik + Let's Encrypt
# Запуск: docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
services:
traefik:
image: traefik:v3
command:
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
- "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
- "--certificatesresolvers.letsencrypt.acme.email=${ACME_EMAIL}"
- "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
ports:
- "80:80"
- "443:443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- letsencrypt_data:/letsencrypt
restart: unless-stopped
app:
environment:
NEXT_PUBLIC_APP_URL: https://${DOMAIN}
BETTER_AUTH_URL: https://${DOMAIN}
deploy:
resources:
limits:
memory: 1G
reservations:
memory: 512M
replicas: 2
labels:
- "traefik.enable=true"
- "traefik.http.routers.app.rule=Host(`${DOMAIN}`)"
- "traefik.http.routers.app.entrypoints=websecure"
- "traefik.http.routers.app.tls.certresolver=letsencrypt"
- "traefik.http.services.app.loadbalancer.server.port=3000"
minio:
labels:
- "traefik.enable=true"
- "traefik.http.routers.minio-api.rule=Host(`s3.${DOMAIN}`)"
- "traefik.http.routers.minio-api.entrypoints=websecure"
- "traefik.http.routers.minio-api.tls.certresolver=letsencrypt"
- "traefik.http.routers.minio-api.service=minio-api"
- "traefik.http.services.minio-api.loadbalancer.server.port=9000"
- "traefik.http.routers.minio-console.rule=Host(`minio.${DOMAIN}`)"
- "traefik.http.routers.minio-console.entrypoints=websecure"
- "traefik.http.routers.minio-console.tls.certresolver=letsencrypt"
- "traefik.http.routers.minio-console.service=minio-console"
- "traefik.http.services.minio-console.loadbalancer.server.port=9001"
redis:
deploy:
resources:
limits:
memory: 256M
postgres:
deploy:
resources:
limits:
memory: 1G
ai-agent:
deploy:
resources:
limits:
memory: 2G
volumes:
letsencrypt_data: