services: # ============================ # GATEWAY # ============================ gateway: image: nginx:alpine volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro ports: - "80:80" depends_on: - api_store - api_internal networks: - frontend_net # ============================ # APPLICATION FLEETS # ============================ api_store: build: ./server environment: - APP_MODULE=store - DB_HOST=pgbouncer - DB_USER=admin - DB_PASSWORD=password - DB_NAME=plantshop - DB_PORT=6432 - JWT_SECRET=supersecretkey networks: - frontend_net - backend_net depends_on: - pgbouncer api_pos: build: ./server environment: - APP_MODULE=pos - DB_HOST=pgbouncer - DB_USER=admin - DB_PASSWORD=password - DB_NAME=plantshop - DB_PORT=6432 - JWT_SECRET=supersecretkey networks: - frontend_net - backend_net depends_on: - pgbouncer api_internal: build: ./server environment: - APP_MODULE=internal - DB_HOST=pgbouncer - DB_USER=admin - DB_PASSWORD=password - DB_NAME=plantshop - DB_PORT=6432 - JWT_SECRET=supersecretkey networks: - frontend_net - backend_net depends_on: - pgbouncer # ============================ # DATABASE PRIMARY # ============================ db_primary: image: postgres:15-alpine environment: POSTGRES_USER: admin POSTGRES_PASSWORD: password POSTGRES_DB: plantshop volumes: - pg_primary_data:/var/lib/postgresql/data - ./postgres/config:/etc/postgresql networks: - backend_net healthcheck: test: ["CMD-SHELL", "pg_isready -U admin"] interval: 10s retries: 5 # ============================ # DATABASE REPLICAS # ============================ db_replica1: image: postgres:15-alpine environment: POSTGRES_USER: admin POSTGRES_PASSWORD: password POSTGRES_DB: plantshop volumes: - pg_replica1_data:/var/lib/postgresql/data - ./postgres/config:/etc/postgresql networks: - backend_net depends_on: - db_primary command: > sh -c " until pg_basebackup -h db_primary -D /var/lib/postgresql/data -U admin -v -P --wal-method=stream; do sleep 5; done && postgres -c hot_standby=on " healthcheck: test: ["CMD-SHELL", "pg_isready -U admin"] interval: 10s retries: 5 db_replica2: image: postgres:15-alpine environment: POSTGRES_USER: admin POSTGRES_PASSWORD: password POSTGRES_DB: plantshop volumes: - pg_replica2_data:/var/lib/postgresql/data - ./postgres/config:/etc/postgresql networks: - backend_net depends_on: - db_primary command: > sh -c " until pg_basebackup -h db_primary -D /var/lib/postgresql/data -U admin -v -P --wal-method=stream; do sleep 5; done && postgres -c hot_standby=on " healthcheck: test: ["CMD-SHELL", "pg_isready -U admin"] interval: 10s retries: 5 # ============================ # CONNECTION POOLER # ============================ pgbouncer: image: brainsam/pgbouncer:latest environment: DB_HOST: db_primary DB_PORT: 5432 DB_USER: admin DB_PASSWORD: password DB_NAME: plantshop POOL_MODE: session MAX_CLIENT_CONN: 200 DEFAULT_POOL_SIZE: 20 ports: - "6432:6432" networks: - backend_net depends_on: - db_primary - db_replica1 - db_replica2 # ============================ # MINIO STORAGE # ============================ minio: image: minio/minio command: server /data --console-address ":9001" environment: MINIO_ROOT_USER: admin MINIO_ROOT_PASSWORD: password ports: - "9000:9000" - "9001:9001" volumes: - minio_data:/data networks: - backend_net # ============================ # NETWORKS # ============================ networks: frontend_net: backend_net: # ============================ # VOLUMES # ============================ volumes: pg_primary_data: pg_replica1_data: pg_replica2_data: minio_data: