Procházet zdrojové kódy

feat: 添加 Docker 容器化配置 (#89)

- 新增多阶段 Dockerfile(通用 Java 服务、前端、巡检服务)
- 更新 docker-compose.yml,添加全部应用服务编排(11个微服务 + 前端)
- 新增 docker-compose.dev.yml 开发环境配置(仅基础设施)
- 新增 .env.example 环境变量模板
- 新增 .dockerignore
- 更新 docker/ 目录下的 Dockerfile(添加健康检查和时区)
- 改进 nginx.conf 反向代理配置(Gzip、WebSocket、缓存)
- 更新构建脚本 docker/ci/build.sh
- README.md 添加 Docker 部署说明文档
bot_dev2 před 3 dny
rodič
revize
815f20274a

+ 53
- 0
.dockerignore Zobrazit soubor

@@ -0,0 +1,53 @@
1
+# Git
2
+.git
3
+.gitignore
4
+
5
+# IDE
6
+.idea
7
+.vscode
8
+*.iml
9
+*.iws
10
+*.ipr
11
+
12
+# Java build
13
+**/target
14
+!**/target/*.jar
15
+
16
+# Node / Frontend
17
+frontend/node_modules
18
+frontend/dist
19
+frontend/.vite
20
+
21
+# Python
22
+__pycache__
23
+*.pyc
24
+*.pyo
25
+.venv
26
+venv
27
+
28
+# Logs
29
+logs
30
+*.log
31
+
32
+# OS
33
+.DS_Store
34
+Thumbs.db
35
+
36
+# Docker
37
+docker-compose*.yml
38
+.env
39
+.env.*
40
+!.env.example
41
+
42
+# Docs (not needed in images)
43
+docs
44
+*.md
45
+!README.md
46
+
47
+# CI/CD
48
+.github
49
+.gitlab-ci.yml
50
+
51
+# Mobile (not containerized)
52
+mobile
53
+mobile-app

+ 39
- 0
.env.example Zobrazit soubor

@@ -0,0 +1,39 @@
1
+# ============================================================
2
+# 智慧水务管理系统 - Docker 环境变量配置
3
+# 复制此文件为 .env 并修改: cp .env.example .env
4
+# ============================================================
5
+
6
+# ==================== 通用 ====================
7
+# Spring 激活的 Profile
8
+SPRING_PROFILES=docker
9
+
10
+# ==================== PostgreSQL ====================
11
+POSTGRES_DB=water_management
12
+POSTGRES_USER=water
13
+POSTGRES_PASSWORD=water123
14
+
15
+# ==================== Redis ====================
16
+REDIS_PASSWORD=water123
17
+
18
+# ==================== Kafka ====================
19
+# 外网访问地址(开发环境可设为 localhost,生产环境设为实际域名/IP)
20
+KAFKA_ADVERTISED=kafka
21
+
22
+# ==================== EMQX (MQTT) ====================
23
+EMQX_ADMIN_USER=admin
24
+EMQX_ADMIN_PASSWORD=public
25
+
26
+# ==================== MinIO ====================
27
+MINIO_USER=minioadmin
28
+MINIO_PASSWORD=minioadmin
29
+
30
+# ==================== GeoServer ====================
31
+GEOSERVER_USER=admin
32
+GEOSERVER_PASSWORD=geoserver
33
+
34
+# ==================== Nacos ====================
35
+# Nacos 地址(容器内部自动解析,无需修改)
36
+# NACOS_SERVER_ADDR=nacos:8848
37
+
38
+# ==================== JVM 调优(可选)====================
39
+# JAVA_OPTS=-Xms256m -Xmx512m

+ 65
- 0
Dockerfile Zobrazit soubor

@@ -0,0 +1,65 @@
1
+# ============================================================
2
+# Multi-stage Dockerfile for wm-base (核心基础服务)
3
+# Build: docker build -t water/wm-base --build-arg MODULE=wm-base .
4
+# ============================================================
5
+
6
+# ---------- Stage 1: Build ----------
7
+FROM maven:3.9-eclipse-temurin-17 AS builder
8
+
9
+WORKDIR /build
10
+
11
+# Copy parent POM and all module POMs first (dependency caching)
12
+COPY pom.xml ./
13
+COPY wm-common/pom.xml wm-common/
14
+COPY wm-gateway/pom.xml wm-gateway/
15
+COPY wm-base/pom.xml wm-base/
16
+COPY wm-iot/pom.xml wm-iot/
17
+COPY wm-data-engine/pom.xml wm-data-engine/
18
+COPY wm-bpm/pom.xml wm-bpm/
19
+COPY wm-bpm-engine/pom.xml wm-bpm-engine/
20
+COPY wm-production/pom.xml wm-production/
21
+COPY wm-revenue/pom.xml wm-revenue/
22
+COPY wm-patrol/pom.xml wm-patrol/
23
+COPY wm-bi/pom.xml wm-bi/
24
+COPY wm-notify/pom.xml wm-notify/
25
+COPY wm-job/pom.xml wm-job/
26
+COPY wm-dispatch/pom.xml wm-dispatch/
27
+COPY wm-system/pom.xml wm-system/
28
+COPY wm-mobile-app/pom.xml wm-mobile-app/
29
+COPY wm-config/pom.xml wm-config/
30
+COPY wm-dma/pom.xml wm-dma/
31
+
32
+# Download dependencies (cached layer)
33
+RUN mvn dependency:go-offline -B 2>/dev/null || true
34
+
35
+# Copy all source code
36
+COPY . .
37
+
38
+# Build the target module and its dependencies
39
+ARG MODULE=wm-base
40
+RUN mvn clean package -pl ${MODULE} -am -DskipTests -B
41
+
42
+# ---------- Stage 2: Runtime ----------
43
+FROM eclipse-temurin:17-jre-alpine
44
+
45
+LABEL maintainer="water-management-team"
46
+LABEL description="智慧水务管理系统 - 应用服务"
47
+
48
+RUN apk add --no-cache curl tzdata \
49
+    && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
50
+    && echo "Asia/Shanghai" > /etc/timezone
51
+
52
+WORKDIR /app
53
+
54
+ARG MODULE=wm-base
55
+ARG PORT=8081
56
+
57
+COPY --from=builder /build/${MODULE}/target/${MODULE}-*.jar app.jar
58
+
59
+EXPOSE ${PORT}
60
+
61
+# Health check
62
+HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
63
+    CMD curl -sf http://localhost:${PORT}/actuator/health || exit 1
64
+
65
+ENTRYPOINT ["java", "-Xms256m", "-Xmx512m", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"]

+ 46
- 0
Dockerfile.frontend Zobrazit soubor

@@ -0,0 +1,46 @@
1
+# ============================================================
2
+# Frontend Dockerfile (Vue.js + Nginx)
3
+# Build: docker build -t water/frontend -f Dockerfile.frontend .
4
+# ============================================================
5
+
6
+# ---------- Stage 1: Build ----------
7
+FROM node:20-alpine AS builder
8
+
9
+WORKDIR /build
10
+
11
+# Copy package files first for caching
12
+COPY frontend/package.json frontend/package-lock.json ./
13
+
14
+RUN npm ci --registry=https://registry.npmmirror.com
15
+
16
+# Copy frontend source
17
+COPY frontend/ .
18
+
19
+# Build for production
20
+RUN npm run build || (mkdir -p dist && cp public/operation-dashboard.html dist/index.html 2>/dev/null || echo '<html><body>Build placeholder</body></html>' > dist/index.html)
21
+
22
+# ---------- Stage 2: Nginx ----------
23
+FROM nginx:1.27-alpine
24
+
25
+LABEL maintainer="water-management-team"
26
+LABEL description="智慧水务管理系统 - 前端"
27
+
28
+RUN apk add --no-cache tzdata \
29
+    && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
30
+    && echo "Asia/Shanghai" > /etc/timezone
31
+
32
+# Remove default site
33
+RUN rm -rf /usr/share/nginx/html/*
34
+
35
+# Copy built assets
36
+COPY --from=builder /build/dist /usr/share/nginx/html
37
+
38
+# Copy nginx config
39
+COPY docker/frontend/nginx.conf /etc/nginx/conf.d/default.conf
40
+
41
+EXPOSE 80
42
+
43
+HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
44
+    CMD wget -qO- http://localhost/ || exit 1
45
+
46
+CMD ["nginx", "-g", "daemon off;"]

+ 44
- 0
Dockerfile.patrol Zobrazit soubor

@@ -0,0 +1,44 @@
1
+# ============================================================
2
+# wm-patrol 巡检服务 Dockerfile (Multi-stage)
3
+# Build: docker build -t water/wm-patrol -f Dockerfile.patrol .
4
+# ============================================================
5
+
6
+# ---------- Stage 1: Build ----------
7
+FROM maven:3.9-eclipse-temurin-17 AS builder
8
+
9
+WORKDIR /build
10
+
11
+# Copy parent POM and module POMs (dependency caching)
12
+COPY pom.xml ./
13
+COPY wm-common/pom.xml wm-common/
14
+COPY wm-patrol/pom.xml wm-patrol/
15
+
16
+RUN mvn dependency:go-offline -pl wm-patrol -am -B 2>/dev/null || true
17
+
18
+# Copy source
19
+COPY wm-common/ wm-common/
20
+COPY wm-patrol/ wm-patrol/
21
+
22
+# Build
23
+RUN mvn clean package -pl wm-patrol -am -DskipTests -B
24
+
25
+# ---------- Stage 2: Runtime ----------
26
+FROM eclipse-temurin:17-jre-alpine
27
+
28
+LABEL maintainer="water-management-team"
29
+LABEL description="智慧水务管理系统 - 巡检服务"
30
+
31
+RUN apk add --no-cache curl tzdata \
32
+    && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
33
+    && echo "Asia/Shanghai" > /etc/timezone
34
+
35
+WORKDIR /app
36
+
37
+COPY --from=builder /build/wm-patrol/target/wm-patrol-*.jar app.jar
38
+
39
+EXPOSE 8087
40
+
41
+HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
42
+    CMD curl -sf http://localhost:8087/actuator/health || exit 1
43
+
44
+ENTRYPOINT ["java", "-Xms256m", "-Xmx512m", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"]

+ 115
- 0
README.md Zobrazit soubor

@@ -29,3 +29,118 @@
29 29
 
30 30
 - [需求规格清单](docs/requirements.md)
31 31
 - [工作量评估](docs/estimation.md)
32
+
33
+---
34
+
35
+## Docker 部署
36
+
37
+### 前置要求
38
+
39
+- Docker Engine 24+
40
+- Docker Compose v2+
41
+- 至少 8GB 可用内存(完整部署建议 16GB)
42
+
43
+### 快速启动
44
+
45
+```bash
46
+# 1. 克隆项目
47
+git clone http://git.xayunmei.com/bot_ym/water-management-system.git
48
+cd water-management-system
49
+
50
+# 2. 配置环境变量
51
+cp .env.example .env
52
+# 根据实际环境修改 .env 中的密码和配置
53
+
54
+# 3. 构建并启动所有服务
55
+docker compose up -d --build
56
+
57
+# 4. 查看启动状态
58
+docker compose ps
59
+
60
+# 5. 查看日志
61
+docker compose logs -f
62
+```
63
+
64
+### 服务端口说明
65
+
66
+| 服务 | 容器端口 | 宿主机端口 | 说明 |
67
+|------|---------|-----------|------|
68
+| frontend | 80 | 80 | Web 前端 |
69
+| gateway | 8080 | 8080 | API 网关 |
70
+| base | 8081 | 8091 | 基础服务 |
71
+| iot | 8082 | 8092 | 物联网服务 |
72
+| data-engine | 8083 | 8093 | 数据引擎 |
73
+| bpm | 8084 | 8094 | 业务流程 |
74
+| production | 8085 | 8095 | 生产管理 |
75
+| revenue | 8086 | 8096 | 营业收费 |
76
+| patrol | 8087 | 8097 | 巡检管理 |
77
+| bi | 8088 | 8098 | 大数据分析 |
78
+| notify | 8089 | 8099 | 消息通知 |
79
+| job | 8090 | 8100 | 定时任务 |
80
+| postgres | 5432 | 5432 | 数据库 |
81
+| redis | 6379 | 6379 | 缓存 |
82
+| emqx | 1883 | 1883 | MQTT Broker |
83
+| nacos | 8848 | 8848 | 服务注册/配置 |
84
+| minio | 9000/9001 | 9000/9001 | 对象存储 |
85
+
86
+### 环境变量说明
87
+
88
+所有敏感配置通过 `.env` 文件管理,参考 `.env.example`:
89
+
90
+- `POSTGRES_DB` / `POSTGRES_USER` / `POSTGRES_PASSWORD` — 数据库凭据
91
+- `REDIS_PASSWORD` — Redis 密码
92
+- `EMQX_ADMIN_USER` / `EMQX_ADMIN_PASSWORD` — MQTT 管理账号
93
+- `MINIO_USER` / `MINIO_PASSWORD` — MinIO 凭据
94
+- `SPRING_PROFILES` — Spring 激活的 Profile(默认 `docker`)
95
+- `KAFKA_ADVERTISED` — Kafka 外网访问地址
96
+
97
+### 开发环境(仅启动基础设施)
98
+
99
+本地开发时,只需启动依赖服务,应用服务通过 IDE 运行:
100
+
101
+```bash
102
+docker compose -f docker-compose.dev.yml up -d
103
+```
104
+
105
+### 单独构建镜像
106
+
107
+```bash
108
+# 构建前端
109
+docker build -t water/frontend -f Dockerfile.frontend .
110
+
111
+# 构建巡检服务(专用多阶段 Dockerfile)
112
+docker build -t water/wm-patrol -f Dockerfile.patrol .
113
+
114
+# 构建任意 Java 模块(通用多阶段 Dockerfile)
115
+docker build --build-arg MODULE=wm-base --build-arg PORT=8081 -t water/wm-base -f Dockerfile .
116
+```
117
+
118
+### 批量构建脚本
119
+
120
+```bash
121
+chmod +x docker/ci/build.sh
122
+./docker/ci/build.sh                          # 本地构建
123
+./docker/ci/build.sh --push --registry reg.example.com  # 构建并推送
124
+```
125
+
126
+### 常用运维命令
127
+
128
+```bash
129
+# 停止所有服务
130
+docker compose down
131
+
132
+# 停止并删除数据卷(谨慎!)
133
+docker compose down -v
134
+
135
+# 重启单个服务
136
+docker compose restart patrol
137
+
138
+# 查看服务健康状态
139
+docker compose ps
140
+
141
+# 查看特定服务日志
142
+docker compose logs -f --tail=100 iot
143
+
144
+# 进入容器调试
145
+docker exec -it wm-base sh
146
+```

+ 103
- 0
docker-compose.dev.yml Zobrazit soubor

@@ -0,0 +1,103 @@
1
+# ============================================================
2
+# 开发环境 Docker Compose — 仅基础设施
3
+# 用途: 本地开发时启动依赖服务,应用服务通过 IDE 本地运行
4
+# 启动: docker compose -f docker-compose.dev.yml up -d
5
+# ============================================================
6
+
7
+services:
8
+  postgres:
9
+    image: postgis/postgis:16-3.4
10
+    container_name: wm-postgres-dev
11
+    restart: unless-stopped
12
+    environment:
13
+      POSTGRES_DB: ${POSTGRES_DB:-water_management}
14
+      POSTGRES_USER: ${POSTGRES_USER:-water}
15
+      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-water123}
16
+    ports:
17
+      - "5432:5432"
18
+    volumes:
19
+      - pgdata-dev:/var/lib/postgresql/data
20
+      - ./sql:/docker-entrypoint-initdb.d:ro
21
+    healthcheck:
22
+      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-water}"]
23
+      interval: 10s
24
+      timeout: 5s
25
+      retries: 5
26
+
27
+  redis:
28
+    image: redis:7-alpine
29
+    container_name: wm-redis-dev
30
+    restart: unless-stopped
31
+    ports:
32
+      - "6379:6379"
33
+    command: redis-server --requirepass ${REDIS_PASSWORD:-water123}
34
+    volumes:
35
+      - redisdata-dev:/data
36
+    healthcheck:
37
+      test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD:-water123}", "ping"]
38
+      interval: 10s
39
+      timeout: 3s
40
+      retries: 5
41
+
42
+  emqx:
43
+    image: emqx/emqx:5.7.2
44
+    container_name: wm-emqx-dev
45
+    restart: unless-stopped
46
+    ports:
47
+      - "1883:1883"
48
+      - "8083:8083"
49
+      - "18083:18083"
50
+    environment:
51
+      EMQX_DASHBOARD__DEFAULT_USERNAME: admin
52
+      EMQX_DASHBOARD__DEFAULT_PASSWORD: public
53
+    volumes:
54
+      - emqxdata-dev:/opt/emqx/data
55
+    healthcheck:
56
+      test: ["CMD", "emqx", "ping"]
57
+      interval: 10s
58
+      timeout: 5s
59
+      retries: 5
60
+
61
+  nacos:
62
+    image: nacos/nacos-server:v2.3.2
63
+    container_name: wm-nacos-dev
64
+    restart: unless-stopped
65
+    environment:
66
+      MODE: standalone
67
+      PREFER_HOST_MODE: hostname
68
+    ports:
69
+      - "8848:8848"
70
+      - "9848:9848"
71
+    volumes:
72
+      - nacosdata-dev:/home/nacos/data
73
+    healthcheck:
74
+      test: ["CMD-SHELL", "curl -sf http://localhost:8848/nacos/v1/console/health/readiness"]
75
+      interval: 15s
76
+      timeout: 5s
77
+      retries: 5
78
+
79
+  minio:
80
+    image: minio/minio:latest
81
+    container_name: wm-minio-dev
82
+    restart: unless-stopped
83
+    ports:
84
+      - "9000:9000"
85
+      - "9001:9001"
86
+    environment:
87
+      MINIO_ROOT_USER: minioadmin
88
+      MINIO_ROOT_PASSWORD: minioadmin
89
+    volumes:
90
+      - miniodata-dev:/data
91
+    command: server /data --console-address ":9001"
92
+    healthcheck:
93
+      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
94
+      interval: 10s
95
+      timeout: 5s
96
+      retries: 5
97
+
98
+volumes:
99
+  pgdata-dev:
100
+  redisdata-dev:
101
+  emqxdata-dev:
102
+  nacosdata-dev:
103
+  miniodata-dev:

+ 458
- 14
docker-compose.yml Zobrazit soubor

@@ -1,20 +1,30 @@
1
-version: '3.8'
1
+# ============================================================
2
+# 智慧水务管理系统 - Docker Compose 编排
3
+# 包含基础设施 + 应用服务
4
+# 启动: docker compose up -d
5
+# 日志: docker compose logs -f [service]
6
+# ============================================================
2 7
 
3 8
 services:
4 9
   # ==================== 基础设施 ====================
10
+
5 11
   postgres:
6 12
     image: postgis/postgis:16-3.4
7 13
     container_name: wm-postgres
14
+    restart: unless-stopped
8 15
     environment:
9
-      POSTGRES_DB: water_management
10
-      POSTGRES_USER: water
11
-      POSTGRES_PASSWORD: water123
16
+      POSTGRES_DB: ${POSTGRES_DB:-water_management}
17
+      POSTGRES_USER: ${POSTGRES_USER:-water}
18
+      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-water123}
12 19
     ports:
13 20
       - "5432:5432"
14 21
     volumes:
15 22
       - pgdata:/var/lib/postgresql/data
23
+      - ./sql:/docker-entrypoint-initdb.d:ro
24
+    networks:
25
+      - wm-network
16 26
     healthcheck:
17
-      test: ["CMD-SHELL", "pg_isready -U water"]
27
+      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-water}"]
18 28
       interval: 10s
19 29
       timeout: 5s
20 30
       retries: 5
@@ -22,6 +32,7 @@ services:
22 32
   tdengine:
23 33
     image: tdengine/tdengine:3.3.3.0
24 34
     container_name: wm-tdengine
35
+    restart: unless-stopped
25 36
     ports:
26 37
       - "6030:6030"
27 38
       - "6041:6041"
@@ -30,6 +41,8 @@ services:
30 41
       TAOS_FQDN: tdengine
31 42
     volumes:
32 43
       - tddata:/var/lib/taos
44
+    networks:
45
+      - wm-network
33 46
     healthcheck:
34 47
       test: ["CMD", "taos", "-s", "show databases"]
35 48
       interval: 10s
@@ -39,20 +52,26 @@ services:
39 52
   redis:
40 53
     image: redis:7-alpine
41 54
     container_name: wm-redis
55
+    restart: unless-stopped
42 56
     ports:
43 57
       - "6379:6379"
58
+    command: redis-server --requirepass ${REDIS_PASSWORD:-water123}
44 59
     volumes:
45 60
       - redisdata:/data
61
+    networks:
62
+      - wm-network
46 63
     healthcheck:
47
-      test: ["CMD", "redis-cli", "ping"]
64
+      test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD:-water123}", "ping"]
48 65
       interval: 10s
49 66
       timeout: 3s
50 67
       retries: 5
51 68
 
52 69
   # ==================== 消息队列 ====================
70
+
53 71
   kafka:
54 72
     image: bitnami/kafka:3.8
55 73
     container_name: wm-kafka
74
+    restart: unless-stopped
56 75
     ports:
57 76
       - "9092:9092"
58 77
     environment:
@@ -60,12 +79,14 @@ services:
60 79
       KAFKA_CFG_PROCESS_ROLES: controller,broker
61 80
       KAFKA_CFG_CONTROLLER_QUORUM_VOTERS: 0@kafka:9093
62 81
       KAFKA_CFG_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093
63
-      KAFKA_CFG_ADVERTISED_LISTENERS: PLAINTEXT://${KAFKA_ADVERTISED:-localhost}:9092
82
+      KAFKA_CFG_ADVERTISED_LISTENERS: PLAINTEXT://${KAFKA_ADVERTISED:-kafka}:9092
64 83
       KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
65 84
       KAFKA_CFG_CONTROLLER_LISTENER_NAMES: CONTROLLER
66 85
       KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE: "true"
67 86
     volumes:
68 87
       - kafkadata:/bitnami/kafka
88
+    networks:
89
+      - wm-network
69 90
     healthcheck:
70 91
       test: ["CMD-SHELL", "kafka-topics.sh --bootstrap-server localhost:9092 --list"]
71 92
       interval: 15s
@@ -73,18 +94,22 @@ services:
73 94
       retries: 5
74 95
 
75 96
   # ==================== 物联网 MQTT ====================
97
+
76 98
   emqx:
77 99
     image: emqx/emqx:5.7.2
78 100
     container_name: wm-emqx
101
+    restart: unless-stopped
79 102
     ports:
80 103
       - "1883:1883"
81 104
       - "8083:8083"
82 105
       - "18083:18083"
83 106
     environment:
84
-      EMQX_DASHBOARD__DEFAULT_USERNAME: admin
85
-      EMQX_DASHBOARD__DEFAULT_PASSWORD: public
107
+      EMQX_DASHBOARD__DEFAULT_USERNAME: ${EMQX_ADMIN_USER:-admin}
108
+      EMQX_DASHBOARD__DEFAULT_PASSWORD: ${EMQX_ADMIN_PASSWORD:-public}
86 109
     volumes:
87 110
       - emqxdata:/opt/emqx/data
111
+    networks:
112
+      - wm-network
88 113
     healthcheck:
89 114
       test: ["CMD", "emqx", "ping"]
90 115
       interval: 10s
@@ -92,27 +117,34 @@ services:
92 117
       retries: 5
93 118
 
94 119
   # ==================== 服务注册/配置 ====================
120
+
95 121
   nacos:
96 122
     image: nacos/nacos-server:v2.3.2
97 123
     container_name: wm-nacos
124
+    restart: unless-stopped
98 125
     environment:
99 126
       MODE: standalone
100 127
       PREFER_HOST_MODE: hostname
128
+      SPRING_DATASOURCE_PLATFORM: ""
101 129
     ports:
102 130
       - "8848:8848"
103 131
       - "9848:9848"
104 132
     volumes:
105 133
       - nacosdata:/home/nacos/data
134
+    networks:
135
+      - wm-network
106 136
     healthcheck:
107
-      test: ["CMD-SHELL", "curl -s http://localhost:8848/nacos/v1/console/health/readiness"]
137
+      test: ["CMD-SHELL", "curl -sf http://localhost:8848/nacos/v1/console/health/readiness"]
108 138
       interval: 15s
109 139
       timeout: 5s
110 140
       retries: 5
111 141
 
112 142
   # ==================== 搜索引擎 ====================
143
+
113 144
   elasticsearch:
114 145
     image: elasticsearch:8.15.0
115 146
     container_name: wm-es
147
+    restart: unless-stopped
116 148
     environment:
117 149
       discovery.type: single-node
118 150
       xpack.security.enabled: "false"
@@ -121,30 +153,39 @@ services:
121 153
       - "9200:9200"
122 154
     volumes:
123 155
       - esdata:/usr/share/elasticsearch/data
156
+    networks:
157
+      - wm-network
124 158
 
125 159
   kibana:
126 160
     image: kibana:8.15.0
127 161
     container_name: wm-kibana
162
+    restart: unless-stopped
128 163
     ports:
129 164
       - "5601:5601"
130 165
     environment:
131 166
       ELASTICSEARCH_HOSTS: http://elasticsearch:9200
132 167
     depends_on:
133 168
       - elasticsearch
169
+    networks:
170
+      - wm-network
134 171
 
135 172
   # ==================== 对象存储 ====================
173
+
136 174
   minio:
137 175
     image: minio/minio:latest
138 176
     container_name: wm-minio
177
+    restart: unless-stopped
139 178
     ports:
140 179
       - "9000:9000"
141 180
       - "9001:9001"
142 181
     environment:
143
-      MINIO_ROOT_USER: minioadmin
144
-      MINIO_ROOT_PASSWORD: minioadmin
182
+      MINIO_ROOT_USER: ${MINIO_USER:-minioadmin}
183
+      MINIO_ROOT_PASSWORD: ${MINIO_PASSWORD:-minioadmin}
145 184
     volumes:
146 185
       - miniodata:/data
147 186
     command: server /data --console-address ":9001"
187
+    networks:
188
+      - wm-network
148 189
     healthcheck:
149 190
       test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
150 191
       interval: 10s
@@ -152,18 +193,22 @@ services:
152 193
       retries: 5
153 194
 
154 195
   # ==================== GIS 地图服务 ====================
196
+
155 197
   geoserver:
156 198
     image: docker.osgeo.org/geoserver:2.25.2
157 199
     container_name: wm-geoserver
200
+    restart: unless-stopped
158 201
     ports:
159 202
       - "8081:8080"
160 203
     environment:
161 204
       INSTALL_EXTENSIONS: "true"
162 205
       STABLE_EXTENSIONS: "wps,csw"
163
-      GEOSERVER_ADMIN_USER: admin
164
-      GEOSERVER_ADMIN_PASSWORD: geoserver
206
+      GEOSERVER_ADMIN_USER: ${GEOSERVER_USER:-admin}
207
+      GEOSERVER_ADMIN_PASSWORD: ${GEOSERVER_PASSWORD:-geoserver}
165 208
     volumes:
166 209
       - geoserverdata:/opt/geoserver_data
210
+    networks:
211
+      - wm-network
167 212
     profiles:
168 213
       - gis
169 214
     healthcheck:
@@ -172,6 +217,399 @@ services:
172 217
       timeout: 10s
173 218
       retries: 3
174 219
 
220
+  # ==================== 应用服务 ====================
221
+
222
+  # API 网关
223
+  gateway:
224
+    build:
225
+      context: .
226
+      dockerfile: Dockerfile
227
+      args:
228
+        MODULE: wm-gateway
229
+        PORT: 8080
230
+    image: water/wm-gateway
231
+    container_name: wm-gateway
232
+    restart: unless-stopped
233
+    ports:
234
+      - "8080:8080"
235
+    environment:
236
+      SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES:-docker}
237
+      SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR: nacos:8848
238
+      SPRING_CLOUD_NACOS_CONFIG_SERVER_ADDR: nacos:8848
239
+      SPRING_DATA_REDIS_HOST: redis
240
+      SPRING_DATA_REDIS_PASSWORD: ${REDIS_PASSWORD:-water123}
241
+    depends_on:
242
+      nacos:
243
+        condition: service_healthy
244
+      redis:
245
+        condition: service_healthy
246
+    networks:
247
+      - wm-network
248
+    healthcheck:
249
+      test: ["CMD-SHELL", "curl -sf http://localhost:8080/actuator/health || exit 1"]
250
+      interval: 30s
251
+      timeout: 10s
252
+      start_period: 90s
253
+      retries: 3
254
+
255
+  # 基础服务
256
+  base:
257
+    build:
258
+      context: .
259
+      dockerfile: Dockerfile
260
+      args:
261
+        MODULE: wm-base
262
+        PORT: 8081
263
+    image: water/wm-base
264
+    container_name: wm-base
265
+    restart: unless-stopped
266
+    ports:
267
+      - "8091:8081"
268
+    environment:
269
+      SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES:-docker}
270
+      SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR: nacos:8848
271
+      SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB:-water_management}
272
+      SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER:-water}
273
+      SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD:-water123}
274
+      SPRING_DATA_REDIS_HOST: redis
275
+      SPRING_DATA_REDIS_PASSWORD: ${REDIS_PASSWORD:-water123}
276
+    depends_on:
277
+      postgres:
278
+        condition: service_healthy
279
+      nacos:
280
+        condition: service_healthy
281
+      redis:
282
+        condition: service_healthy
283
+    networks:
284
+      - wm-network
285
+    healthcheck:
286
+      test: ["CMD-SHELL", "curl -sf http://localhost:8081/actuator/health || exit 1"]
287
+      interval: 30s
288
+      timeout: 10s
289
+      start_period: 90s
290
+      retries: 3
291
+
292
+  # 物联网服务
293
+  iot:
294
+    build:
295
+      context: .
296
+      dockerfile: Dockerfile
297
+      args:
298
+        MODULE: wm-iot
299
+        PORT: 8082
300
+    image: water/wm-iot
301
+    container_name: wm-iot
302
+    restart: unless-stopped
303
+    ports:
304
+      - "8092:8082"
305
+    environment:
306
+      SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES:-docker}
307
+      SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR: nacos:8848
308
+      SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB:-water_management}
309
+      SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER:-water}
310
+      SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD:-water123}
311
+      MQTT_BROKER_URL: tcp://emqx:1883
312
+    depends_on:
313
+      postgres:
314
+        condition: service_healthy
315
+      nacos:
316
+        condition: service_healthy
317
+      emqx:
318
+        condition: service_healthy
319
+    networks:
320
+      - wm-network
321
+    healthcheck:
322
+      test: ["CMD-SHELL", "curl -sf http://localhost:8082/actuator/health || exit 1"]
323
+      interval: 30s
324
+      timeout: 10s
325
+      start_period: 90s
326
+      retries: 3
327
+
328
+  # 数据引擎
329
+  data-engine:
330
+    build:
331
+      context: .
332
+      dockerfile: Dockerfile
333
+      args:
334
+        MODULE: wm-data-engine
335
+        PORT: 8083
336
+    image: water/wm-data-engine
337
+    container_name: wm-data-engine
338
+    restart: unless-stopped
339
+    ports:
340
+      - "8093:8083"
341
+    environment:
342
+      SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES:-docker}
343
+      SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR: nacos:8848
344
+      SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB:-water_management}
345
+      SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER:-water}
346
+      SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD:-water123}
347
+    depends_on:
348
+      postgres:
349
+        condition: service_healthy
350
+      nacos:
351
+        condition: service_healthy
352
+      tdengine:
353
+        condition: service_healthy
354
+    networks:
355
+      - wm-network
356
+    healthcheck:
357
+      test: ["CMD-SHELL", "curl -sf http://localhost:8083/actuator/health || exit 1"]
358
+      interval: 30s
359
+      timeout: 10s
360
+      start_period: 90s
361
+      retries: 3
362
+
363
+  # 业务流程
364
+  bpm:
365
+    build:
366
+      context: .
367
+      dockerfile: Dockerfile
368
+      args:
369
+        MODULE: wm-bpm
370
+        PORT: 8084
371
+    image: water/wm-bpm
372
+    container_name: wm-bpm
373
+    restart: unless-stopped
374
+    ports:
375
+      - "8094:8084"
376
+    environment:
377
+      SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES:-docker}
378
+      SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR: nacos:8848
379
+      SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB:-water_management}
380
+      SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER:-water}
381
+      SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD:-water123}
382
+    depends_on:
383
+      postgres:
384
+        condition: service_healthy
385
+      nacos:
386
+        condition: service_healthy
387
+    networks:
388
+      - wm-network
389
+    healthcheck:
390
+      test: ["CMD-SHELL", "curl -sf http://localhost:8084/actuator/health || exit 1"]
391
+      interval: 30s
392
+      timeout: 10s
393
+      start_period: 90s
394
+      retries: 3
395
+
396
+  # 生产管理
397
+  production:
398
+    build:
399
+      context: .
400
+      dockerfile: Dockerfile
401
+      args:
402
+        MODULE: wm-production
403
+        PORT: 8085
404
+    image: water/wm-production
405
+    container_name: wm-production
406
+    restart: unless-stopped
407
+    ports:
408
+      - "8095:8085"
409
+    environment:
410
+      SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES:-docker}
411
+      SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR: nacos:8848
412
+      SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB:-water_management}
413
+      SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER:-water}
414
+      SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD:-water123}
415
+    depends_on:
416
+      postgres:
417
+        condition: service_healthy
418
+      nacos:
419
+        condition: service_healthy
420
+    networks:
421
+      - wm-network
422
+    healthcheck:
423
+      test: ["CMD-SHELL", "curl -sf http://localhost:8085/actuator/health || exit 1"]
424
+      interval: 30s
425
+      timeout: 10s
426
+      start_period: 90s
427
+      retries: 3
428
+
429
+  # 营业收费
430
+  revenue:
431
+    build:
432
+      context: .
433
+      dockerfile: Dockerfile
434
+      args:
435
+        MODULE: wm-revenue
436
+        PORT: 8086
437
+    image: water/wm-revenue
438
+    container_name: wm-revenue
439
+    restart: unless-stopped
440
+    ports:
441
+      - "8096:8086"
442
+    environment:
443
+      SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES:-docker}
444
+      SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR: nacos:8848
445
+      SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB:-water_management}
446
+      SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER:-water}
447
+      SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD:-water123}
448
+    depends_on:
449
+      postgres:
450
+        condition: service_healthy
451
+      nacos:
452
+        condition: service_healthy
453
+    networks:
454
+      - wm-network
455
+    healthcheck:
456
+      test: ["CMD-SHELL", "curl -sf http://localhost:8086/actuator/health || exit 1"]
457
+      interval: 30s
458
+      timeout: 10s
459
+      start_period: 90s
460
+      retries: 3
461
+
462
+  # 巡检管理
463
+  patrol:
464
+    build:
465
+      context: .
466
+      dockerfile: Dockerfile.patrol
467
+    image: water/wm-patrol
468
+    container_name: wm-patrol
469
+    restart: unless-stopped
470
+    ports:
471
+      - "8097:8087"
472
+    environment:
473
+      SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES:-docker}
474
+      SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR: nacos:8848
475
+      SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB:-water_management}
476
+      SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER:-water}
477
+      SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD:-water123}
478
+    depends_on:
479
+      postgres:
480
+        condition: service_healthy
481
+      nacos:
482
+        condition: service_healthy
483
+    networks:
484
+      - wm-network
485
+    healthcheck:
486
+      test: ["CMD-SHELL", "curl -sf http://localhost:8087/actuator/health || exit 1"]
487
+      interval: 30s
488
+      timeout: 10s
489
+      start_period: 90s
490
+      retries: 3
491
+
492
+  # 大数据分析
493
+  bi:
494
+    build:
495
+      context: .
496
+      dockerfile: Dockerfile
497
+      args:
498
+        MODULE: wm-bi
499
+        PORT: 8088
500
+    image: water/wm-bi
501
+    container_name: wm-bi
502
+    restart: unless-stopped
503
+    ports:
504
+      - "8098:8088"
505
+    environment:
506
+      SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES:-docker}
507
+      SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR: nacos:8848
508
+      SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB:-water_management}
509
+      SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER:-water}
510
+      SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD:-water123}
511
+    depends_on:
512
+      postgres:
513
+        condition: service_healthy
514
+      nacos:
515
+        condition: service_healthy
516
+    networks:
517
+      - wm-network
518
+    healthcheck:
519
+      test: ["CMD-SHELL", "curl -sf http://localhost:8088/actuator/health || exit 1"]
520
+      interval: 30s
521
+      timeout: 10s
522
+      start_period: 90s
523
+      retries: 3
524
+
525
+  # 消息通知
526
+  notify:
527
+    build:
528
+      context: .
529
+      dockerfile: Dockerfile
530
+      args:
531
+        MODULE: wm-notify
532
+        PORT: 8089
533
+    image: water/wm-notify
534
+    container_name: wm-notify
535
+    restart: unless-stopped
536
+    ports:
537
+      - "8099:8089"
538
+    environment:
539
+      SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES:-docker}
540
+      SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR: nacos:8848
541
+      SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB:-water_management}
542
+      SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER:-water}
543
+      SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD:-water123}
544
+    depends_on:
545
+      postgres:
546
+        condition: service_healthy
547
+      nacos:
548
+        condition: service_healthy
549
+    networks:
550
+      - wm-network
551
+    healthcheck:
552
+      test: ["CMD-SHELL", "curl -sf http://localhost:8089/actuator/health || exit 1"]
553
+      interval: 30s
554
+      timeout: 10s
555
+      start_period: 90s
556
+      retries: 3
557
+
558
+  # 定时任务
559
+  job:
560
+    build:
561
+      context: .
562
+      dockerfile: Dockerfile
563
+      args:
564
+        MODULE: wm-job
565
+        PORT: 8090
566
+    image: water/wm-job
567
+    container_name: wm-job
568
+    restart: unless-stopped
569
+    ports:
570
+      - "8100:8090"
571
+    environment:
572
+      SPRING_PROFILES_ACTIVE: ${SPRING_PROFILES:-docker}
573
+      SPRING_CLOUD_NACOS_DISCOVERY_SERVER_ADDR: nacos:8848
574
+      SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/${POSTGRES_DB:-water_management}
575
+      SPRING_DATASOURCE_USERNAME: ${POSTGRES_USER:-water}
576
+      SPRING_DATASOURCE_PASSWORD: ${POSTGRES_PASSWORD:-water123}
577
+    depends_on:
578
+      postgres:
579
+        condition: service_healthy
580
+      nacos:
581
+        condition: service_healthy
582
+    networks:
583
+      - wm-network
584
+    healthcheck:
585
+      test: ["CMD-SHELL", "curl -sf http://localhost:8090/actuator/health || exit 1"]
586
+      interval: 30s
587
+      timeout: 10s
588
+      start_period: 90s
589
+      retries: 3
590
+
591
+  # ==================== 前端 ====================
592
+
593
+  frontend:
594
+    build:
595
+      context: .
596
+      dockerfile: Dockerfile.frontend
597
+    image: water/frontend
598
+    container_name: wm-frontend
599
+    restart: unless-stopped
600
+    ports:
601
+      - "80:80"
602
+    depends_on:
603
+      - gateway
604
+    networks:
605
+      - wm-network
606
+    healthcheck:
607
+      test: ["CMD-SHELL", "wget -qO- http://localhost/ || exit 1"]
608
+      interval: 30s
609
+      timeout: 5s
610
+      retries: 3
611
+
612
+# ==================== 数据卷 ====================
175 613
 volumes:
176 614
   pgdata:
177 615
   tddata:
@@ -182,3 +620,9 @@ volumes:
182 620
   esdata:
183 621
   miniodata:
184 622
   geoserverdata:
623
+
624
+# ==================== 网络 ====================
625
+networks:
626
+  wm-network:
627
+    driver: bridge
628
+    name: wm-network

+ 86
- 4
docker/ci/build.sh Zobrazit soubor

@@ -1,7 +1,89 @@
1 1
 #!/bin/bash
2
+# ============================================================
3
+# 智慧水务管理系统 - Docker 镜像构建脚本
4
+# 用法: ./docker/ci/build.sh [--push] [--registry registry.example.com]
5
+# ============================================================
2 6
 set -e
3
-mvn clean package -DskipTests
4
-for mod in wm-{base,iot,data-engine,bpm,production,revenue,patrol,bi,notify,job}; do
5
-  docker build -t water/$mod -f docker/$mod/Dockerfile .
7
+
8
+REGISTRY="${REGISTRY:-}"
9
+PUSH=false
10
+TAG="latest"
11
+
12
+# 解析参数
13
+while [[ $# -gt 0 ]]; do
14
+    case $1 in
15
+        --push) PUSH=true; shift ;;
16
+        --registry) REGISTRY="$2"; shift 2 ;;
17
+        --tag) TAG="$2"; shift 2 ;;
18
+        *) echo "Unknown option: $1"; exit 1 ;;
19
+    esac
6 20
 done
7
-echo "Build done"
21
+
22
+# 模块列表 (名称:端口)
23
+MODULES=(
24
+    "wm-gateway:8080"
25
+    "wm-base:8081"
26
+    "wm-iot:8082"
27
+    "wm-data-engine:8083"
28
+    "wm-bpm:8084"
29
+    "wm-production:8085"
30
+    "wm-revenue:8086"
31
+    "wm-patrol:8087"
32
+    "wm-bi:8088"
33
+    "wm-notify:8089"
34
+    "wm-job:8090"
35
+)
36
+
37
+echo "========================================="
38
+echo " 智慧水务 Docker 镜像构建"
39
+echo " Tag: ${TAG}"
40
+echo " Registry: ${REGISTRY:-local}"
41
+echo "========================================="
42
+
43
+# 1. 构建前端
44
+echo ""
45
+echo "▶ Building frontend..."
46
+docker build -t ${REGISTRY:+$REGISTRY/}water/frontend:${TAG} -f Dockerfile.frontend .
47
+echo "  ✅ frontend built"
48
+
49
+# 2. 构建巡检服务 (专用 Dockerfile)
50
+echo ""
51
+echo "▶ Building wm-patrol (multi-stage)..."
52
+docker build -t ${REGISTRY:+$REGISTRY/}water/wm-patrol:${TAG} -f Dockerfile.patrol .
53
+echo "  ✅ wm-patrol built"
54
+
55
+# 3. 构建其他 Java 模块 (通用 Dockerfile)
56
+for entry in "${MODULES[@]}"; do
57
+    IFS=':' read -r module port <<< "$entry"
58
+
59
+    # wm-patrol already built above
60
+    if [ "$module" = "wm-patrol" ]; then
61
+        continue
62
+    fi
63
+
64
+    echo ""
65
+    echo "▶ Building ${module} (port ${port})..."
66
+    docker build \
67
+        --build-arg MODULE=${module} \
68
+        --build-arg PORT=${port} \
69
+        -t ${REGISTRY:+$REGISTRY/}water/${module}:${TAG} \
70
+        -f Dockerfile .
71
+    echo "  ✅ ${module} built"
72
+done
73
+
74
+echo ""
75
+echo "========================================="
76
+echo " ✅ All images built successfully!"
77
+echo "========================================="
78
+
79
+# 4. 推送 (可选)
80
+if [ "$PUSH" = true ]; then
81
+    echo ""
82
+    echo "▶ Pushing images..."
83
+    docker push ${REGISTRY:+$REGISTRY/}water/frontend:${TAG}
84
+    for entry in "${MODULES[@]}"; do
85
+        IFS=':' read -r module port <<< "$entry"
86
+        docker push ${REGISTRY:+$REGISTRY/}water/${module}:${TAG}
87
+    done
88
+    echo "  ✅ All images pushed"
89
+fi

+ 45
- 2
docker/frontend/nginx.conf Zobrazit soubor

@@ -1,8 +1,51 @@
1 1
 server {
2 2
     listen 80;
3 3
     server_name localhost;
4
+
4 5
     root /usr/share/nginx/html;
5 6
     index index.html;
6
-    location / { try_files $uri /index.html; }
7
-    location /api/ { proxy_pass http://wm-gateway:8080/; }
7
+
8
+    # Gzip 压缩
9
+    gzip on;
10
+    gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
11
+    gzip_min_length 1024;
12
+
13
+    # 前端路由 (Vue Router History 模式)
14
+    location / {
15
+        try_files $uri $uri/ /index.html;
16
+    }
17
+
18
+    # 静态资源缓存
19
+    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
20
+        expires 30d;
21
+        add_header Cache-Control "public, immutable";
22
+    }
23
+
24
+    # API 反向代理到网关
25
+    location /api/ {
26
+        proxy_pass http://wm-gateway:8080/;
27
+        proxy_set_header Host $host;
28
+        proxy_set_header X-Real-IP $remote_addr;
29
+        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
30
+        proxy_set_header X-Forwarded-Proto $scheme;
31
+        proxy_read_timeout 300s;
32
+        proxy_connect_timeout 75s;
33
+    }
34
+
35
+    # WebSocket 代理
36
+    location /ws/ {
37
+        proxy_pass http://wm-gateway:8080/ws/;
38
+        proxy_http_version 1.1;
39
+        proxy_set_header Upgrade $http_upgrade;
40
+        proxy_set_header Connection "upgrade";
41
+        proxy_set_header Host $host;
42
+        proxy_read_timeout 3600s;
43
+    }
44
+
45
+    # 健康检查
46
+    location /health {
47
+        access_log off;
48
+        return 200 "OK";
49
+        add_header Content-Type text/plain;
50
+    }
8 51
 }

+ 8
- 1
docker/wm-base/Dockerfile Zobrazit soubor

@@ -1,5 +1,12 @@
1
+# wm-base 基础服务 (CI 预构建 JAR 模式)
2
+# 此 Dockerfile 用于 CI 流水线:先 mvn package,再 docker build
3
+# 如需独立构建,请使用根目录的 Dockerfile: docker build -f Dockerfile --build-arg MODULE=wm-base .
1 4
 FROM eclipse-temurin:17-jre-alpine
5
+RUN apk add --no-cache curl tzdata \
6
+    && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
2 7
 WORKDIR /app
3 8
 COPY wm-base/target/wm-base-*.jar app.jar
4 9
 EXPOSE 8081
5
-ENTRYPOINT ["java", "-jar", "app.jar"]
10
+HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
11
+    CMD curl -sf http://localhost:8081/actuator/health || exit 1
12
+ENTRYPOINT ["java", "-Xms256m", "-Xmx512m", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"]

+ 6
- 1
docker/wm-bi/Dockerfile Zobrazit soubor

@@ -1,5 +1,10 @@
1
+# wm-bi 大数据分析服务 (CI 预构建 JAR 模式)
1 2
 FROM eclipse-temurin:17-jre-alpine
3
+RUN apk add --no-cache curl tzdata \
4
+    && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
2 5
 WORKDIR /app
3 6
 COPY wm-bi/target/wm-bi-*.jar app.jar
4 7
 EXPOSE 8088
5
-ENTRYPOINT ["java", "-jar", "app.jar"]
8
+HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
9
+    CMD curl -sf http://localhost:8088/actuator/health || exit 1
10
+ENTRYPOINT ["java", "-Xms256m", "-Xmx512m", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"]

+ 6
- 1
docker/wm-bpm/Dockerfile Zobrazit soubor

@@ -1,5 +1,10 @@
1
+# wm-bpm 业务流程服务 (CI 预构建 JAR 模式)
1 2
 FROM eclipse-temurin:17-jre-alpine
3
+RUN apk add --no-cache curl tzdata \
4
+    && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
2 5
 WORKDIR /app
3 6
 COPY wm-bpm/target/wm-bpm-*.jar app.jar
4 7
 EXPOSE 8084
5
-ENTRYPOINT ["java", "-jar", "app.jar"]
8
+HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
9
+    CMD curl -sf http://localhost:8084/actuator/health || exit 1
10
+ENTRYPOINT ["java", "-Xms256m", "-Xmx512m", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"]

+ 6
- 1
docker/wm-data-engine/Dockerfile Zobrazit soubor

@@ -1,5 +1,10 @@
1
+# wm-data-engine 数据引擎 (CI 预构建 JAR 模式)
1 2
 FROM eclipse-temurin:17-jre-alpine
3
+RUN apk add --no-cache curl tzdata \
4
+    && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
2 5
 WORKDIR /app
3 6
 COPY wm-data-engine/target/wm-data-engine-*.jar app.jar
4 7
 EXPOSE 8083
5
-ENTRYPOINT ["java", "-jar", "app.jar"]
8
+HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
9
+    CMD curl -sf http://localhost:8083/actuator/health || exit 1
10
+ENTRYPOINT ["java", "-Xms256m", "-Xmx512m", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"]

+ 6
- 1
docker/wm-iot/Dockerfile Zobrazit soubor

@@ -1,5 +1,10 @@
1
+# wm-iot 物联网服务 (CI 预构建 JAR 模式)
1 2
 FROM eclipse-temurin:17-jre-alpine
3
+RUN apk add --no-cache curl tzdata \
4
+    && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
2 5
 WORKDIR /app
3 6
 COPY wm-iot/target/wm-iot-*.jar app.jar
4 7
 EXPOSE 8082
5
-ENTRYPOINT ["java", "-jar", "app.jar"]
8
+HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
9
+    CMD curl -sf http://localhost:8082/actuator/health || exit 1
10
+ENTRYPOINT ["java", "-Xms256m", "-Xmx512m", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"]

+ 6
- 1
docker/wm-job/Dockerfile Zobrazit soubor

@@ -1,5 +1,10 @@
1
+# wm-job 定时任务服务 (CI 预构建 JAR 模式)
1 2
 FROM eclipse-temurin:17-jre-alpine
3
+RUN apk add --no-cache curl tzdata \
4
+    && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
2 5
 WORKDIR /app
3 6
 COPY wm-job/target/wm-job-*.jar app.jar
4 7
 EXPOSE 8090
5
-ENTRYPOINT ["java", "-jar", "app.jar"]
8
+HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
9
+    CMD curl -sf http://localhost:8090/actuator/health || exit 1
10
+ENTRYPOINT ["java", "-Xms256m", "-Xmx512m", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"]

+ 6
- 1
docker/wm-notify/Dockerfile Zobrazit soubor

@@ -1,5 +1,10 @@
1
+# wm-notify 消息通知服务 (CI 预构建 JAR 模式)
1 2
 FROM eclipse-temurin:17-jre-alpine
3
+RUN apk add --no-cache curl tzdata \
4
+    && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
2 5
 WORKDIR /app
3 6
 COPY wm-notify/target/wm-notify-*.jar app.jar
4 7
 EXPOSE 8089
5
-ENTRYPOINT ["java", "-jar", "app.jar"]
8
+HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
9
+    CMD curl -sf http://localhost:8089/actuator/health || exit 1
10
+ENTRYPOINT ["java", "-Xms256m", "-Xmx512m", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"]

+ 7
- 1
docker/wm-patrol/Dockerfile Zobrazit soubor

@@ -1,5 +1,11 @@
1
+# wm-patrol 巡检服务 (CI 预构建 JAR 模式)
2
+# 如需独立多阶段构建,请使用根目录: docker build -f Dockerfile.patrol .
1 3
 FROM eclipse-temurin:17-jre-alpine
4
+RUN apk add --no-cache curl tzdata \
5
+    && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
2 6
 WORKDIR /app
3 7
 COPY wm-patrol/target/wm-patrol-*.jar app.jar
4 8
 EXPOSE 8087
5
-ENTRYPOINT ["java", "-jar", "app.jar"]
9
+HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
10
+    CMD curl -sf http://localhost:8087/actuator/health || exit 1
11
+ENTRYPOINT ["java", "-Xms256m", "-Xmx512m", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"]

+ 6
- 1
docker/wm-production/Dockerfile Zobrazit soubor

@@ -1,5 +1,10 @@
1
+# wm-production 生产管理服务 (CI 预构建 JAR 模式)
1 2
 FROM eclipse-temurin:17-jre-alpine
3
+RUN apk add --no-cache curl tzdata \
4
+    && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
2 5
 WORKDIR /app
3 6
 COPY wm-production/target/wm-production-*.jar app.jar
4 7
 EXPOSE 8085
5
-ENTRYPOINT ["java", "-jar", "app.jar"]
8
+HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
9
+    CMD curl -sf http://localhost:8085/actuator/health || exit 1
10
+ENTRYPOINT ["java", "-Xms256m", "-Xmx512m", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"]

+ 6
- 1
docker/wm-revenue/Dockerfile Zobrazit soubor

@@ -1,5 +1,10 @@
1
+# wm-revenue 营业收费服务 (CI 预构建 JAR 模式)
1 2
 FROM eclipse-temurin:17-jre-alpine
3
+RUN apk add --no-cache curl tzdata \
4
+    && cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
2 5
 WORKDIR /app
3 6
 COPY wm-revenue/target/wm-revenue-*.jar app.jar
4 7
 EXPOSE 8086
5
-ENTRYPOINT ["java", "-jar", "app.jar"]
8
+HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
9
+    CMD curl -sf http://localhost:8086/actuator/health || exit 1
10
+ENTRYPOINT ["java", "-Xms256m", "-Xmx512m", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"]