postgresql: add disposable dry-run test stack for cutover validation (pgha-test, own network + data dirs, zero prod impact)
This commit is contained in:
@@ -0,0 +1,208 @@
|
||||
# ─────────────────────────────────────────────────────────────────────────
|
||||
# postgresql/cutover/test/pgha-dryrun.yaml — DISPOSABLE dry-run stack
|
||||
#
|
||||
# Validates the ADR-0001 cutover mechanics WITHOUT touching production:
|
||||
# - own overlay network (pgha-test_db-backend), own stack name
|
||||
# - throwaway "legacy" postgres:17 seeded with marker data, carrying the
|
||||
# in-network alias "postgresql" (mirrors prod CLONE_HOST)
|
||||
# - same etcd/patroni/haproxy topology, images, and env wiring as the
|
||||
# real staging file — including clone-from-live via pg_basebackup
|
||||
# - reuses the real Docker secrets (read-only mounts; harmless)
|
||||
# - disposable data dirs under /volume1/docker/PostgreSQL/dryrun/
|
||||
#
|
||||
# Deploy: docker stack deploy -c <this file> pgha-test
|
||||
# Teardown: docker stack rm pgha-test && rm -rf /volume1/docker/PostgreSQL/dryrun
|
||||
# ─────────────────────────────────────────────────────────────────────────
|
||||
version: "3.6"
|
||||
|
||||
services:
|
||||
|
||||
# Stand-in for the production single-instance postgres (clone source)
|
||||
legacy:
|
||||
image: public.ecr.aws/docker/library/postgres:17
|
||||
hostname: db
|
||||
command: [postgres]
|
||||
environment:
|
||||
POSTGRES_USER: PGadmin
|
||||
POSTGRES_PASSWORD_FILE: /run/secrets/postgresql_password
|
||||
secrets:
|
||||
- postgresql_password
|
||||
volumes:
|
||||
- /volume1/docker/PostgreSQL/dryrun/legacy:/var/lib/postgresql/data
|
||||
networks:
|
||||
db-backend:
|
||||
aliases:
|
||||
- postgresql
|
||||
- db
|
||||
deploy:
|
||||
placement:
|
||||
constraints:
|
||||
- node.hostname == docker-2
|
||||
|
||||
etcd-1:
|
||||
image: quay.io/coreos/etcd:v3.5.9
|
||||
hostname: etcd-1
|
||||
command:
|
||||
- etcd
|
||||
- --name=etcd-1
|
||||
- --data-dir=/etcd-data
|
||||
- --initial-advertise-peer-urls=http://etcd-1:2380
|
||||
- --listen-peer-urls=http://0.0.0.0:2380
|
||||
- --listen-client-urls=http://0.0.0.0:2379
|
||||
- --advertise-client-urls=http://etcd-1:2379
|
||||
- --initial-cluster=etcd-1=http://etcd-1:2380,etcd-2=http://etcd-2:2380,etcd-3=http://etcd-3:2380
|
||||
- --initial-cluster-state=new
|
||||
- --initial-cluster-token=pgha-test-etcd
|
||||
volumes:
|
||||
- /volume1/docker/PostgreSQL/dryrun/etcd-1:/etcd-data
|
||||
networks:
|
||||
- db-backend
|
||||
deploy:
|
||||
placement:
|
||||
constraints:
|
||||
- node.hostname == docker-1
|
||||
|
||||
etcd-2:
|
||||
image: quay.io/coreos/etcd:v3.5.9
|
||||
hostname: etcd-2
|
||||
command:
|
||||
- etcd
|
||||
- --name=etcd-2
|
||||
- --data-dir=/etcd-data
|
||||
- --initial-advertise-peer-urls=http://etcd-2:2380
|
||||
- --listen-peer-urls=http://0.0.0.0:2380
|
||||
- --listen-client-urls=http://0.0.0.0:2379
|
||||
- --advertise-client-urls=http://etcd-2:2379
|
||||
- --initial-cluster=etcd-1=http://etcd-1:2380,etcd-2=http://etcd-2:2380,etcd-3=http://etcd-3:2380
|
||||
- --initial-cluster-state=new
|
||||
- --initial-cluster-token=pgha-test-etcd
|
||||
volumes:
|
||||
- /volume1/docker/PostgreSQL/dryrun/etcd-2:/etcd-data
|
||||
networks:
|
||||
- db-backend
|
||||
deploy:
|
||||
placement:
|
||||
constraints:
|
||||
- node.hostname == docker-2
|
||||
|
||||
etcd-3:
|
||||
image: quay.io/coreos/etcd:v3.5.9
|
||||
hostname: etcd-3
|
||||
command:
|
||||
- etcd
|
||||
- --name=etcd-3
|
||||
- --data-dir=/etcd-data
|
||||
- --initial-advertise-peer-urls=http://etcd-3:2380
|
||||
- --listen-peer-urls=http://0.0.0.0:2380
|
||||
- --listen-client-urls=http://0.0.0.0:2379
|
||||
- --advertise-client-urls=http://etcd-3:2379
|
||||
- --initial-cluster=etcd-1=http://etcd-1:2380,etcd-2=http://etcd-2:2380,etcd-3=http://etcd-3:2380
|
||||
- --initial-cluster-state=new
|
||||
- --initial-cluster-token=pgha-test-etcd
|
||||
volumes:
|
||||
- /volume1/docker/PostgreSQL/dryrun/etcd-3:/etcd-data
|
||||
networks:
|
||||
- db-backend
|
||||
deploy:
|
||||
placement:
|
||||
constraints:
|
||||
- node.hostname == docker-3
|
||||
|
||||
patroni-0:
|
||||
image: ghcr.io/zalando/spilo-17:4.0-p3
|
||||
hostname: patroni-0
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- |
|
||||
export PGPASSWORD_SUPERUSER="$(cat /run/secrets/postgresql_password)"
|
||||
export PGPASSWORD_STANDBY="$(cat /run/secrets/postgresql_replication_password)"
|
||||
export PATRONI_RESTAPI_PASSWORD="$(cat /run/secrets/postgresql_patroni_password)"
|
||||
export CLONE_PASSWORD="$(cat /run/secrets/postgresql_password)"
|
||||
exec /bin/sh /launch.sh init
|
||||
environment:
|
||||
SCOPE: pgha-test
|
||||
PATRONI_NAME: patroni-0
|
||||
ETCD_HOSTS: '"etcd-1:2379","etcd-2:2379","etcd-3:2379"'
|
||||
PGUSER_SUPERUSER: PGadmin
|
||||
PGUSER_STANDBY: standby
|
||||
PATRONI_RESTAPI_USERNAME: patroni
|
||||
PGROOT: /home/postgres/pgdata/pgroot
|
||||
CLONE_METHOD: CLONE_WITH_BASEBACKUP
|
||||
CLONE_SCOPE: legacy-single
|
||||
CLONE_HOST: postgresql
|
||||
CLONE_PORT: "5432"
|
||||
CLONE_USER: PGadmin
|
||||
secrets:
|
||||
- postgresql_password
|
||||
- postgresql_replication_password
|
||||
- postgresql_patroni_password
|
||||
volumes:
|
||||
- /volume1/docker/PostgreSQL/dryrun/patroni-0:/home/postgres/pgdata
|
||||
networks:
|
||||
- db-backend
|
||||
deploy:
|
||||
placement:
|
||||
constraints:
|
||||
- node.labels.pg-role == primary
|
||||
|
||||
patroni-1:
|
||||
image: ghcr.io/zalando/spilo-17:4.0-p3
|
||||
hostname: patroni-1
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- |
|
||||
export PGPASSWORD_SUPERUSER="$(cat /run/secrets/postgresql_password)"
|
||||
export PGPASSWORD_STANDBY="$(cat /run/secrets/postgresql_replication_password)"
|
||||
export PATRONI_RESTAPI_PASSWORD="$(cat /run/secrets/postgresql_patroni_password)"
|
||||
export CLONE_PASSWORD="$(cat /run/secrets/postgresql_password)"
|
||||
exec /bin/sh /launch.sh init
|
||||
environment:
|
||||
SCOPE: pgha-test
|
||||
PATRONI_NAME: patroni-1
|
||||
ETCD_HOSTS: '"etcd-1:2379","etcd-2:2379","etcd-3:2379"'
|
||||
PGUSER_SUPERUSER: PGadmin
|
||||
PGUSER_STANDBY: standby
|
||||
PATRONI_RESTAPI_USERNAME: patroni
|
||||
PGROOT: /home/postgres/pgdata/pgroot
|
||||
CLONE_METHOD: CLONE_WITH_BASEBACKUP
|
||||
CLONE_SCOPE: legacy-single
|
||||
CLONE_HOST: postgresql
|
||||
CLONE_PORT: "5432"
|
||||
CLONE_USER: PGadmin
|
||||
secrets:
|
||||
- postgresql_password
|
||||
- postgresql_replication_password
|
||||
- postgresql_patroni_password
|
||||
volumes:
|
||||
- /volume1/docker/PostgreSQL/dryrun/patroni-1:/home/postgres/pgdata
|
||||
networks:
|
||||
- db-backend
|
||||
deploy:
|
||||
placement:
|
||||
constraints:
|
||||
- node.labels.pg-role == replica
|
||||
|
||||
haproxy:
|
||||
image: haproxy:2.9-alpine
|
||||
hostname: haproxy
|
||||
volumes:
|
||||
- /volume1/docker/compose-files/postgresql/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:ro
|
||||
networks:
|
||||
- db-backend
|
||||
deploy:
|
||||
mode: global
|
||||
|
||||
networks:
|
||||
db-backend:
|
||||
attachable: true
|
||||
driver: overlay
|
||||
|
||||
secrets:
|
||||
postgresql_password:
|
||||
external: true
|
||||
postgresql_replication_password:
|
||||
external: true
|
||||
postgresql_patroni_password:
|
||||
external: true
|
||||
Reference in New Issue
Block a user