# =================================================================== # TopFans Docker Compose - Production (4G RAM, 2 CPU) # =================================================================== # Usage: # docker-compose -f docker-compose.prod.yml --profile prod up -d # =================================================================== x-common-env: &common-env GIN_MODE: release ENV: production LOG_LEVEL: info DB_HOST: postgres DB_PORT: 5432 DB_USER: postgres DB_PASSWORD: ${DB_PASSWORD:-postgres123} DB_NAME: topfans DB_SSLMODE: disable x-postgres-env: &postgres-env POSTGRES_DB: topfans POSTGRES_USER: postgres POSTGRES_PASSWORD: ${DB_PASSWORD:-postgres123} POSTGRES_MAX_CONNECTIONS: 100 POSTGRES_SHARED_BUFFERS: 128MB POSTGRES_WORK_MEM: 8MB POSTGRES_MAINTENANCE_WORK_MEM: 64MB POSTGRES_EFFECTIVE_CACHE_SIZE: 512MB POSTGRES_CHECKPOINT_COMPLETION_TARGET: 0.9 POSTGRES_WAL_BUFFERS: 8MB x-healthcheck: &healthcheck interval: 30s timeout: 10s retries: 5 start_period: 60s services: # ==================== Database ==================== postgres: image: postgres:latest container_name: topfans-postgres restart: always environment: <<: *postgres-env volumes: - postgres_data:/var/lib/postgresql ports: - "5432:5432" networks: - topfans-net healthcheck: test: ["CMD-SHELL", "pg_isready -U postgres -d topfans"] <<: *healthcheck deploy: resources: limits: memory: 400M reservations: memory: 128M # ==================== Redis ==================== redis: image: redis:latest container_name: topfans-redis restart: always environment: REDIS_PASSWORD: ${REDIS_PASSWORD:-123456} ports: - "6379:6379" networks: - topfans-net healthcheck: test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD:-123456}", "ping"] interval: 30s timeout: 10s retries: 5 deploy: resources: limits: memory: 256M reservations: memory: 64M # ==================== Flyway Migration ==================== # flyway: # image: flyway/flyway:10 # container_name: topfans-flyway # restart: "no" # depends_on: # postgres: # condition: service_healthy # environment: # - FLYWAY_URL=jdbc:postgresql://postgres:5432/topfans # - FLYWAY_USER=postgres # - FLYWAY_PASSWORD=${DB_PASSWORD:-postgres123} # - FLYWAY_SCHEMAS=public # - FLYWAY_PLACEHOLDER_REPLACEMENT=true # volumes: # - ./sql/migrations:/flyway/sql # - flyway_data:/flyway/data # command: migrate -baselineOnMigrate=true # networks: # - topfans-net # ==================== Dubbo Services ==================== userservice: image: topfans/userservice:latest build: context: .. dockerfile: docker/Dockerfile.services target: userservice container_name: topfans-userservice restart: always env_file: - .env.prod environment: <<: *common-env PORT: 20000 DB_HOST: postgres DB_PORT: 5432 DB_USER: postgres DB_PASSWORD: ${DB_PASSWORD:-postgres123} DB_NAME: topfans REDIS_HOST: topfans-redis REDIS_PORT: 6379 REDIS_PASSWORD: ${REDIS_PASSWORD:-123456} REDIS_DB: 0 depends_on: postgres: condition: service_healthy redis: condition: service_healthy networks: - topfans-net expose: - "20000" healthcheck: test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:21000 || exit 1"] <<: *healthcheck deploy: resources: limits: memory: 150M cpus: '0.5' reservations: memory: 64M cpus: '0.25' assetservice: image: topfans/assetservice:latest build: context: .. dockerfile: docker/Dockerfile.services target: assetservice container_name: topfans-assetservice restart: always env_file: - .env.prod environment: <<: *common-env PORT: 20003 DB_HOST: postgres DB_PORT: 5432 DB_USER: postgres DB_PASSWORD: ${DB_PASSWORD:-postgres123} DB_NAME: topfans USER_SERVICE_URL: tri://userservice:20000 depends_on: userservice: condition: service_started networks: - topfans-net expose: - "20003" healthcheck: test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:21003 || exit 1"] <<: *healthcheck deploy: resources: limits: memory: 200M cpus: '0.5' reservations: memory: 64M cpus: '0.25' socialservice: image: topfans/socialservice:latest build: context: .. dockerfile: docker/Dockerfile.services target: socialservice container_name: topfans-socialservice restart: always environment: <<: *common-env PORT: 20002 DB_HOST: postgres DB_PORT: 5432 DB_USER: postgres DB_PASSWORD: ${DB_PASSWORD:-postgres123} DB_NAME: topfans USER_SERVICE_URL: tri://userservice:20000 ASSET_SERVICE_URL: tri://assetservice:20003 depends_on: userservice: condition: service_started assetservice: condition: service_started networks: - topfans-net expose: - "20002" healthcheck: test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:21002 || exit 1"] <<: *healthcheck deploy: resources: limits: memory: 150M cpus: '0.5' reservations: memory: 64M cpus: '0.25' galleryservice: image: topfans/galleryservice:latest build: context: .. dockerfile: docker/Dockerfile.services target: galleryservice container_name: topfans-galleryservice restart: always environment: <<: *common-env PORT: 20001 DB_HOST: postgres DB_PORT: 5432 DB_USER: postgres DB_PASSWORD: ${DB_PASSWORD:-postgres123} DB_NAME: topfans USER_SERVICE_URL: tri://userservice:20000 ASSET_SERVICE_URL: tri://assetservice:20003 TASK_SERVICE_URL: tri://taskservice:20006 depends_on: userservice: condition: service_started assetservice: condition: service_started networks: - topfans-net expose: - "20001" healthcheck: test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:21001 || exit 1"] <<: *healthcheck deploy: resources: limits: memory: 150M cpus: '0.5' reservations: memory: 64M cpus: '0.25' activityservice: image: topfans/activityservice:latest build: context: .. dockerfile: docker/Dockerfile.services target: activityservice container_name: topfans-activityservice restart: always environment: <<: *common-env PORT: 20004 DB_HOST: postgres DB_PORT: 5432 DB_USER: postgres DB_PASSWORD: ${DB_PASSWORD:-postgres123} DB_NAME: topfans USER_SERVICE_URL: tri://userservice:20000 REDIS_HOST: topfans-redis REDIS_PORT: 6379 REDIS_PASSWORD: ${REDIS_PASSWORD:-123456} REDIS_DB: 0 depends_on: userservice: condition: service_started redis: condition: service_healthy networks: - topfans-net expose: - "20004" healthcheck: test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:21004 || exit 1"] <<: *healthcheck deploy: resources: limits: memory: 100M cpus: '0.5' reservations: memory: 32M cpus: '0.25' taskservice: image: topfans/taskservice:latest build: context: .. dockerfile: docker/Dockerfile.services target: taskservice container_name: topfans-taskservice restart: always environment: <<: *common-env PORT: 20006 DB_HOST: postgres DB_PORT: 5432 DB_USER: postgres DB_PASSWORD: ${DB_PASSWORD:-postgres123} DB_NAME: topfans USER_SERVICE_URL: tri://userservice:20000 GALLERY_SERVICE_URL: tri://galleryservice:20001 depends_on: userservice: condition: service_started networks: - topfans-net expose: - "20006" healthcheck: test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:21006 || exit 1"] <<: *healthcheck deploy: resources: limits: memory: 150M cpus: '0.5' reservations: memory: 64M cpus: '0.25' starbookservice: image: topfans/starbookservice:latest build: context: .. dockerfile: docker/Dockerfile.services target: starbookservice container_name: topfans-starbookservice restart: always environment: <<: *common-env PORT: 20005 DB_HOST: postgres DB_PORT: 5432 DB_USER: postgres DB_PASSWORD: ${DB_PASSWORD:-postgres123} DB_NAME: topfans ASSET_SERVICE_URL: tri://assetservice:20003 depends_on: userservice: condition: service_started assetservice: condition: service_started networks: - topfans-net expose: - "20005" healthcheck: test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:21005 || exit 1"] <<: *healthcheck deploy: resources: limits: memory: 150M cpus: '0.5' reservations: memory: 64M cpus: '0.25' # ==================== AI Chat Service ==================== aichatservice: image: topfans/aichatservice:latest build: context: .. dockerfile: docker/Dockerfile.services target: aichatservice container_name: topfans-aichatservice restart: always env_file: - .env.prod environment: <<: *common-env PORT: 20008 DB_HOST: postgres DB_PORT: 5432 DB_USER: postgres DB_PASSWORD: ${DB_PASSWORD:-postgres123} DB_NAME: topfans REDIS_HOST: topfans-redis REDIS_PORT: 6379 REDIS_PASSWORD: ${REDIS_PASSWORD:-123456} REDIS_DB: 0 depends_on: userservice: condition: service_started redis: condition: service_healthy networks: - topfans-net expose: - "20008" healthcheck: test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:21008 || exit 1"] <<: *healthcheck deploy: resources: limits: memory: 512M cpus: '1' reservations: memory: 256M cpus: '0.5' # ==================== API Gateway ==================== gateway: image: topfans/gateway:latest build: context: .. dockerfile: docker/Dockerfile.services target: gateway container_name: topfans-gateway restart: always env_file: - .env.prod environment: <<: *common-env SERVER_PORT: 8080 JWT_SECRET: ${JWT_SECRET:-topfans-secret-key-please-change-in-production} DUBBO_USER_SERVICE_URL: tri://userservice:20000 DUBBO_SOCIAL_SERVICE_URL: tri://socialservice:20002 DUBBO_ASSET_SERVICE_URL: tri://assetservice:20003 DUBBO_GALLERY_SERVICE_URL: tri://galleryservice:20001 DUBBO_ACTIVITY_SERVICE_URL: tri://activityservice:20004 DUBBO_TASK_SERVICE_URL: tri://taskservice:20006 DUBBO_STARBOOK_SERVICE_URL: tri://starbookservice:20005 DIFY_API_BASE: ${DIFY_API_BASE:-http://dify-api:8081/v1} DIFY_API_KEY: ${DIFY_API_KEY:-} DUBBO_AI_CHAT_SERVICE_URL: tri://aichatservice:20008 REDIS_HOST: topfans-redis REDIS_PORT: 6379 REDIS_PASSWORD: ${REDIS_PASSWORD:-123456} REDIS_DB: 0 depends_on: userservice: condition: service_started assetservice: condition: service_started socialservice: condition: service_started galleryservice: condition: service_started activityservice: condition: service_started taskservice: condition: service_started starbookservice: condition: service_started aichatservice: condition: service_started redis: condition: service_healthy networks: - topfans-net ports: - "8080:8080" healthcheck: test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1"] <<: *healthcheck deploy: resources: limits: memory: 200M cpus: '0.5' reservations: memory: 64M cpus: '0.25' volumes: postgres_data: flyway_data: networks: topfans-net: driver: bridge external: true