fleetanalytics_mcp/pgbouncer/docker-compose.yml
kiania b58e429c1c infra(pgbouncer): add transaction-pooling front for timescale_db
The DB is at max_connections=100 with ~9 services each holding persistent pools
(several as the postgres superuser, idle for hours), so peaks hit "too many
connections". PgBouncer multiplexes many client connections onto a small fixed
set of backends, bounding DB connections regardless of how many app pools exist.

Adds (stack-wide infra, parked in this repo for now — see README scope note):
- pgbouncer.ini: transaction pooling, auth_query pass-through, bounded pool sizes
- auth_setup.sql: pgbouncer_auth role + SECURITY DEFINER pgbouncer.user_lookup()
  so per-app passwords aren't hand-maintained
- docker-compose.yml: the service (join the existing DB network)
- userlist.txt.example + .gitignore: keep the auth verifier out of git
- README.md: deploy steps, incremental cutover (superuser apps first), and the
  transaction-pooling caveats — including the MCP-specific note (rely on role-level
  GUCs; simplest to leave the minor MCP direct and pool the heavy superuser apps)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 23:44:30 +03:00

40 lines
2 KiB
YAML

# docker-compose.yml — PgBouncer in front of timescale_db.
# ─────────────────────────────────────────────────────────────────────────────
# Deploy:
# 1. Apply auth_setup.sql to the DB as postgres (creates pgbouncer_auth + lookup fn).
# 2. Generate pgbouncer/userlist.txt (see userlist.txt.example).
# 3. Put this stack on the SAME docker network as timescale_db so `timescale_db`
# resolves (the tracksolid stack's network — the one with the 10.0.15.x addrs).
# 4. `docker compose -f pgbouncer/docker-compose.yml up -d`
# 5. Repoint each app's DSN host:port from timescale_db:5432 → pgbouncer:6432
# (same dbname/user/password) and redeploy it. Migrate the SUPERUSER app pools
# first — they are the heaviest consumers.
services:
pgbouncer:
image: edoburu/pgbouncer:latest # pin to a digest/tag in prod
container_name: pgbouncer
restart: unless-stopped
networks: [dbnet]
ports:
- "6432:6432" # drop this if only in-network apps connect
volumes:
- ./pgbouncer.ini:/etc/pgbouncer/pgbouncer.ini:ro
- ./userlist.txt:/etc/pgbouncer/userlist.txt:ro
logging:
driver: json-file
options: { max-size: "10m", max-file: "5" }
healthcheck:
# `SHOW VERSION` on the admin console proves PgBouncer is accepting connections.
test: ["CMD-SHELL", "psql -h 127.0.0.1 -p 6432 -U pgbouncer_auth pgbouncer -tAc 'SHOW VERSION' || exit 1"]
interval: 30s
timeout: 3s
retries: 3
start_period: 10s
networks:
# Attach to the EXISTING network that can reach timescale_db (external = pre-created
# by the tracksolid/Coolify stack). Set the real name here, e.g. the network shown by
# docker inspect timescale_db --format '{{range $k,$v := .NetworkSettings.Networks}}{{$k}}{{"\n"}}{{end}}'
dbnet:
external: true
name: CHANGE_ME_tracksolid_db_network