Docker 部署
从开发环境到生产环境的完整部署方案。
一、镜像概览
| 版本 | 镜像 | Registry |
|---|---|---|
| CE 开源版 | mingshang-iot/ce-backend mingshang-iot/ce-frontend | Docker Hub |
| PE 商业版 | registry.mingshang-iot.com/pe-backend | 私有 Registry |
| EE 集群版 | registry.mingshang-iot.com/ee-backend | 私有 Registry |
二、Docker Compose 单机部署
2.1 docker-compose.yml
yaml
version: "3.8"
services:
mysql:
image: mysql:8.0
restart: always
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_PASSWORD:-mingshang123}
MYSQL_DATABASE: mingshang
volumes:
- mysql-data:/var/lib/mysql
- ./backend/sql/ms-init.sql:/docker-entrypoint-initdb.d/init.sql
ports: ["3307:3306"]
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
redis:
image: redis:7-alpine
restart: always
command: redis-server --save 60 1 --loglevel warning
volumes: [redis-data:/data]
ports: ["6380:6379"]
emqx:
image: emqx:5.8
restart: always
environment:
EMQX_DASHBOARD__DEFAULT_USERNAME: admin
EMQX_DASHBOARD__DEFAULT_PASSWORD: ${EMQX_PASSWORD:-mingshang123}
volumes: [emqx-data:/opt/emqx/data]
ports:
- "1884:1883"
- "18084:18083"
tdengine:
image: tdengine/tdengine:3.5
restart: always
environment:
TAOS_FIRST_EP: fqdn_tdengine
volumes: [tdengine-data:/var/lib/taos]
ports: ["6042:6041"]
backend:
build:
context: .
dockerfile: deploy/docker/Dockerfile.backend
restart: always
depends_on: [mysql, redis, emqx, tdengine]
environment:
JAVA_OPTS: "-Xms512m -Xmx2g -XX:+UseG1GC"
SPRING_PROFILES_ACTIVE: prod
MYSQL_HOST: mysql
REDIS_HOST: redis
EMQX_HOST: emqx
MYSQL_PASSWORD: ${MYSQL_PASSWORD:-mingshang123}
ports: ["8080:8080"]
frontend:
build:
context: .
dockerfile: deploy/docker/Dockerfile.frontend
restart: always
depends_on: [backend]
ports: ["80:80"]
volumes:
mysql-data:
redis-data:
emqx-data:
tdengine-data:2.2 一键启动
bash
# CE 开源版
docker compose up -d
# PE 商业版(带 ZLMediaKit)
docker compose --profile pe up -d2.3 健康检查
bash
# 后端
curl http://localhost:8080/actuator/health
# → {"status":"UP"}
# 所有容器
docker ps
# → 6/6 运行中(PE 7/7)三、Dockerfile 说明
Backend(多阶段构建,~180MB)
dockerfile
FROM maven:3.9-eclipse-temurin-21 AS builder
WORKDIR /build
COPY backend/pom.xml .
COPY backend/ms-common ./ms-common
COPY backend/ms-server ./ms-server
COPY backend/ms-service ./ms-service
COPY backend/ms-plugins ./ms-plugins
COPY backend/ms-admin ./ms-admin
RUN mvn clean package -DskipTests -Pce
FROM eclipse-temurin:21-jre-alpine AS runtime
RUN adduser -D -g '' mingshang
USER mingshang
WORKDIR /app
ENV JAVA_OPTS="-Xms512m -Xmx2g -XX:+UseG1GC" \
SPRING_PROFILES_ACTIVE=prod \
MYSQL_HOST=mysql REDIS_HOST=redis EMQX_HOST=emqx
COPY --from=builder /build/ms-admin/target/mingshang-admin.jar /app/app.jar
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s --start-period=60s \
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/actuator/health || exit 1
ENTRYPOINT ["sh", "-c", "java ${JAVA_OPTS} -jar /app/app.jar"]Frontend(Nginx,~40MB)
dockerfile
FROM node:20-alpine AS builder
WORKDIR /build
COPY frontend/vue3-admin/package.json ./
RUN pnpm install
COPY frontend/vue3-admin/ ./
ENV VITE_APP_SERVER_API_URL=/api
RUN pnpm build
FROM nginx:1.27-alpine
COPY --from=builder /build/dist /usr/share/nginx/html
COPY deploy/nginx/default.conf /etc/nginx/conf.d/default.conf
EXPOSE 80Nginx 反代
nginx
server {
listen 80;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://backend:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /mqtt {
proxy_pass http://emqx:8083/mqtt;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
gzip on;
gzip_types text/plain application/javascript application/json text/css;
}四、Kubernetes Helm 部署
4.1 Helm Chart 结构
deploy/helm/mingshang-iot/
Chart.yaml
values.yaml
templates/
- backend-deployment.yaml
- frontend-deployment.yaml
- mysql-statefulset.yaml
- redis-statefulset.yaml
- emqx-statefulset.yaml
- tdengine-statefulset.yaml
- ingress.yaml
- secret.yaml4.2 安装
bash
helm install mingshang-iot deploy/helm/mingshang-iot \
--namespace iot \
--create-namespace \
-f values-prod.yaml4.3 values.yaml 关键配置
yaml
backend:
replicas: 3
resources:
requests: {cpu: "2", memory: "4Gi"}
limits: {cpu: "4", memory: "8Gi"}
env:
SPRING_PROFILES_ACTIVE: prod
MYSQL_HOST: mysql
MYSQL_PASSWORD: "changeme"
tdengine:
replicas: 3
storage: 500Gi
mysql:
replicas: 1
storage: 100Gi
backup:
enabled: true
cron: "0 2 * * *"
ingress:
enabled: true
host: api.mingshang-iot.com
tls: secretName=mingshang-tls五、资源配置参考
| 规模 | 设备数 | 后端实例 | TDengine | 最低配置 |
|---|---|---|---|---|
| Small | 1 万 | 2 | 单节点 | 8 核 16G |
| Medium | 10 万 | 3-5 | 3 节点集群 | 24 核 48G |
| Large | 50 万+ | 10+ | 6+ 节点 | 64 核 128G |
六、离线交付(内网环境)
bash
# 导出镜像
docker save -o mingshang-images.tar \
mingshang-iot/ce-backend:latest \
mingshang-iot/ce-frontend:latest \
mysql:8.0 redis:7-alpine emqx:5.8 tdengine/tdengine:3.5
# 在目标机器导入
docker load -i mingshang-images.tar
# 修改 docker-compose.yml 中 image 为本地 tag
# 然后 docker compose up -d