# 多客户 PG 实例(docs/adr-multi-customer-db-isolation.md)。 # # 客户1 继续用同目录的 docker-compose.tencent-pg.yml,本文件只服务 c2 及以后的客户 # + 产品母版 tpl——刻意不合并进那个文件:合并会改掉客户1 的 compose 项目名(jnpf-pg), # 导致 docker compose 认为是新项目并重建它正在跑的容器。 # # 库名与角色名【全客户一致】(jnpf_init / jnpf_flow / jnpf_xxljob / nacos_config, # jnpf_app / jnpf_flow_app / nacos_app),客户之间只靠【端口】区分—— # 这是整个方案让 install.sh / create-app-roles.sh / backup.sh / promote-db.sh # / harden-pg-hba.sh 零改动复用的支点。 # # 用法(在 /home/ubuntu/jnpf-pg/ 下,.env 提供 JNPF_PG_PASSWORD): # CUSTOMER_ID=c2 CUSTOMER_PG_PORT=15433 docker compose -f postgres/tencent/docker-compose.customer-pg.yml up -d # CUSTOMER_ID=tpl CUSTOMER_PG_PORT=15439 docker compose -f postgres/tencent/docker-compose.customer-pg.yml up -d # 一般不直接用,走 ./postgres/tencent/add-customer.sh <客户ID> <端口>。 # # 端口约定:客户N = 15431+N(客户1=15432 已被既有实例占用),产品母版 = 15439。 name: jnpf-pg-${CUSTOMER_ID:?缺 CUSTOMER_ID,如 customer2 / tpl(新客户直接用拼音;c2 是客户B的历史 ID,卷名沿用)} services: pg: # 容器名可与 CUSTOMER_ID 解耦(CUSTOMER_NAME 未设时=CUSTOMER_ID): # 客户B历史 CUSTOMER_ID=c2(项目名/卷名 jnpf_pgdata_c2 由它派生,改了会挂空卷、绝不能动), # 2026-08-08 起容器名规范为 cx-pg-<客户拼音>,.env.客户B 里设 CUSTOMER_NAME=customer2 即可。 # 新客户 CUSTOMER_ID 直接用拼音,无需设 CUSTOMER_NAME。 container_name: cx-pg-${CUSTOMER_NAME:-${CUSTOMER_ID}} # 与客户1 同镜像(cx/postgres:18.4,含 pg_bigm/pgvector)。刻意不写 build: # CVM 上该镜像已存在,新客户不该触发重新构建。 image: cx/postgres:18.4 platform: linux/amd64 restart: unless-stopped shm_size: 256m # 客户1 的既有实例是 3g(400 连接 + 512MB shared_buffers);新实例按 # ADR §5 的 150 连接 + 128MB shared_buffers 预算,1g 足够,6 个实例才 ~3G。 mem_limit: 1g memswap_limit: 1g # CVM 无 swap,禁止溢出 environment: TZ: Asia/Shanghai POSTGRES_USER: postgres POSTGRES_PASSWORD: ${JNPF_PG_PASSWORD:?缺 JNPF_PG_PASSWORD,先在 .env 设} POSTGRES_INITDB_ARGS: "--locale=C.UTF-8 --encoding=UTF8" volumes: - pgdata:/var/lib/postgresql ports: - "${CUSTOMER_PG_PORT:?缺 CUSTOMER_PG_PORT,客户N=15431+N,母版=15439}:5432" command: - postgres - -c # 每实例独算,不再抢客户1 那 400 槽的全局池。 # 实测一套长跑全栈 45 连接、Druid 压到 5/1 后 ~25,150 可容 ~5 套栈。 - max_connections=150 - -c # 一整套库才 435MB 且实测 active 连接恒为 0(全是池空占),512MB 是浪费。 # 客户1 的既有实例维持 512MB 不动。 - shared_buffers=128MB - -c - shared_preload_libraries=pg_stat_statements,auto_explain - -c - pg_stat_statements.track=all - -c - timezone=Asia/Shanghai healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"] interval: 15s timeout: 10s retries: 10 start_period: 60s volumes: pgdata: # 显式命名,避免 compose 按项目名生成 jnpf-pg-c2_pgdata 这种不好辨认的卷名 name: jnpf_pgdata_${CUSTOMER_ID}