# ============================================================================= # RWA Backend Services - Docker Compose # ============================================================================= # Usage: # ./deploy.sh up # Start all services # ./deploy.sh down # Stop all services # ./deploy.sh logs # View logs # ./deploy.sh status # Check status # ============================================================================= services: # =========================================================================== # Infrastructure Services # =========================================================================== postgres: image: postgres:16-alpine container_name: rwa-postgres environment: POSTGRES_USER: ${POSTGRES_USER:-rwa_user} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-rwa_secure_password} POSTGRES_MULTIPLE_DATABASES: rwa_identity,rwa_wallet,rwa_mpc,rwa_backup,rwa_planting,rwa_referral,rwa_reward,rwa_leaderboard,rwa_reporting,rwa_authorization,rwa_admin,rwa_presence ports: - "5432:5432" volumes: - postgres_data:/var/lib/postgresql/data - ./scripts/init-databases.sh:/docker-entrypoint-initdb.d/init-databases.sh:ro healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-rwa_user}"] interval: 5s timeout: 5s retries: 10 restart: unless-stopped networks: - rwa-network redis: image: redis:7-alpine container_name: rwa-redis command: redis-server --appendonly yes ${REDIS_PASSWORD:+--requirepass $REDIS_PASSWORD} ports: - "6379:6379" volumes: - redis_data:/data healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 5s retries: 10 restart: unless-stopped networks: - rwa-network zookeeper: image: confluentinc/cp-zookeeper:7.5.0 container_name: rwa-zookeeper environment: ZOOKEEPER_CLIENT_PORT: 2181 ZOOKEEPER_TICK_TIME: 2000 healthcheck: test: ["CMD", "nc", "-z", "localhost", "2181"] interval: 10s timeout: 5s retries: 5 restart: unless-stopped networks: - rwa-network kafka: image: confluentinc/cp-kafka:7.5.0 container_name: rwa-kafka depends_on: zookeeper: condition: service_healthy ports: - "9092:9092" environment: KAFKA_BROKER_ID: 1 KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092 KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:29092,PLAINTEXT_HOST://0.0.0.0:9092 KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 KAFKA_AUTO_CREATE_TOPICS_ENABLE: "true" healthcheck: test: ["CMD", "kafka-topics", "--bootstrap-server", "localhost:9092", "--list"] interval: 30s timeout: 10s retries: 5 start_period: 30s restart: unless-stopped networks: - rwa-network # =========================================================================== # Application Services # =========================================================================== identity-service: build: context: ./identity-service dockerfile: Dockerfile container_name: rwa-identity-service ports: - "3000:3000" environment: - NODE_ENV=production - APP_PORT=3000 - DATABASE_URL=postgresql://${POSTGRES_USER:-rwa_user}:${POSTGRES_PASSWORD:-rwa_secure_password}@postgres:5432/rwa_identity?schema=public - JWT_SECRET=${JWT_SECRET} - JWT_ACCESS_EXPIRES_IN=2h - JWT_REFRESH_EXPIRES_IN=30d - REDIS_HOST=redis - REDIS_PORT=6379 - REDIS_PASSWORD=${REDIS_PASSWORD:-} - REDIS_DB=0 - KAFKA_BROKERS=kafka:29092 - KAFKA_CLIENT_ID=identity-service - KAFKA_GROUP_ID=identity-service-group - WALLET_ENCRYPTION_SALT=${WALLET_ENCRYPTION_SALT} - MPC_SERVICE_URL=http://mpc-service:3006 - MPC_MODE=remote - BACKUP_SERVICE_URL=http://backup-service:3002 - BACKUP_SERVICE_ENABLED=true - SERVICE_JWT_SECRET=${SERVICE_JWT_SECRET} depends_on: postgres: condition: service_healthy redis: condition: service_healthy kafka: condition: service_started healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3000/api/v1/health"] interval: 30s timeout: 3s retries: 3 start_period: 40s restart: unless-stopped networks: - rwa-network wallet-service: build: context: ./wallet-service dockerfile: Dockerfile container_name: rwa-wallet-service ports: - "3001:3001" environment: - NODE_ENV=production - APP_PORT=3001 - DATABASE_URL=postgresql://${POSTGRES_USER:-rwa_user}:${POSTGRES_PASSWORD:-rwa_secure_password}@postgres:5432/rwa_wallet?schema=public - JWT_SECRET=${JWT_SECRET} - REDIS_HOST=redis - REDIS_PORT=6379 - REDIS_PASSWORD=${REDIS_PASSWORD:-} - REDIS_DB=1 - KAFKA_BROKERS=kafka:29092 - KAFKA_CLIENT_ID=wallet-service - KAFKA_GROUP_ID=wallet-service-group depends_on: postgres: condition: service_healthy redis: condition: service_healthy kafka: condition: service_started healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3001/api/v1/health"] interval: 30s timeout: 3s retries: 3 start_period: 40s restart: unless-stopped networks: - rwa-network backup-service: build: context: ./backup-service dockerfile: Dockerfile container_name: rwa-backup-service ports: - "3002:3002" environment: - NODE_ENV=production - APP_PORT=3002 - DATABASE_URL=postgresql://${POSTGRES_USER:-rwa_user}:${POSTGRES_PASSWORD:-rwa_secure_password}@postgres:5432/rwa_backup?schema=public - SERVICE_JWT_SECRET=${SERVICE_JWT_SECRET} - ALLOWED_SERVICES=identity-service,recovery-service - BACKUP_ENCRYPTION_KEY=${BACKUP_ENCRYPTION_KEY} - BACKUP_ENCRYPTION_KEY_ID=key-v1 - MAX_RETRIEVE_PER_DAY=3 - MAX_STORE_PER_MINUTE=10 depends_on: postgres: condition: service_healthy healthcheck: test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:3002/health"] interval: 30s timeout: 3s retries: 3 start_period: 40s restart: unless-stopped networks: - rwa-network planting-service: build: context: ./planting-service dockerfile: Dockerfile container_name: rwa-planting-service ports: - "3003:3003" environment: - NODE_ENV=production - APP_PORT=3003 - DATABASE_URL=postgresql://${POSTGRES_USER:-rwa_user}:${POSTGRES_PASSWORD:-rwa_secure_password}@postgres:5432/rwa_planting?schema=public - JWT_SECRET=${JWT_SECRET} - REDIS_HOST=redis - REDIS_PORT=6379 - REDIS_PASSWORD=${REDIS_PASSWORD:-} - REDIS_DB=2 - KAFKA_BROKERS=kafka:29092 - KAFKA_CLIENT_ID=planting-service - KAFKA_GROUP_ID=planting-service-group depends_on: postgres: condition: service_healthy redis: condition: service_healthy kafka: condition: service_started healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3003/api/v1/health"] interval: 30s timeout: 3s retries: 3 start_period: 40s restart: unless-stopped networks: - rwa-network referral-service: build: context: ./referral-service dockerfile: Dockerfile container_name: rwa-referral-service ports: - "3004:3004" environment: - NODE_ENV=production - APP_PORT=3004 - DATABASE_URL=postgresql://${POSTGRES_USER:-rwa_user}:${POSTGRES_PASSWORD:-rwa_secure_password}@postgres:5432/rwa_referral?schema=public - JWT_SECRET=${JWT_SECRET} - REDIS_HOST=redis - REDIS_PORT=6379 - REDIS_PASSWORD=${REDIS_PASSWORD:-} - REDIS_DB=3 - KAFKA_BROKERS=kafka:29092 - KAFKA_CLIENT_ID=referral-service - KAFKA_GROUP_ID=referral-service-group depends_on: postgres: condition: service_healthy redis: condition: service_healthy kafka: condition: service_started healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3004/api/v1/health"] interval: 30s timeout: 3s retries: 3 start_period: 40s restart: unless-stopped networks: - rwa-network reward-service: build: context: ./reward-service dockerfile: Dockerfile container_name: rwa-reward-service ports: - "3005:3005" environment: - NODE_ENV=production - APP_PORT=3005 - DATABASE_URL=postgresql://${POSTGRES_USER:-rwa_user}:${POSTGRES_PASSWORD:-rwa_secure_password}@postgres:5432/rwa_reward?schema=public - JWT_SECRET=${JWT_SECRET} - REDIS_HOST=redis - REDIS_PORT=6379 - REDIS_PASSWORD=${REDIS_PASSWORD:-} - REDIS_DB=4 - KAFKA_BROKERS=kafka:29092 - KAFKA_CLIENT_ID=reward-service - KAFKA_GROUP_ID=reward-service-group depends_on: postgres: condition: service_healthy redis: condition: service_healthy kafka: condition: service_started healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3005/health"] interval: 30s timeout: 3s retries: 3 start_period: 40s restart: unless-stopped networks: - rwa-network mpc-service: build: context: ./mpc-service dockerfile: Dockerfile container_name: rwa-mpc-service ports: - "3006:3006" environment: - NODE_ENV=production - APP_PORT=3006 - DATABASE_URL=postgresql://${POSTGRES_USER:-rwa_user}:${POSTGRES_PASSWORD:-rwa_secure_password}@postgres:5432/rwa_mpc?schema=public - JWT_SECRET=${JWT_SECRET} - REDIS_HOST=redis - REDIS_PORT=6379 - REDIS_PASSWORD=${REDIS_PASSWORD:-} - REDIS_DB=5 - KAFKA_BROKERS=kafka:29092 - KAFKA_CLIENT_ID=mpc-service - KAFKA_GROUP_ID=mpc-service-group # MPC System (deployed on 192.168.1.111) - MPC_ACCOUNT_SERVICE_URL=http://192.168.1.111:4000 - MPC_COORDINATOR_URL=http://192.168.1.111:8081 - MPC_SESSION_COORDINATOR_URL=http://192.168.1.111:8081 - MPC_MESSAGE_ROUTER_WS_URL=ws://192.168.1.111:8082 - MPC_SERVER_PARTY_API_URL=http://192.168.1.111:8083 - MPC_API_KEY=rwa-mpc-api-key-2024-secure-access-token - SHARE_MASTER_KEY=${SHARE_MASTER_KEY} depends_on: postgres: condition: service_healthy redis: condition: service_healthy kafka: condition: service_started healthcheck: test: ["CMD", "node", "-e", "require('http').get('http://localhost:3006/api/v1/health', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"] interval: 30s timeout: 3s retries: 3 start_period: 40s restart: unless-stopped networks: - rwa-network leaderboard-service: build: context: ./leaderboard-service dockerfile: Dockerfile container_name: rwa-leaderboard-service ports: - "3007:3007" environment: - NODE_ENV=production - APP_PORT=3007 - DATABASE_URL=postgresql://${POSTGRES_USER:-rwa_user}:${POSTGRES_PASSWORD:-rwa_secure_password}@postgres:5432/rwa_leaderboard?schema=public - JWT_SECRET=${JWT_SECRET} - REDIS_HOST=redis - REDIS_PORT=6379 - REDIS_PASSWORD=${REDIS_PASSWORD:-} - REDIS_DB=6 - KAFKA_BROKERS=kafka:29092 - KAFKA_CLIENT_ID=leaderboard-service - KAFKA_GROUP_ID=leaderboard-service-group depends_on: postgres: condition: service_healthy redis: condition: service_healthy kafka: condition: service_started healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3007/api/health"] interval: 30s timeout: 3s retries: 3 start_period: 40s restart: unless-stopped networks: - rwa-network reporting-service: build: context: ./reporting-service dockerfile: Dockerfile container_name: rwa-reporting-service ports: - "3008:3008" environment: - NODE_ENV=production - APP_PORT=3008 - DATABASE_URL=postgresql://${POSTGRES_USER:-rwa_user}:${POSTGRES_PASSWORD:-rwa_secure_password}@postgres:5432/rwa_reporting?schema=public - JWT_SECRET=${JWT_SECRET} - REDIS_HOST=redis - REDIS_PORT=6379 - REDIS_PASSWORD=${REDIS_PASSWORD:-} - REDIS_DB=7 - KAFKA_BROKERS=kafka:29092 - KAFKA_CLIENT_ID=reporting-service - KAFKA_GROUP_ID=reporting-service-group depends_on: postgres: condition: service_healthy redis: condition: service_healthy kafka: condition: service_started healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3008/api/v1/health"] interval: 30s timeout: 3s retries: 3 start_period: 40s restart: unless-stopped networks: - rwa-network authorization-service: build: context: ./authorization-service dockerfile: Dockerfile container_name: rwa-authorization-service ports: - "3009:3009" environment: - NODE_ENV=production - APP_PORT=3009 - DATABASE_URL=postgresql://${POSTGRES_USER:-rwa_user}:${POSTGRES_PASSWORD:-rwa_secure_password}@postgres:5432/rwa_authorization?schema=public - JWT_SECRET=${JWT_SECRET} - REDIS_HOST=redis - REDIS_PORT=6379 - REDIS_PASSWORD=${REDIS_PASSWORD:-} - REDIS_DB=8 - KAFKA_BROKERS=kafka:29092 - KAFKA_CLIENT_ID=authorization-service - KAFKA_GROUP_ID=authorization-service-group depends_on: postgres: condition: service_healthy redis: condition: service_healthy kafka: condition: service_started healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3009/api/v1/health"] interval: 30s timeout: 3s retries: 3 start_period: 40s restart: unless-stopped networks: - rwa-network admin-service: build: context: ./admin-service dockerfile: Dockerfile container_name: rwa-admin-service ports: - "3010:3010" environment: - NODE_ENV=production - APP_PORT=3010 - DATABASE_URL=postgresql://${POSTGRES_USER:-rwa_user}:${POSTGRES_PASSWORD:-rwa_secure_password}@postgres:5432/rwa_admin?schema=public - JWT_SECRET=${JWT_SECRET} - REDIS_HOST=redis - REDIS_PORT=6379 - REDIS_PASSWORD=${REDIS_PASSWORD:-} - REDIS_DB=9 depends_on: postgres: condition: service_healthy redis: condition: service_healthy healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3010/api/v1/health"] interval: 30s timeout: 3s retries: 3 start_period: 40s restart: unless-stopped networks: - rwa-network presence-service: build: context: ./presence-service dockerfile: Dockerfile container_name: rwa-presence-service ports: - "3011:3011" environment: - NODE_ENV=production - APP_PORT=3011 - API_PREFIX=api/v1 - DATABASE_URL=postgresql://${POSTGRES_USER:-rwa_user}:${POSTGRES_PASSWORD:-rwa_secure_password}@postgres:5432/rwa_presence?schema=public - JWT_SECRET=${JWT_SECRET} - REDIS_HOST=redis - REDIS_PORT=6379 - REDIS_PASSWORD=${REDIS_PASSWORD:-} - REDIS_DB=10 - KAFKA_ENABLED=true - KAFKA_BROKERS=kafka:29092 - KAFKA_CLIENT_ID=presence-service - KAFKA_GROUP_ID=presence-service-group - PRESENCE_WINDOW_SECONDS=180 - SNAPSHOT_INTERVAL_SECONDS=60 - TZ=Asia/Shanghai depends_on: postgres: condition: service_healthy redis: condition: service_healthy kafka: condition: service_started healthcheck: test: ["CMD", "curl", "-f", "http://localhost:3011/api/v1/health"] interval: 30s timeout: 3s retries: 3 start_period: 40s restart: unless-stopped networks: - rwa-network # =========================================================================== # Volumes # =========================================================================== volumes: postgres_data: driver: local redis_data: driver: local # =========================================================================== # Networks # =========================================================================== networks: rwa-network: driver: bridge