# ============================================================ # 智慧水务管理系统 - Docker Compose 编排 # 包含基础设施 + 应用服务 # 启动: docker compose up -d # 日志: docker compose logs -f [service] # ============================================================ services: # ==================== 基础设施 ==================== postgres: image: postgis/postgis:16-3.4 container_name: wm-postgres restart: unless-stopped environment: POSTGRES_DB: ${POSTGRES_DB:-water_management} POSTGRES_USER: ${POSTGRES_USER:-water} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-water123} ports: - "5432:5432" volumes: - pgdata:/var/lib/postgresql/data - ./sql:/docker-entrypoint-initdb.d:ro networks: - wm-network healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-water}"] interval: 10s timeout: 5s retries: 5 tdengine: image: tdengine/tdengine:3.3.3.0 container_name: wm-tdengine restart: unless-stopped ports: - "6030:6030" - "6041:6041" - "6043:6043" environment: TAOS_FQDN: tdengine volumes: - tddata:/var/lib/taos networks: - wm-network healthcheck: test: ["CMD", "taos", "-s", "show databases"] interval: 10s timeout: 5s retries: 5 redis: image: redis:7-alpine container_name: wm-redis restart: unless-stopped ports: - "6379:6379" command: redis-server --requirepass ${REDIS_PASSWORD:-water123} volumes: - redisdata:/data networks: - wm-network healthcheck: test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD:-water123}", "ping"] interval: 10s timeout: 3s retries: 5 # ==================== 消息队列 ==================== kafka: image: bitnami/kafka:3.8 container_name: wm-kafka restart: unless-stopped ports: - "9092:9092" environment: KAFKA_CFG_NODE_ID: 0 KAFKA_CFG_PROCESS_ROLES: controller,broker KAFKA_CFG_CONTROLLER_QUORUM_VOTERS: 0@kafka:9093 KAFKA_CFG_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093 KAFKA_CFG_ADVERTISED_LISTENERS: PLAINTEXT://${KAFKA_ADVERTISED:-kafka}:9092 KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT KAFKA_CFG_CONTROLLER_LISTENER_NAMES: CONTROLLER KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE: "true" volumes: - kafkadata:/bitnami/kafka networks: - wm-network healthcheck: test: ["CMD-SHELL", "kafka-topics.sh --bootstrap-server localhost:9092 --list"] interval: 15s timeout: 10s retries: 5 # ==================== 物联网 MQTT ==================== emqx: image: emqx/emqx:5.7.2 container_name: wm-emqx restart: unless-stopped ports: - "1883:1883" - "8083:8083" - "18083:18083" environment: EMQX_DASHBOARD__DEFAULT_USERNAME: ${EMQX_ADMIN_USER:-admin} EMQX_DASHBOARD__DEFAULT_PASSWORD: ${EMQX_ADMIN_PASSWORD:-public} volumes: - emqxdata:/opt/emqx/data networks: - wm-network healthcheck: test: ["CMD", "emqx", "ping"] interval: 10s timeout: 5s retries: 5 # ==================== 服务注册/配置 ==================== nacos: image: nacos/nacos-server:v2.3.2 container_name: wm-nacos restart: unless-stopped environment: MODE: standalone PREFER_HOST_MODE: hostname SPRING_DATASOURCE_PLATFORM: "" ports: - "8848:8848" - "9848:9848" volumes: - nacosdata:/home/nacos/data networks: - wm-network healthcheck: test: ["CMD-SHELL", "curl -sf http://localhost:8848/nacos/v1/console/health/readiness"] interval: 15s timeout: 5s retries: 5 # ==================== 搜索引擎 ==================== elasticsearch: image: elasticsearch:8.15.0 container_name: wm-es restart: unless-stopped environment: discovery.type: single-node xpack.security.enabled: "false" "ES_JAVA_OPTS": "-Xms512m -Xmx512m" ports: - "9200:9200" volumes: - esdata:/usr/share/elasticsearch/data networks: - wm-network profiles: - testing - full kibana: image: kibana:8.15.0 container_name: wm-kibana restart: unless-stopped ports: - "5601:5601" environment: ELASTICSEARCH_HOSTS: http://elasticsearch:9200 depends_on: - elasticsearch networks: - wm-network profiles: - testing - full # ==================== 对象存储 ==================== minio: image: minio/minio:latest container_name: wm-minio restart: unless-stopped ports: - "9000:9000" - "9001:9001" environment: MINIO_ROOT_USER: ${MINIO_USER:-minioadmin} MINIO_ROOT_PASSWORD: ${MINIO_PASSWORD:-minioadmin} volumes: - miniodata:/data command: server /data --console-address ":9001" networks: - wm-network healthcheck: test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] interval: 10s timeout: 5s retries: 5 # ==================== GIS 地图服务 ==================== geoserver: image: docker.osgeo.org/geoserver:2.25.2 container_name: wm-geoserver restart: unless-stopped ports: - "8081:8080" environment: INSTALL_EXTENSIONS: "true" STABLE_EXTENSIONS: "wps,csw" GEOSERVER_ADMIN_USER: ${GEOSERVER_USER:-admin} GEOSERVER_ADMIN_PASSWORD: ${GEOSERVER_PASSWORD:-geoserver} volumes: - geoserverdata:/opt/geoserver_data networks: - wm-network profiles: - gis - testing - full healthcheck: test: ["CMD-SHELL", "curl -s http://localhost:8080/geoserver/web/"] interval: 20s timeout: 10s retries: 3 # ==================== 应用服务 ==================== # API 网关 gateway: build: context: . dockerfile: Dockerfile args: MODULE: wm-gateway PORT: 8080 image: water/wm-gateway container_name: wm-gateway restart: unless-stopped ports: - "8080:8080" environment: SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES:-docker} SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR: nacos:8848 SPRING_CLOUD_NACOS_CONFIG_SERVER_ADDR: nacos:8848 SPRING_DATA_REDIS_HOST: redis SPRING_DATA_REDIS_PASSWORD: ${REDIS_PASSWORD:-water123} depends_on: nacos: condition: service_healthy redis: condition: service_healthy networks: - wm-network healthcheck: test: ["CMD-SHELL", "curl -sf http://localhost:8080/actuator/health || exit 1"] interval: 30s timeout: 10s start_period: 90s retries: 3 # 基础服务 base: build: context: . dockerfile: Dockerfile args: MODULE: wm-base PORT: 8081 image: water/wm-base container_name: wm-base restart: unless-stopped ports: - "8091:8081" environment: SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES:-docker} SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR: nacos:8848 SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB:-water_management} SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER:-water} SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD:-water123} SPRING_DATA_REDIS_HOST: redis SPRING_DATA_REDIS_PASSWORD: ${REDIS_PASSWORD:-water123} depends_on: postgres: condition: service_healthy nacos: condition: service_healthy redis: condition: service_healthy networks: - wm-network healthcheck: test: ["CMD-SHELL", "curl -sf http://localhost:8081/actuator/health || exit 1"] interval: 30s timeout: 10s start_period: 90s retries: 3 # 物联网服务 iot: build: context: . dockerfile: Dockerfile args: MODULE: wm-iot PORT: 8082 image: water/wm-iot container_name: wm-iot restart: unless-stopped ports: - "8092:8082" environment: SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES:-docker} SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR: nacos:8848 SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB:-water_management} SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER:-water} SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD:-water123} MQTT_BROKER_URL: tcp://emqx:1883 depends_on: postgres: condition: service_healthy nacos: condition: service_healthy emqx: condition: service_healthy networks: - wm-network healthcheck: test: ["CMD-SHELL", "curl -sf http://localhost:8082/actuator/health || exit 1"] interval: 30s timeout: 10s start_period: 90s retries: 3 # 数据引擎 data-engine: build: context: . dockerfile: Dockerfile args: MODULE: wm-data-engine PORT: 8083 image: water/wm-data-engine container_name: wm-data-engine restart: unless-stopped ports: - "8093:8083" environment: SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES:-docker} SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR: nacos:8848 SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB:-water_management} SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER:-water} SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD:-water123} depends_on: postgres: condition: service_healthy nacos: condition: service_healthy tdengine: condition: service_healthy networks: - wm-network healthcheck: test: ["CMD-SHELL", "curl -sf http://localhost:8083/actuator/health || exit 1"] interval: 30s timeout: 10s start_period: 90s retries: 3 # 业务流程 bpm: build: context: . dockerfile: Dockerfile args: MODULE: wm-bpm PORT: 8084 image: water/wm-bpm container_name: wm-bpm restart: unless-stopped ports: - "8094:8084" environment: SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES:-docker} SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR: nacos:8848 SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB:-water_management} SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER:-water} SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD:-water123} depends_on: postgres: condition: service_healthy nacos: condition: service_healthy networks: - wm-network healthcheck: test: ["CMD-SHELL", "curl -sf http://localhost:8084/actuator/health || exit 1"] interval: 30s timeout: 10s start_period: 90s retries: 3 # 生产管理 production: build: context: . dockerfile: Dockerfile args: MODULE: wm-production PORT: 8085 image: water/wm-production container_name: wm-production restart: unless-stopped ports: - "8095:8085" environment: SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES:-docker} SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR: nacos:8848 SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB:-water_management} SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER:-water} SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD:-water123} depends_on: postgres: condition: service_healthy nacos: condition: service_healthy networks: - wm-network healthcheck: test: ["CMD-SHELL", "curl -sf http://localhost:8085/actuator/health || exit 1"] interval: 30s timeout: 10s start_period: 90s retries: 3 # 营业收费 revenue: build: context: . dockerfile: Dockerfile args: MODULE: wm-revenue PORT: 8086 image: water/wm-revenue container_name: wm-revenue restart: unless-stopped ports: - "8096:8086" environment: SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES:-docker} SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR: nacos:8848 SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB:-water_management} SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER:-water} SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD:-water123} depends_on: postgres: condition: service_healthy nacos: condition: service_healthy networks: - wm-network healthcheck: test: ["CMD-SHELL", "curl -sf http://localhost:8086/actuator/health || exit 1"] interval: 30s timeout: 10s start_period: 90s retries: 3 # 巡检管理 patrol: build: context: . dockerfile: Dockerfile.patrol image: water/wm-patrol container_name: wm-patrol restart: unless-stopped ports: - "8097:8087" environment: SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES:-docker} SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR: nacos:8848 SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB:-water_management} SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER:-water} SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD:-water123} depends_on: postgres: condition: service_healthy nacos: condition: service_healthy networks: - wm-network healthcheck: test: ["CMD-SHELL", "curl -sf http://localhost:8087/actuator/health || exit 1"] interval: 30s timeout: 10s start_period: 90s retries: 3 # 大数据分析 bi: build: context: . dockerfile: Dockerfile args: MODULE: wm-bi PORT: 8088 image: water/wm-bi container_name: wm-bi restart: unless-stopped ports: - "8098:8088" environment: SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES:-docker} SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR: nacos:8848 SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB:-water_management} SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER:-water} SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD:-water123} depends_on: postgres: condition: service_healthy nacos: condition: service_healthy networks: - wm-network profiles: - testing - full healthcheck: test: ["CMD-SHELL", "curl -sf http://localhost:8088/actuator/health || exit 1"] interval: 30s timeout: 10s start_period: 90s retries: 3 # 消息通知 notify: build: context: . dockerfile: Dockerfile args: MODULE: wm-notify PORT: 8089 image: water/wm-notify container_name: wm-notify restart: unless-stopped ports: - "8099:8089" environment: SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES:-docker} SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR: nacos:8848 SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB:-water_management} SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER:-water} SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD:-water123} depends_on: postgres: condition: service_healthy nacos: condition: service_healthy networks: - wm-network healthcheck: test: ["CMD-SHELL", "curl -sf http://localhost:8089/actuator/health || exit 1"] interval: 30s timeout: 10s start_period: 90s retries: 3 # 定时任务 job: build: context: . dockerfile: Dockerfile args: MODULE: wm-job PORT: 8090 image: water/wm-job container_name: wm-job restart: unless-stopped ports: - "8100:8090" environment: SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES:-docker} SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR: nacos:8848 SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB:-water_management} SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER:-water} SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD:-water123} depends_on: postgres: condition: service_healthy nacos: condition: service_healthy networks: - wm-network healthcheck: test: ["CMD-SHELL", "curl -sf http://localhost:8090/actuator/health || exit 1"] interval: 30s timeout: 10s start_period: 90s retries: 3 # ==================== 前端 ==================== frontend: build: context: . dockerfile: Dockerfile.frontend image: water/frontend container_name: wm-frontend restart: unless-stopped ports: - "80:80" depends_on: - gateway networks: - wm-network healthcheck: test: ["CMD-SHELL", "wget -qO- http://localhost/ || exit 1"] interval: 30s timeout: 5s retries: 3 # ==================== 数据卷 ==================== volumes: pgdata: tddata: redisdata: kafkadata: emqxdata: nacosdata: esdata: miniodata: geoserverdata: # ==================== 网络 ==================== networks: wm-network: driver: bridge name: wm-network