name: rtgs # RTGS 3센터 A-A-A 풀스택 (컨테이너). 로컬 native(run-*.cmd)와 별개 — Coder/podman 등 컨테이너 호스트용. # 공유 인프라(PostgreSQL 3DB + Kafka) + 단일 순번기 + DC1/DC2/DC3 각 6서비스 + 프론트(콘솔·DT). # 컨테이너는 네트워크 격리라 포트 오프셋 불필요(전부 기본 포트, service name으로 구분). # ---------- 공용 백엔드(서비스 공통) ---------- x-backend-env: &backend-env POSTGRES_HOST: postgres POSTGRES_PORT: "5432" POSTGRES_USER: rtgs POSTGRES_PASSWORD: rtgs KAFKA_BOOTSTRAP: kafka:9092 CENTER_COUNT: "3" GUCCI_JWT_SECRET: rtgs-gucci-dev-secret-key-please-change-0123456789 x-backend: &backend image: rtgs-backend:latest build: context: .. dockerfile: deploy/Dockerfile.backend restart: unless-stopped x-health: &svc-health healthcheck: test: ["CMD-SHELL", "curl -fs http://localhost:$${SERVER_PORT}/actuator/health || exit 1"] interval: 10s timeout: 4s retries: 30 start_period: 40s services: # ================= 인프라 ================= postgres: image: postgres:16 container_name: rtgs-postgres environment: POSTGRES_DB: rtgs POSTGRES_USER: rtgs POSTGRES_PASSWORD: rtgs command: ["postgres", "-c", "max_connections=300"] volumes: - pgdata:/var/lib/postgresql/data - ./init/init-3centers.sql:/docker-entrypoint-initdb.d/01-init-3centers.sql:ro healthcheck: test: ["CMD-SHELL", "pg_isready -U rtgs -d rtgs"] interval: 5s timeout: 3s retries: 30 kafka: image: apache/kafka:3.8.1 container_name: rtgs-kafka environment: KAFKA_NODE_ID: "1" KAFKA_PROCESS_ROLES: "broker,controller" KAFKA_CONTROLLER_QUORUM_VOTERS: "1@kafka:9093" KAFKA_LISTENERS: "PLAINTEXT://:9092,CONTROLLER://:9093" KAFKA_ADVERTISED_LISTENERS: "PLAINTEXT://kafka:9092" KAFKA_CONTROLLER_LISTENER_NAMES: "CONTROLLER" KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: "CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT" KAFKA_INTER_BROKER_LISTENER_NAME: "PLAINTEXT" KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: "1" KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: "1" KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: "1" KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: "0" KAFKA_NUM_PARTITIONS: "1" # 저널 전역순서 = 단일 파티션 KAFKA_AUTO_CREATE_TOPICS_ENABLE: "true" healthcheck: test: ["CMD-SHELL", "/opt/kafka/bin/kafka-topics.sh --bootstrap-server localhost:9092 --list || exit 1"] interval: 10s timeout: 5s retries: 30 start_period: 20s # ================= 순번기(전역 단일, DC1) ================= sequencer: <<: [*backend, *svc-health] container_name: rtgs-sequencer environment: {<<: *backend-env, SERVICE: sequencer, SERVER_PORT: "8090", CENTER_ID: DC1, POSTGRES_DB: rtgs_dc1} depends_on: kafka: {condition: service_healthy} dc1-louisvuitton: {condition: service_healthy} # ================= DC1 ================= dc1-louisvuitton: <<: [*backend, *svc-health] container_name: rtgs-dc1-louisvuitton environment: {<<: *backend-env, SERVICE: louisvuitton, SERVER_PORT: "8099", CENTER_ID: DC1, POSTGRES_DB: rtgs_dc1} depends_on: {postgres: {condition: service_healthy}} ports: ["8099:8099"] dc1-dior: <<: [*backend, *svc-health] environment: {<<: *backend-env, SERVICE: dior, SERVER_PORT: "8092", CENTER_ID: DC1, POSTGRES_DB: rtgs_dc1} depends_on: {dc1-louisvuitton: {condition: service_healthy}, kafka: {condition: service_healthy}} dc1-hermes: <<: [*backend, *svc-health] environment: {<<: *backend-env, SERVICE: hermes, SERVER_PORT: "8093", CENTER_ID: DC1, POSTGRES_DB: rtgs_dc1} depends_on: {dc1-louisvuitton: {condition: service_healthy}, kafka: {condition: service_healthy}} dc1-prada: <<: [*backend, *svc-health] environment: {<<: *backend-env, SERVICE: prada, SERVER_PORT: "8094", CENTER_ID: DC1, POSTGRES_DB: rtgs_dc1} depends_on: {dc1-louisvuitton: {condition: service_healthy}, kafka: {condition: service_healthy}} dc1-chanel: <<: [*backend, *svc-health] environment: {<<: *backend-env, SERVICE: chanel, SERVER_PORT: "8091", CENTER_ID: DC1, POSTGRES_DB: rtgs_dc1} depends_on: {dc1-louisvuitton: {condition: service_healthy}, kafka: {condition: service_healthy}} dc1-gucci: <<: [*backend, *svc-health] environment: {<<: *backend-env, SERVICE: gucci, SERVER_PORT: "8095", CENTER_ID: DC1, POSTGRES_DB: rtgs_dc1, CHANEL_URL: "http://dc1-chanel:8091"} depends_on: {dc1-chanel: {condition: service_healthy}} ports: ["8095:8095"] # ================= DC2 ================= dc2-louisvuitton: <<: [*backend, *svc-health] container_name: rtgs-dc2-louisvuitton environment: {<<: *backend-env, SERVICE: louisvuitton, SERVER_PORT: "8099", CENTER_ID: DC2, POSTGRES_DB: rtgs_dc2, RTGS_CONTROL_ENABLED: "false"} depends_on: {postgres: {condition: service_healthy}} ports: ["8199:8099"] dc2-dior: <<: [*backend, *svc-health] environment: {<<: *backend-env, SERVICE: dior, SERVER_PORT: "8092", CENTER_ID: DC2, POSTGRES_DB: rtgs_dc2} depends_on: {dc2-louisvuitton: {condition: service_healthy}, kafka: {condition: service_healthy}} dc2-hermes: <<: [*backend, *svc-health] environment: {<<: *backend-env, SERVICE: hermes, SERVER_PORT: "8093", CENTER_ID: DC2, POSTGRES_DB: rtgs_dc2} depends_on: {dc2-louisvuitton: {condition: service_healthy}, kafka: {condition: service_healthy}} dc2-prada: <<: [*backend, *svc-health] environment: {<<: *backend-env, SERVICE: prada, SERVER_PORT: "8094", CENTER_ID: DC2, POSTGRES_DB: rtgs_dc2} depends_on: {dc2-louisvuitton: {condition: service_healthy}, kafka: {condition: service_healthy}} dc2-chanel: <<: [*backend, *svc-health] environment: {<<: *backend-env, SERVICE: chanel, SERVER_PORT: "8091", CENTER_ID: DC2, POSTGRES_DB: rtgs_dc2} depends_on: {dc2-louisvuitton: {condition: service_healthy}, kafka: {condition: service_healthy}} dc2-gucci: <<: [*backend, *svc-health] environment: {<<: *backend-env, SERVICE: gucci, SERVER_PORT: "8095", CENTER_ID: DC2, POSTGRES_DB: rtgs_dc2, CHANEL_URL: "http://dc2-chanel:8091"} depends_on: {dc2-chanel: {condition: service_healthy}} ports: ["8195:8095"] # ================= DC3 ================= dc3-louisvuitton: <<: [*backend, *svc-health] container_name: rtgs-dc3-louisvuitton environment: {<<: *backend-env, SERVICE: louisvuitton, SERVER_PORT: "8099", CENTER_ID: DC3, POSTGRES_DB: rtgs_dc3, RTGS_CONTROL_ENABLED: "false"} depends_on: {postgres: {condition: service_healthy}} ports: ["8299:8099"] dc3-dior: <<: [*backend, *svc-health] environment: {<<: *backend-env, SERVICE: dior, SERVER_PORT: "8092", CENTER_ID: DC3, POSTGRES_DB: rtgs_dc3} depends_on: {dc3-louisvuitton: {condition: service_healthy}, kafka: {condition: service_healthy}} dc3-hermes: <<: [*backend, *svc-health] environment: {<<: *backend-env, SERVICE: hermes, SERVER_PORT: "8093", CENTER_ID: DC3, POSTGRES_DB: rtgs_dc3} depends_on: {dc3-louisvuitton: {condition: service_healthy}, kafka: {condition: service_healthy}} dc3-prada: <<: [*backend, *svc-health] environment: {<<: *backend-env, SERVICE: prada, SERVER_PORT: "8094", CENTER_ID: DC3, POSTGRES_DB: rtgs_dc3} depends_on: {dc3-louisvuitton: {condition: service_healthy}, kafka: {condition: service_healthy}} dc3-chanel: <<: [*backend, *svc-health] environment: {<<: *backend-env, SERVICE: chanel, SERVER_PORT: "8091", CENTER_ID: DC3, POSTGRES_DB: rtgs_dc3} depends_on: {dc3-louisvuitton: {condition: service_healthy}, kafka: {condition: service_healthy}} dc3-gucci: <<: [*backend, *svc-health] environment: {<<: *backend-env, SERVICE: gucci, SERVER_PORT: "8095", CENTER_ID: DC3, POSTGRES_DB: rtgs_dc3, CHANEL_URL: "http://dc3-chanel:8091"} depends_on: {dc3-chanel: {condition: service_healthy}} ports: ["8295:8095"] # ================= 프론트(콘솔 + DT) ================= frontend: image: rtgs-frontend:latest build: context: .. dockerfile: deploy/Dockerfile.frontend container_name: rtgs-frontend restart: unless-stopped ports: ["8080:80"] depends_on: dc1-gucci: {condition: service_healthy} volumes: pgdata: