From b664cb33c4f213851619b34754e6d2b95cdcc814 Mon Sep 17 00:00:00 2001 From: Keannu Bernasol Date: Thu, 5 Sep 2024 13:16:23 +0800 Subject: [PATCH] Add native PgBouncer support to alleviate DB connection limit errors --- .env.sample | 5 ++++- backend/config/settings.py | 18 ++++++++++++++---- docker-compose.demo.yml | 13 +++++++++++-- docker-compose.dev.yml | 23 +++++++++++++++++++---- 4 files changed, 48 insertions(+), 11 deletions(-) diff --git a/.env.sample b/.env.sample index 021b6f6..0658d59 100644 --- a/.env.sample +++ b/.env.sample @@ -27,7 +27,10 @@ DB_PASSWORD = '' DB_HOST = 'postgres' DB_PORT = '5432' DB_SSL_MODE = 'disable' -DB_DISABLE_SERVER_SIDE_CURSORS = 'False' # If you're using an external connection bouncer (eg. PgBouncer), set this to True +# DB connection bouncer +USE_BOUNCER = 'True' +DB_BOUNCER_HOST = 'pgbouncer' +DB_BOUNCER_PORT = '6432' # Redis # Used for DB cache and Celery broker diff --git a/backend/config/settings.py b/backend/config/settings.py index bfd5707..514e5b1 100644 --- a/backend/config/settings.py +++ b/backend/config/settings.py @@ -223,16 +223,26 @@ SPECTACULAR_SETTINGS = { WSGI_APPLICATION = 'config.wsgi.application' +# If you're using an external connection bouncer (eg. PgBouncer), server side cursors must be disabled to avoid any issues +USE_BOUNCER = get_secret("USE_BOUNCER") +if USE_BOUNCER: + DISABLE_SERVER_SIDE_CURSORS = True + DB_HOST = get_secret("DB_BOUNCER_HOST") + DB_PORT = get_secret("DB_BOUNCER_PORT") +else: + DISABLE_SERVER_SIDE_CURSORS = False + DB_HOST = get_secret("DB_HOST") + DB_PORT = get_secret("DB_PORT") + DATABASES = { "default": { "ENGINE": "django.db.backends.postgresql", - # Set to True to avoid issues with pgbouncer when pooling connections - 'DISABLE_SERVER_SIDE_CURSORS': get_secret("DB_DISABLE_SERVER_SIDE_CURSORS"), + 'DISABLE_SERVER_SIDE_CURSORS': DISABLE_SERVER_SIDE_CURSORS, "NAME": get_secret("DB_DATABASE"), "USER": get_secret("DB_USERNAME"), "PASSWORD": get_secret("DB_PASSWORD"), - "HOST": get_secret("DB_HOST"), - "PORT": get_secret("DB_PORT"), + "HOST": DB_HOST, + "PORT": DB_PORT, "OPTIONS": { "sslmode": get_secret("DB_SSL_MODE") }, diff --git a/docker-compose.demo.yml b/docker-compose.demo.yml index eeb09d9..bbc5326 100644 --- a/docker-compose.demo.yml +++ b/docker-compose.demo.yml @@ -51,11 +51,20 @@ services: volumes: - db-data:/var/lib/postgresql/data + # DB Bouncer + pgbouncer: + image: bitnami/pgbouncer:latest + environment: + - POSTGRESQL_HOST=postgres + - PGBOUNCER_DATABASE=${DB_DATABASE} + - POSTGRESQL_USERNAME=${DB_USERNAME} + - POSTGRESQL_PASSWORD=${DB_PASSWORD} + depends_on: + - postgres + # Redis Server redis: image: redis:latest - ports: - - "${REDIS_PORT}:6379" # Stripe CLI Webhook Listener stripe-listener: diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index b5a63e8..58fc5ab 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -17,6 +17,8 @@ services: - .:/code depends_on: - postgres + - pgbouncer + - redis # Django Celery Worker celery: @@ -32,6 +34,7 @@ services: depends_on: - django - postgres + - pgbouncer - redis # Runs multiple worker instances scale: 4 @@ -45,9 +48,10 @@ services: volumes: - .:/code depends_on: - - celery - django + - celery - postgres + - pgbouncer - redis # Django Celery Monitor @@ -62,8 +66,10 @@ services: volumes: - .:/code depends_on: - - celery - django + - celery + - postgres + - pgbouncer - redis # SQL Database @@ -77,11 +83,20 @@ services: volumes: - db-data:/var/lib/postgresql/data + # DB Bouncer + pgbouncer: + image: bitnami/pgbouncer:latest + environment: + - POSTGRESQL_HOST=postgres + - PGBOUNCER_DATABASE=${DB_DATABASE} + - POSTGRESQL_USERNAME=${DB_USERNAME} + - POSTGRESQL_PASSWORD=${DB_PASSWORD} + depends_on: + - postgres + # Redis Server redis: image: redis:latest - ports: - - "${REDIS_PORT}:6379" # Stripe CLI Webhook Listener stripe-listener: