version: '3.8' services: # PostgreSQL Database postgres: image: postgres:16-alpine container_name: boc-postgres environment: POSTGRES_USER: boc POSTGRES_PASSWORD: boc_secret_2026 POSTGRES_DB: boc volumes: - postgres_data:/var/lib/postgresql/data ports: - "5435:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U boc"] interval: 5s timeout: 5s retries: 5 networks: - boc-network # Redis — Cache, Sessions, Rate Limiting, Pub/Sub redis: image: redis:7-alpine container_name: boc-redis command: redis-server --appendonly yes --maxmemory 256mb --maxmemory-policy allkeys-lru volumes: - redis_data:/data ports: - "6381:6379" healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 3s retries: 5 networks: - boc-network # Kafka — Event Streaming zookeeper: image: confluentinc/cp-zookeeper:7.5.0 container_name: boc-zookeeper environment: ZOOKEEPER_CLIENT_PORT: 2181 ZOOKEEPER_TICK_TIME: 2000 networks: - boc-network kafka: image: confluentinc/cp-kafka:7.5.0 container_name: boc-kafka depends_on: - zookeeper ports: - "9095:9092" environment: KAFKA_BROKER_ID: 1 KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092,PLAINTEXT_INTERNAL://kafka:29092 KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_INTERNAL:PLAINTEXT KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT_INTERNAL KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 KAFKA_AUTO_CREATE_TOPICS_ENABLE: "true" healthcheck: test: ["CMD", "kafka-broker-api-versions", "--bootstrap-server", "localhost:9092"] interval: 10s timeout: 5s retries: 5 networks: - boc-network # Kafka UI kafka-ui: image: provectuslabs/kafka-ui:latest container_name: boc-kafka-ui ports: - "8084:8080" environment: KAFKA_CLUSTERS_0_NAME: boc KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS: kafka:29092 KAFKA_CLUSTERS_0_ZOOKEEPER: zookeeper:2181 depends_on: - kafka networks: - boc-network # Go Backend API boc-api: build: context: ./backend dockerfile: Dockerfile container_name: boc-api environment: PORT: "9092" DB_URL: "postgres://boc:boc_secret_2026@postgres:5432/boc?sslmode=disable" JWT_SECRET: "boc_jwt_secret_change_in_production" AMOS_BASE_URL: "http://aamos-ledger:3250" MIGRATIONS_DIR: "./db/migrations" RUST_SERVICE_URL: "http://boc-rust:9093" REDIS_URL: "redis://redis:6379" KAFKA_BROKERS: "kafka:29092" ports: - "9096:9092" depends_on: postgres: condition: service_healthy redis: condition: service_healthy kafka: condition: service_healthy volumes: - ./backend/db/migrations:/app/db/migrations:ro restart: unless-stopped healthcheck: test: ["CMD", "wget", "-q", "--spider", "http://localhost:9092/health"] interval: 10s timeout: 5s retries: 3 networks: - boc-network # Rust Analytics Service boc-rust: build: context: ./rust-service dockerfile: Dockerfile container_name: boc-rust environment: RUST_LOG: "info" DB_URL: "postgres://boc:boc_secret_2026@postgres:5432/boc?sslmode=disable" REDIS_URL: "redis://redis:6379" KAFKA_BROKERS: "kafka:29092" ports: - "9093:9093" depends_on: postgres: condition: service_healthy redis: condition: service_healthy kafka: condition: service_healthy restart: unless-stopped healthcheck: test: ["CMD", "wget", "-q", "--spider", "http://localhost:9093/health"] interval: 10s timeout: 5s retries: 3 networks: - boc-network # C Runtime (shared memory / IPC) boc-c-runtime: build: context: ./c-runtime dockerfile: Dockerfile container_name: boc-c-runtime environment: SHM_NAME: "/boc_ipc_main" SHM_SIZE: "16777216" depends_on: - boc-api - boc-rust restart: unless-stopped privileged: true shm_size: '32mb' networks: - boc-network # Nginx Reverse Proxy nginx: image: nginx:alpine container_name: boc-nginx ports: - "80:80" - "443:443" volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./web:/usr/share/nginx/html:ro depends_on: - boc-api - boc-rust restart: unless-stopped networks: - boc-network volumes: postgres_data: redis_data: networks: boc-network: driver: bridge