* Initial plan * feat: enable connection pool monitoring and configure Prisma connection limits - Start connection pool monitoring automatically in server.ts - Add connection pool configuration logging to db.ts - Update .env.example with detailed connection pool parameters - Configure connection_limit=5 in Docker Compose for PgBouncer - Add DATABASE_URL_DIRECT to production docker-compose - Create comprehensive unit tests for connection pool monitoring Co-authored-by: PatrickFanella <61631520+PatrickFanella@users.noreply.github.com> * docs: add connection pooling quick start and implementation guides - Add CONNECTION_POOLING_QUICKSTART.md with practical commands - Add CONNECTION_POOLING_IMPLEMENTATION.md with implementation summary - Include troubleshooting tips and monitoring commands - Document performance tuning strategies Co-authored-by: PatrickFanella <61631520+PatrickFanella@users.noreply.github.com> * fix: address code review comments - Fix username consistency in .env.example (use 'spywatcher' instead of 'postgres') - Add clarifying comment for dynamic import pattern in server.ts - Both changes improve code clarity and consistency Co-authored-by: PatrickFanella <61631520+PatrickFanella@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: PatrickFanella <61631520+PatrickFanella@users.noreply.github.com>
203 lines
5.6 KiB
YAML
203 lines
5.6 KiB
YAML
services:
|
|
postgres:
|
|
image: postgres:15-alpine
|
|
container_name: spywatcher-postgres-dev
|
|
environment:
|
|
POSTGRES_DB: spywatcher
|
|
POSTGRES_USER: spywatcher
|
|
POSTGRES_PASSWORD: ${DB_PASSWORD:-spywatcher_dev_password}
|
|
POSTGRES_INITDB_ARGS: "-E UTF8 --locale=en_US.UTF-8"
|
|
volumes:
|
|
- postgres-data:/var/lib/postgresql/data
|
|
- ./scripts/postgres-init.sql:/docker-entrypoint-initdb.d/init.sql
|
|
ports:
|
|
- "5432:5432"
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U spywatcher"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
networks:
|
|
- spywatcher-network
|
|
command:
|
|
- "postgres"
|
|
- "-c"
|
|
- "max_connections=100"
|
|
- "-c"
|
|
- "shared_buffers=256MB"
|
|
- "-c"
|
|
- "effective_cache_size=1GB"
|
|
- "-c"
|
|
- "maintenance_work_mem=64MB"
|
|
- "-c"
|
|
- "checkpoint_completion_target=0.9"
|
|
- "-c"
|
|
- "wal_buffers=16MB"
|
|
- "-c"
|
|
- "default_statistics_target=100"
|
|
- "-c"
|
|
- "random_page_cost=1.1"
|
|
- "-c"
|
|
- "effective_io_concurrency=200"
|
|
- "-c"
|
|
- "work_mem=4MB"
|
|
- "-c"
|
|
- "min_wal_size=1GB"
|
|
- "-c"
|
|
- "max_wal_size=4GB"
|
|
|
|
pgbouncer:
|
|
build:
|
|
context: ./pgbouncer
|
|
dockerfile: Dockerfile
|
|
container_name: spywatcher-pgbouncer-dev
|
|
environment:
|
|
DB_USER: spywatcher
|
|
DB_PASSWORD: ${DB_PASSWORD:-spywatcher_dev_password}
|
|
PGBOUNCER_ADMIN_USER: pgbouncer_admin
|
|
PGBOUNCER_ADMIN_PASSWORD: ${PGBOUNCER_ADMIN_PASSWORD:-pgbouncer_admin_pass}
|
|
ports:
|
|
- "6432:6432"
|
|
depends_on:
|
|
postgres:
|
|
condition: service_healthy
|
|
networks:
|
|
- spywatcher-network
|
|
|
|
redis:
|
|
image: redis:7-alpine
|
|
container_name: spywatcher-redis-dev
|
|
ports:
|
|
- "6379:6379"
|
|
volumes:
|
|
- redis-data:/data
|
|
healthcheck:
|
|
test: ["CMD", "redis-cli", "ping"]
|
|
interval: 10s
|
|
timeout: 5s
|
|
retries: 5
|
|
networks:
|
|
- spywatcher-network
|
|
command: redis-server --appendonly yes
|
|
|
|
backend:
|
|
build:
|
|
context: ./backend
|
|
dockerfile: Dockerfile.dev
|
|
container_name: spywatcher-backend-dev
|
|
volumes:
|
|
- ./backend:/app
|
|
- /app/node_modules
|
|
- /app/dist
|
|
- logs-backend:/app/logs
|
|
environment:
|
|
# Use PgBouncer for application connections, direct for migrations
|
|
# Connection pool settings: connection_limit=5 (low since PgBouncer handles pooling)
|
|
DATABASE_URL: postgresql://spywatcher:${DB_PASSWORD:-spywatcher_dev_password}@pgbouncer:6432/spywatcher?pgbouncer=true&connection_limit=5&pool_timeout=20
|
|
DATABASE_URL_DIRECT: postgresql://spywatcher:${DB_PASSWORD:-spywatcher_dev_password}@postgres:5432/spywatcher
|
|
REDIS_URL: redis://redis:6379
|
|
NODE_ENV: development
|
|
PORT: 3001
|
|
ADMIN_DISCORD_IDS: ${ADMIN_DISCORD_IDS}
|
|
BOT_GUILD_IDS: ${BOT_GUILD_IDS}
|
|
DISCORD_BOT_TOKEN: ${DISCORD_BOT_TOKEN}
|
|
DISCORD_CLIENT_ID: ${DISCORD_CLIENT_ID}
|
|
DISCORD_CLIENT_SECRET: ${DISCORD_CLIENT_SECRET}
|
|
DISCORD_GUILD_ID: ${DISCORD_GUILD_ID}
|
|
DISCORD_REDIRECT_URI: ${DISCORD_REDIRECT_URI:-http://localhost:5173/auth/callback}
|
|
JWT_REFRESH_SECRET: ${JWT_REFRESH_SECRET:-dev_jwt_refresh_secret}
|
|
JWT_SECRET: ${JWT_SECRET:-dev_jwt_secret}
|
|
ports:
|
|
- "3001:3001"
|
|
depends_on:
|
|
pgbouncer:
|
|
condition: service_started
|
|
redis:
|
|
condition: service_healthy
|
|
networks:
|
|
- spywatcher-network
|
|
labels:
|
|
com.docker.compose.project: "discord-spywatcher"
|
|
command: sh -c "DATABASE_URL=$DATABASE_URL_DIRECT npx prisma migrate dev && npm run dev:api"
|
|
|
|
frontend:
|
|
build:
|
|
context: ./frontend
|
|
dockerfile: Dockerfile.dev
|
|
container_name: spywatcher-frontend-dev
|
|
volumes:
|
|
- ./frontend:/app
|
|
- /app/node_modules
|
|
environment:
|
|
VITE_API_URL: http://localhost:3001
|
|
VITE_DISCORD_CLIENT_ID: ${VITE_DISCORD_CLIENT_ID}
|
|
ports:
|
|
- "5173:5173"
|
|
depends_on:
|
|
- backend
|
|
networks:
|
|
- spywatcher-network
|
|
labels:
|
|
com.docker.compose.project: "discord-spywatcher"
|
|
|
|
loki:
|
|
image: grafana/loki:2.9.3
|
|
container_name: spywatcher-loki-dev
|
|
ports:
|
|
- "3100:3100"
|
|
volumes:
|
|
- ./loki/loki-config.yml:/etc/loki/local-config.yaml
|
|
- loki-data:/loki
|
|
command: -config.file=/etc/loki/local-config.yaml
|
|
networks:
|
|
- spywatcher-network
|
|
labels:
|
|
com.docker.compose.project: "discord-spywatcher"
|
|
|
|
promtail:
|
|
image: grafana/promtail:2.9.3
|
|
container_name: spywatcher-promtail-dev
|
|
volumes:
|
|
- ./promtail/promtail-config.yml:/etc/promtail/config.yml
|
|
- /var/run/docker.sock:/var/run/docker.sock
|
|
- logs-backend:/logs/backend:ro
|
|
command: -config.file=/etc/promtail/config.yml
|
|
depends_on:
|
|
- loki
|
|
networks:
|
|
- spywatcher-network
|
|
labels:
|
|
com.docker.compose.project: "discord-spywatcher"
|
|
|
|
grafana:
|
|
image: grafana/grafana:10.2.3
|
|
container_name: spywatcher-grafana-dev
|
|
ports:
|
|
- "3000:3000"
|
|
volumes:
|
|
- grafana-data:/var/lib/grafana
|
|
- ./grafana/provisioning:/etc/grafana/provisioning
|
|
environment:
|
|
- GF_SECURITY_ADMIN_USER=${GRAFANA_ADMIN_USER:-admin}
|
|
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD:-admin}
|
|
- GF_USERS_ALLOW_SIGN_UP=false
|
|
- GF_SERVER_ROOT_URL=http://localhost:3000
|
|
- GF_INSTALL_PLUGINS=
|
|
depends_on:
|
|
- loki
|
|
networks:
|
|
- spywatcher-network
|
|
labels:
|
|
com.docker.compose.project: "discord-spywatcher"
|
|
|
|
volumes:
|
|
postgres-data:
|
|
redis-data:
|
|
loki-data:
|
|
grafana-data:
|
|
logs-backend:
|
|
|
|
networks:
|
|
spywatcher-network:
|
|
driver: bridge
|