feat(docker): 删除docker的内容

This commit is contained in:
Join
2025-12-01 16:13:45 +08:00
parent b07c5c302a
commit 9c9a2b4a5f
13 changed files with 0 additions and 1147 deletions
-42
View File
@@ -1,42 +0,0 @@
# ================================
# 数据库配置 (MySQL 5.8 兼容)
# ================================
MYSQL_HOST=mysql
MYSQL_PORT=3306
MYSQL_DATABASE=univ
MYSQL_USERNAME=root
MYSQL_PASSWORD=Haha@2025
MYSQL_VERSION=5.8
# ================================
# Redis 配置
# ================================
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=Nexiot2025
REDIS_DATABASE=11
# ================================
# MQTT 配置
# ================================
MQTT_HOST=tcp://emqx:1883
MQTT_USERNAME=universal_iot
MQTT_PASSWORD=Abc@2025
MQTT_CLIENT_ID_PREFIX=univ_iot_docker
# ================================
# 应用配置
# ================================
SPRING_PROFILES_ACTIVE=docker
SERVER_PORT=8080
# ================================
# 端口映射 (可选,用于外部访问)
# ================================
BACKEND_PORT=8080
FRONTEND_PORT=80
MYSQL_EXTERNAL_PORT=3306
REDIS_EXTERNAL_PORT=6379
MQTT_EXTERNAL_PORT=1883
EMQX_DASHBOARD_PORT=18083
ADMINER_PORT=8081
-190
View File
@@ -1,190 +0,0 @@
# IoT 平台 Docker 部署
本文件夹包含 IoT 平台的所有 Docker 相关配置和脚本。
## 📁 文件结构
```
docker/
├── README.md # 本说明文档
├── docker-compose.yml # 完整服务编排 (MySQL + Redis + EMQX + 应用)
├── docker-compose.apps.yml # 仅应用服务编排
├── build-docker.sh # Docker 镜像构建脚本
├── start-docker.sh # 启动完整服务脚本
├── start-apps.sh # 启动应用服务脚本
├── env.example # 环境变量模板
├── mysql/ # MySQL 配置和初始化
│ ├── conf/ # MySQL 配置文件
│ │ └── my.cnf # MySQL 5.8 配置
│ └── init/ # 数据库初始化脚本
│ ├── 01-init.sql # 基础初始化
│ └── 02-iot.sql # IoT 平台数据表和数据
├── DOCKER_DEPLOYMENT.md # Docker 部署详细说明
├── DOCKER_TROUBLESHOOTING.md # 问题排查指南
├── DEPENDENCY_ANALYSIS.md # 依赖兼容性分析
└── DEPLOYMENT_SUMMARY.md # 部署总结和状态
```
## 🚀 快速开始
### 1. 构建镜像
```bash
# 进入 docker 目录
cd docker
# 构建默认版本 (推荐)
./build-docker.sh default local
# 构建其他版本
./build-docker.sh alpine # 后端 Alpine + 前端默认
./build-docker.sh corretto ubuntu # 后端 Corretto + 前端 Ubuntu
```
### 2. 启动服务
#### 方式一:仅启动应用服务 (当前推荐)
```bash
cd docker
./start-apps.sh
```
**访问地址:**
- 前端界面: http://localhost:80
- 后端 API: http://localhost:9092
#### 方式二:启动完整服务 (需要解决网络问题)
```bash
cd docker
./start-docker.sh
```
**包含服务:**
- MySQL 5.8 (端口 3306)
- Redis 7.x (端口 6379)
- EMQX 5.3 (端口 1883, 8083, 8084, 18083)
- 后端应用 (端口 9092)
- 前端应用 (端口 80)
## 🔧 构建选项
### 后端版本
- `default`: OpenJDK 21 (Oracle Linux) - 推荐
- `alpine`: OpenJDK 21 Alpine (镜像更小)
- `corretto`: Amazon Corretto 21 (企业级支持)
### 前端版本
- `default`: Alpine + nginx (网络问题)
- `ubuntu`: Ubuntu + nginx
- `centos`: CentOS + nginx
- `simple`: Python HTTP 服务器
- `local`: 基于本地镜像 + nginx - 推荐
## 📊 服务管理
### 查看服务状态
```bash
cd docker
# 应用服务
docker-compose -f docker-compose.apps.yml ps
# 完整服务
docker-compose ps
```
### 查看日志
```bash
cd docker
# 后端日志
docker-compose -f docker-compose.apps.yml logs backend
# 前端日志
docker-compose -f docker-compose.apps.yml logs frontend
# 实时日志
docker-compose -f docker-compose.apps.yml logs -f
```
### 停止服务
```bash
cd docker
# 应用服务
docker-compose -f docker-compose.apps.yml down
# 完整服务
docker-compose down
```
## 🌐 网络问题解决
如果遇到镜像拉取失败,请配置 Docker 镜像加速器:
```bash
# 创建 Docker 配置文件
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": [
"https://docker.mirrors.ustc.edu.cn",
"https://hub-mirror.c.163.com",
"https://mirror.baidubce.com"
]
}
EOF
# 重启 Docker 服务
sudo systemctl daemon-reload
sudo systemctl restart docker
```
## 📝 端口配置
- **前端**: 80 (HTTP)
- **后端**: 9092 (Spring Boot)
- **MySQL**: 3306
- **Redis**: 6379
- **EMQX**: 1883 (MQTT), 8083 (MQTT/SSL), 8084 (MQTT/WebSocket), 18083 (管理界面)
## 🗄️ 数据库初始化
MySQL 启动后会自动执行以下初始化脚本:
1. `01-init.sql`: 创建数据库、用户、设置字符集等
2. `02-iot.sql`: 创建 IoT 平台所需的所有表结构和初始数据
## ⚠️ 注意事项
1. **端口冲突**: 确保本地端口 80, 9092, 3306, 6379, 1883 等未被占用
2. **网络问题**: 如果无法拉取镜像,请使用 `./build-docker.sh default local` 构建
3. **数据持久化**: MySQL 和 Redis 数据会保存在 Docker volumes 中
4. **配置文件**: 可以通过修改 `mysql/conf/my.cnf` 调整 MySQL 配置
## 🔍 故障排查
如果遇到问题,请查看:
1. [DOCKER_TROUBLESHOOTING.md](./DOCKER_TROUBLESHOOTING.md) - 问题排查指南
2. [DEPLOYMENT_SUMMARY.md](./DEPLOYMENT_SUMMARY.md) - 部署状态和问题诊断
3. 容器日志: `docker-compose logs -f [service_name]`
## 📞 技术支持
如需帮助,请提供:
1. Docker 版本 (`docker --version`)
2. Docker Compose 版本 (`docker-compose --version`)
3. 操作系统信息
4. 错误日志
5. 网络环境信息
-67
View File
@@ -1,67 +0,0 @@
# 仅凭一个 docker-compose 文件运行(发布说明)
此说明指导你如何“脱离源码”,仅提供一个 `docker-compose.release.yml` 给他人即可运行整套服务。
## 核心思路
- 构建并推送后端、前端、(可选)自定义 MySQL 初始镜像到镜像仓库(Docker Hub/GHCR/私有仓库)。
- 在 `docker-compose.release.yml` 中引用这些镜像,不再使用 `build`,不挂载本地目录。
- 默认环境变量内嵌在 compose 中,拿到文件即可 `docker compose up -d`。
## 镜像准备
1. 后端镜像(示例)
```bash
# 在仓库根或 cn-universal-web 下完成打包
mvn -q -DskipTests -pl cn-universal-web package
# 构建镜像
cd cn-universal-web
docker build -t nexiot/cn-universal-backend:1.0.0 .
docker push nexiot/cn-universal-backend:1.0.0
```
2. 前端镜像(示例)
```bash
cd cn-universal-web-ui
npm ci && npm run build
docker build -t nexiot/cn-universal-frontend:1.0.0 .
docker push nexiot/cn-universal-frontend:1.0.0
```
3. MySQL 初始化镜像(可选)
- 若需自动初始化数据库(而不靠本地挂载),可构建自定义 MySQL 镜像,将 `docker/mysql/init` 下 SQL 复制到 `/docker-entrypoint-initdb.d`。
- 示例 Dockerfile:
```Dockerfile
FROM mysql:8.0
COPY init/ /docker-entrypoint-initdb.d/
```
- 构建与推送:
```bash
cd docker/mysql
docker build -t nexiot/cn-universal-mysql:8.0-inited .
docker push nexiot/cn-universal-mysql:8.0-inited
```
- 然后在 `docker-compose.release.yml` 中将 `MYSQL_IMAGE` 设置为该镜像。
## 运行(仅凭一个 compose 文件)
- 将 `docker/docker-compose.release.yml` 发给使用者或发布到文档中。
- 使用者只需执行:
```bash
docker compose -f docker-compose.release.yml up -d
```
- 访问:
- 前端:`http://localhost:80`
- 后端健康:`http://localhost:9092/actuator/health`
## 安全与源码泄漏
- 镜像中不包含源码:后端 Dockerfile 仅复制 `target/cn-universal-web/` 的打包产物;前端仅复制 `dist/` 与 `nginx.conf`。
- `.dockerignore` 已排除了 `src/`、`.git` 等,构建上下文不会带源码。
- 上传镜像到公开仓库不会泄漏源代码,只要遵循上述构建规范。
## 参数覆盖(可选)
- `docker-compose.release.yml` 使用了可覆盖的镜像和配置项,例如:
- `BACKEND_IMAGE`、`FRONTEND_IMAGE`、`MYSQL_IMAGE` 等镜像名
- `SPRING_DATASOURCE_*`、`REDIS_*`、`MQTT_*` 等配置
- 使用者可在运行前通过环境变量覆盖,不需要额外 `.env` 文件。
## 注意事项
- 如未采用自定义 MySQL 初始化镜像,请确认后端能自建库表(例如使用 Flyway/Liquibase)。否则首次启动需要手工导入初始化 SQL。
- 发布前建议在全新机器上用该 `docker-compose.release.yml` 做一次完整起跑验证,确保无本地路径依赖。
-124
View File
@@ -1,124 +0,0 @@
param(
[string]$Backend = "default",
[string]$Frontend = "default"
)
$ErrorActionPreference = "Stop"
Write-Host "🚀 开始构建 Docker 镜像 (JDK 21 + MySQL 5.8 + EMQX)..."
Write-Host ""
Write-Host "📋 支持的构建版本:"
Write-Host " 后端版本:"
Write-Host " .\build-docker.ps1 -Backend <default|alpine|corretto> -Frontend <default|ubuntu|centos|simple|local>"
Write-Host ""
Write-Host " 示例:"
Write-Host " .\build-docker.ps1"
Write-Host " .\build-docker.ps1 -Backend alpine"
Write-Host " .\build-docker.ps1 -Backend corretto -Frontend ubuntu"
Write-Host " .\build-docker.ps1 -Frontend simple"
Write-Host ""
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$RepoRoot = (Resolve-Path (Join-Path $ScriptDir "..")).Path
# .env
if (-not (Test-Path (Join-Path $ScriptDir ".env"))) {
Write-Host "📝 创建 .env 文件..."
Copy-Item (Join-Path $ScriptDir "env.example") (Join-Path $ScriptDir ".env") -Force
Write-Host "✅ .env 文件已创建,请根据需要修改配置"
}
# 构建后端(优先使用 tar.gz 产物)
if (-not (Test-Path (Join-Path $RepoRoot "cn-universal-web/target/cn-universal-web"))) {
$tarPath = Join-Path $RepoRoot "cn-universal-web/target/cn-universal-web.tar.gz"
if (Test-Path $tarPath) {
Write-Host "📦 检测到后端产物 cn-universal-web.tar.gz,正在解压..."
Push-Location (Join-Path $RepoRoot "cn-universal-web/target")
& tar -xzf cn-universal-web.tar.gz
Pop-Location
}
}
if (-not (Test-Path (Join-Path $RepoRoot "cn-universal-web/target/cn-universal-web"))) {
Write-Host "🔨 未发现后端构建目录,开始执行 Maven Reactor 构建..."
Push-Location $RepoRoot
& mvn -q -T 1C -DskipTests -pl cn-universal-web -am install
& mvn -q -DskipTests -pl cn-universal-web package
Pop-Location
}
# 构建前端
if (-not (Test-Path (Join-Path $RepoRoot "cn-universal-web-ui/dist"))) {
Write-Host "🔨 前端未构建,开始执行 NPM 构建..."
Push-Location (Join-Path $RepoRoot "cn-universal-web-ui")
& npm ci
& npm run build
Pop-Location
}
# 后端镜像
Write-Host "🔨 构建后端镜像..."
Push-Location (Join-Path $RepoRoot "cn-universal-web")
switch ($Backend) {
"alpine" {
Write-Host "📦 使用 Alpine 版本 (镜像更小)"
& docker build -f Dockerfile.alpine -t cn-universal-backend:alpine .
& docker tag cn-universal-backend:alpine cn-universal-backend:latest
}
"corretto" {
Write-Host "🏢 使用 Amazon Corretto 版本 (企业级支持)"
& docker build -f Dockerfile.amazoncorretto -t cn-universal-backend:corretto .
& docker tag cn-universal-backend:corretto cn-universal-backend:latest
}
Default {
Write-Host "📦 使用默认 OpenJDK 版本"
& docker build -t cn-universal-backend:latest .
}
}
Pop-Location
# 前端镜像
Write-Host "🔨 构建前端镜像..."
Push-Location (Join-Path $RepoRoot "cn-universal-web-ui")
switch ($Frontend) {
"ubuntu" {
Write-Host "🐧 使用 Ubuntu 版本"
& docker build -f Dockerfile.ubuntu -t cn-universal-frontend:ubuntu .
& docker tag cn-universal-frontend:ubuntu cn-universal-frontend:latest
}
"centos" {
Write-Host "🔴 使用 CentOS 版本"
& docker build -f Dockerfile.centos -t cn-universal-frontend:centos .
& docker tag cn-universal-frontend:centos cn-universal-frontend:latest
}
"simple" {
Write-Host "🐍 使用 Python 简单版本"
& docker build -f Dockerfile.simple -t cn-universal-frontend:simple .
& docker tag cn-universal-frontend:simple cn-universal-frontend:latest
}
"local" {
Write-Host "🏠 使用本地镜像版本"
& docker build -f Dockerfile.local -t cn-universal-frontend:local .
& docker tag cn-universal-frontend:local cn-universal-frontend:latest
}
Default {
Write-Host "📦 使用默认 Alpine 版本"
& docker build -t cn-universal-frontend:latest .
}
}
Pop-Location
Write-Host "✅ 镜像构建完成!"
Write-Host ""
Write-Host "📋 可用镜像:"
Write-Host " - cn-universal-backend:latest"
Write-Host " - cn-universal-frontend:latest"
Write-Host ""
Write-Host "🚀 启动服务:"
Write-Host " cd docker && docker-compose up -d"
Write-Host ""
Write-Host "📊 查看服务状态:"
Write-Host " cd docker && docker-compose ps"
Write-Host ""
Write-Host "🔍 查看日志:"
Write-Host " cd docker && docker-compose logs -f"
-132
View File
@@ -1,132 +0,0 @@
#!/bin/bash
set -e
echo "🚀 开始构建 Docker 镜像 (JDK 21 + MySQL 5.8 + EMQX)..."
echo ""
echo "📋 支持的构建版本:"
echo " 后端版本:"
echo " ./build-docker.sh [backend] [frontend]"
echo " backend: default/alpine/corretto"
echo " frontend: default/ubuntu/centos/simple/local"
echo ""
echo " 示例:"
echo " ./build-docker.sh # 默认版本"
echo " ./build-docker.sh alpine # 后端 Alpine + 前端默认"
echo " ./build-docker.sh corretto ubuntu # 后端 Corretto + 前端 Ubuntu"
echo " ./build-docker.sh default simple # 后端默认 + 前端 Python 简单版"
echo ""
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
echo "🛠 检查并构建前后端产物..."
# 优先使用已打包的 tar.gz 产物
if [ ! -d "${REPO_ROOT}/cn-universal-web/target/cn-universal-web" ] && [ -f "${REPO_ROOT}/cn-universal-web/target/cn-universal-web.tar.gz" ]; then
echo "📦 检测到后端产物 cn-universal-web.tar.gz,正在解压..."
(
cd "${REPO_ROOT}/cn-universal-web/target" && tar -xzf cn-universal-web.tar.gz
)
fi
if [ ! -d "${REPO_ROOT}/cn-universal-web/target/cn-universal-web" ]; then
echo "🔨 未发现后端构建目录,开始执行 Maven Reactor 构建..."
(
cd "${REPO_ROOT}"
mvn -q -T 1C -DskipTests -pl cn-universal-web -am install
mvn -q -DskipTests -pl cn-universal-web package
)
fi
# 确保 docker profile 配置文件存在于打包目录
if [ -d "${REPO_ROOT}/cn-universal-web/target/cn-universal-web/config" ] && [ -f "${REPO_ROOT}/cn-universal-web/src/main/resources/application-docker.properties" ]; then
cp "${REPO_ROOT}/cn-universal-web/src/main/resources/application-docker.properties" "${REPO_ROOT}/cn-universal-web/target/cn-universal-web/config/application-docker.properties"
fi
if [ ! -d "${REPO_ROOT}/cn-universal-web-ui/dist" ]; then
echo "🔨 前端未构建,开始执行 NPM 构建..."
(
cd "${REPO_ROOT}/cn-universal-web-ui"
npm ci
npm run build
)
fi
if [ ! -f "${SCRIPT_DIR}/.env" ]; then
echo "📝 创建 .env 文件..."
cp "${SCRIPT_DIR}/env.example" "${SCRIPT_DIR}/.env"
echo "✅ .env 文件已创建,请根据需要修改配置"
fi
echo "🔨 构建后端镜像..."
cd "${REPO_ROOT}/cn-universal-web"
# 选择 Dockerfile 版本
DOCKERFILE_VERSION=${1:-default}
case $DOCKERFILE_VERSION in
"alpine")
echo "📦 使用 Alpine 版本 (镜像更小)"
docker build -f Dockerfile.alpine -t cn-universal-backend:alpine .
docker tag cn-universal-backend:alpine cn-universal-backend:latest
;;
"corretto")
echo "🏢 使用 Amazon Corretto 版本 (企业级支持)"
docker build -f Dockerfile.amazoncorretto -t cn-universal-backend:corretto .
docker tag cn-universal-backend:corretto cn-universal-backend:latest
;;
*)
echo "📦 使用默认 OpenJDK 版本"
docker build -t cn-universal-backend:latest .
;;
esac
cd "${SCRIPT_DIR}"
echo "🔨 构建前端镜像..."
cd "${REPO_ROOT}/cn-universal-web-ui"
# 选择前端 Dockerfile 版本
FRONTEND_VERSION=${2:-default}
case $FRONTEND_VERSION in
"ubuntu")
echo "🐧 使用 Ubuntu 版本"
docker build -f Dockerfile.ubuntu -t cn-universal-frontend:ubuntu .
docker tag cn-universal-frontend:ubuntu cn-universal-frontend:latest
;;
"centos")
echo "🔴 使用 CentOS 版本"
docker build -f Dockerfile.centos -t cn-universal-frontend:centos .
docker tag cn-universal-frontend:centos cn-universal-frontend:latest
;;
"simple")
echo "🐍 使用 Python 简单版本"
docker build -f Dockerfile.simple -t cn-universal-frontend:simple .
docker tag cn-universal-frontend:simple cn-universal-frontend:latest
;;
"local")
echo "🏠 使用本地镜像版本"
docker build -f Dockerfile.local -t cn-universal-frontend:local .
docker tag cn-universal-frontend:local cn-universal-frontend:latest
;;
*)
echo "📦 使用默认 Alpine 版本"
docker build -t cn-universal-frontend:latest .
;;
esac
cd "${REPO_ROOT}"
echo "✅ 镜像构建完成!"
echo ""
echo "📋 可用镜像:"
echo " - cn-universal-backend:latest"
echo " - cn-universal-frontend:latest"
echo ""
echo "🚀 启动服务:"
echo " cd docker && docker-compose up -d"
echo ""
echo "📊 查看服务状态:"
echo " cd docker && docker-compose ps"
echo ""
echo "🔍 查看日志:"
echo " cd docker && docker-compose logs -f"
-147
View File
@@ -1,147 +0,0 @@
version: '3.8'
services:
backend:
image: ${BACKEND_IMAGE:-nexiot/cn-universal-backend:1.0.0}
container_name: cn-universal-backend
restart: unless-stopped
ports:
- "9092:9092"
environment:
- SPRING_DATASOURCE_URL=${SPRING_DATASOURCE_URL:-jdbc:mysql://mysql:3306/univ?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true}
- SPRING_DATASOURCE_USERNAME=${SPRING_DATASOURCE_USERNAME:-root}
- SPRING_DATASOURCE_PASSWORD=${SPRING_DATASOURCE_PASSWORD:-Haha@2025}
- SPRING_DATA_REDIS_HOST=${REDIS_HOST:-redis}
- SPRING_DATA_REDIS_PORT=${REDIS_PORT:-6379}
- SPRING_DATA_REDIS_PASSWORD=${REDIS_PASSWORD:-Nexiot2025}
- SPRING_DATA_REDIS_DATABASE=${REDIS_DATABASE:-11}
- MQTT_CFG_HOST=${MQTT_HOST:-tcp://emqx:1883}
- MQTT_CFG_CLIENT_USERNAME=${MQTT_USERNAME:-universal_iot}
- MQTT_CFG_CLIENT_PASSWORD=${MQTT_PASSWORD:-Abc@2025}
- MQTT_CFG_CLIENT_ID_PREFIX=${MQTT_CLIENT_ID_PREFIX:-univ_iot_docker}
- MQTT_CFG_HOST_OUT=${MQTT_HOST_OUT:-tcp://127.0.0.1:1883}
- MQTT_CFG_EMQX_HEADER_KEY=${EMQX_HEADER_KEY:-universal-emqx}
- MQTT_CFG_EMQX_HEADER_VALUE=${EMQX_HEADER_VALUE:-d41d8cd98f00b204e9800998ecf8427e}
- SPRING_PROFILES_ACTIVE=docker
- RUN_MODE=docker
- LOGGING_FILE_PATH=/app/logs
- LOGGING_FILE_NAME=/app/logs/cn-universal-web.log
- SERVER_PORT=9092
- SERVER_HTTP2_ENABLED=false
- JAVA_TOOL_OPTIONS=-Dio.netty.native.workdir=/app/logs
- TCP_PROTOCOL_ENABLED=false
- UDP_PROTOCOL_ENABLED=false
- CTAIOT_PROTOCOL_ENABLE=false
- ONENET_PROTOCOL_ENABLED=false
- IMOULIFE_PROTOCOL_ENABLED=false
- SHARD_LOG_ENABLE=true
- SPRING_APPLICATION_JSON={"server":{"port":9092},"management":{"endpoints":{"web":{"exposure":{"include":"health,info,metrics,prometheus"},"base-path":"/actuator"}}}},"shard":{"log":{"enable":true,"table":{"number":24},"virtual":{"number":8}},"logMeta":{"enable":true,"table":{"number":24},"virtual":{"number":8}}},"iot":{"register":{"auto":{"unionId":"auto_register","latitude":31.081598,"longitude":81.314141}}}}
depends_on:
- mysql
- redis
- emqx
networks:
- release-network
volumes:
- backend_logs:/app/logs
security_opt:
- no-new-privileges:true
read_only: true
tmpfs:
- /tmp
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
frontend:
image: ${FRONTEND_IMAGE:-nexiot/cn-universal-frontend:1.0.0}
container_name: cn-universal-frontend
restart: unless-stopped
ports:
- "80:80"
depends_on:
- backend
networks:
- release-network
security_opt:
- no-new-privileges:true
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
mysql:
image: ${MYSQL_IMAGE:-mysql:8.0}
container_name: cn-universal-mysql
restart: unless-stopped
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_PASSWORD:-Haha@2025}
- MYSQL_DATABASE=${MYSQL_DATABASE:-univ}
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
networks:
- release-network
command: --default-authentication-plugin=mysql_native_password --lower_case_table_names=1 --sql_mode=STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
redis:
image: ${REDIS_IMAGE:-redis:7-alpine}
container_name: cn-universal-redis
restart: unless-stopped
environment:
- REDIS_PASSWORD=${REDIS_PASSWORD:-Nexiot2025}
ports:
- "6379:6379"
volumes:
- redis_data:/data
networks:
- release-network
command: redis-server --requirepass ${REDIS_PASSWORD:-Nexiot2025}
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
emqx:
image: ${EMQX_IMAGE:-emqx/emqx:5.3}
container_name: cn-universal-emqx
restart: unless-stopped
environment:
- EMQX_NAME=emqx
- EMQX_HOST=localhost
ports:
- "1883:1883"
- "8083:8083"
- "8084:8084"
- "18083:18083"
volumes:
- emqx_data:/opt/emqx/data
- emqx_log:/opt/emqx/log
networks:
- release-network
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
volumes:
mysql_data:
redis_data:
emqx_data:
emqx_log:
backend_logs:
networks:
release-network:
driver: bridge
-169
View File
@@ -1,169 +0,0 @@
version: '3.8'
services:
# 后端服务
backend:
build:
context: ../cn-universal-web
dockerfile: Dockerfile
container_name: cn-universal-backend
restart: unless-stopped
ports:
- "9092:9092"
environment:
# 数据库配置 (MySQL 5.8 兼容)
- SPRING_DATASOURCE_URL=jdbc:mysql://${MYSQL_HOST:-mysql}:${MYSQL_PORT:-3306}/${MYSQL_DATABASE:-univ}?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false&allowPublicKeyRetrieval=true&nullCatalogMeansCurrent=true
- SPRING_DATASOURCE_USERNAME=${MYSQL_USERNAME:-root}
- SPRING_DATASOURCE_PASSWORD=${MYSQL_PASSWORD:-Haha@2025}
# Redis 配置
- SPRING_DATA_REDIS_HOST=${REDIS_HOST:-redis}
- SPRING_DATA_REDIS_PORT=${REDIS_PORT:-6379}
- SPRING_DATA_REDIS_PASSWORD=${REDIS_PASSWORD:-Nexiot2025}
- SPRING_DATA_REDIS_DATABASE=${REDIS_DATABASE:-11}
# MQTT 配置
- MQTT_CFG_HOST=${MQTT_HOST:-tcp://emqx:1883}
- MQTT_CFG_CLIENT_USERNAME=${MQTT_USERNAME:-universal_iot}
- MQTT_CFG_CLIENT_PASSWORD=${MQTT_PASSWORD:-Abc@2025}
- MQTT_CFG_CLIENT_ID_PREFIX=${MQTT_CLIENT_ID_PREFIX:-univ_iot_docker}
# 备用外网 MQTT Host(可选)
- MQTT_CFG_HOST_OUT=${MQTT_HOST_OUT:-tcp://127.0.0.1:1883}
# EMQX HTTP鉴权请求头(后端会校验)
- MQTT_CFG_EMQX_HEADER_KEY=${EMQX_HEADER_KEY:-universal-emqx}
- MQTT_CFG_EMQX_HEADER_VALUE=${EMQX_HEADER_VALUE:-d41d8cd98f00b204e9800998ecf8427e}
# 应用配置
- SPRING_PROFILES_ACTIVE=docker
- RUN_MODE=docker
- LOGGING_FILE_PATH=/app/logs
- SERVER_PORT=9092
- SERVER_HTTP2_ENABLED=false
- JAVA_TOOL_OPTIONS=-Dio.netty.native.workdir=/app/logs
# 启用数据库与 Redis 自动配置(由环境变量提供连接信息)
# 关闭外部协议模块,避免阻塞启动(Docker 内可按需开启)
- TCP_PROTOCOL_ENABLED=false
- UDP_PROTOCOL_ENABLED=false
- CTAIOT_PROTOCOL_ENABLE=false
- ONENET_PROTOCOL_ENABLED=false
- IMOULIFE_PROTOCOL_ENABLED=false
# 兼容未打包的 local profile 配置
- SHARD_LOG_ENABLE=true
- SHARD_LOGMETA_ENABLE=true
- SPRING_APPLICATION_JSON={"server":{"port":9092},"management":{"endpoints":{"web":{"exposure":{"include":"health,info,metrics,prometheus"},"base-path":"/actuator"}}}},"shard":{"log":{"enable":true,"table":{"number":24},"virtual":{"number":8}},"logMeta":{"enable":true,"table":{"number":24},"virtual":{"number":8}}},"iot":{"register":{"auto":{"unionId":"auto_register","latitude":31.081598,"longitude":81.314141}}}}
depends_on:
- mysql
- redis
- emqx
networks:
- iot-network
volumes:
- ./logs:/app/logs
security_opt:
- no-new-privileges:true
read_only: true
tmpfs:
- /tmp
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# 前端服务
frontend:
build:
context: ../cn-universal-web-ui
dockerfile: Dockerfile
container_name: cn-universal-frontend
restart: unless-stopped
ports:
- "80:80"
depends_on:
- backend
networks:
- iot-network
security_opt:
- no-new-privileges:true
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# MySQL 数据库 (5.8 兼容)
mysql:
image: mysql:8.0
container_name: cn-universal-mysql
restart: unless-stopped
environment:
- MYSQL_ROOT_PASSWORD=${MYSQL_PASSWORD:-Haha@2025}
- MYSQL_DATABASE=${MYSQL_DATABASE:-univ}
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
- ./mysql/init:/docker-entrypoint-initdb.d
- ./mysql/conf:/etc/mysql/conf.d
networks:
- iot-network
command: --default-authentication-plugin=mysql_native_password --lower_case_table_names=1 --sql_mode=STRICT_TRANS_TABLES,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# Redis 缓存
redis:
image: redis:7-alpine
container_name: cn-universal-redis
restart: unless-stopped
environment:
- REDIS_PASSWORD=${REDIS_PASSWORD:-Nexiot2025}
ports:
- "6379:6379"
volumes:
- redis_data:/data
networks:
- iot-network
command: redis-server --requirepass ${REDIS_PASSWORD:-Nexiot2025}
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# EMQX MQTT Broker
emqx:
image: emqx/emqx:5.3
container_name: cn-universal-emqx
restart: unless-stopped
environment:
- EMQX_NAME=emqx
- EMQX_HOST=localhost
ports:
- "1883:1883"
- "8083:8083"
- "8084:8084"
- "18083:18083"
volumes:
- emqx_data:/opt/emqx/data
- emqx_log:/opt/emqx/log
networks:
- iot-network
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
volumes:
mysql_data:
redis_data:
emqx_data:
emqx_log:
networks:
iot-network:
driver: bridge
-41
View File
@@ -1,41 +0,0 @@
# ================================
# 数据库配置 (MySQL 5.8 兼容)
# ================================
MYSQL_HOST=mysql
MYSQL_PORT=3306
MYSQL_DATABASE=univ
MYSQL_USERNAME=root
MYSQL_PASSWORD=Haha@2025
MYSQL_VERSION=5.8
# ================================
# Redis 配置
# ================================
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=Nexiot2025
REDIS_DATABASE=11
# ================================
# MQTT 配置
# ================================
MQTT_HOST=tcp://emqx:1883
MQTT_USERNAME=universal_iot
MQTT_PASSWORD=Abc@2025
MQTT_CLIENT_ID_PREFIX=univ_iot_docker
# ================================
# 应用配置
# ================================
SPRING_PROFILES_ACTIVE=docker
SERVER_PORT=8080
# ================================
# 端口映射 (可选,用于外部访问)
# ================================
BACKEND_PORT=8080
FRONTEND_PORT=80
MYSQL_EXTERNAL_PORT=3306
REDIS_EXTERNAL_PORT=6379
MQTT_EXTERNAL_PORT=1883
EMQX_DASHBOARD_PORT=18083
-7
View File
@@ -1,7 +0,0 @@
FROM mysql:8.0
# 复制初始化 SQL 文件到容器
COPY init/*.sql /docker-entrypoint-initdb.d/
# 设置权限
RUN chmod -R 755 /docker-entrypoint-initdb.d/
-25
View File
@@ -1,25 +0,0 @@
@echo off
chcp 65001 >nul
REM 构建 MySQL 镜像
echo 🔨 Building custom MySQL image with init data...
REM 设置镜像名称和版本
set IMAGE_NAME=nexiot/mysql
set IMAGE_TAG=8.0-init
REM 构建镜像
docker build -t %IMAGE_NAME%:%IMAGE_TAG% -f docker/mysql/Dockerfile docker/mysql/
REM 检查构建结果
if %errorlevel% equ 0 (
echo ✅ MySQL image built successfully: %IMAGE_NAME%:%IMAGE_TAG%
echo.
echo 📤 Push to registry:
echo docker push %IMAGE_NAME%:%IMAGE_TAG%
) else (
echo ❌ Build failed!
exit /b 1
)
pause
-22
View File
@@ -1,22 +0,0 @@
#!/bin/bash
# 构建 MySQL 镜像
echo "🔨 Building custom MySQL image with init data..."
# 设置镜像名称和版本
IMAGE_NAME="nexiot/mysql"
IMAGE_TAG="8.0-init"
# 构建镜像
docker build -t ${IMAGE_NAME}:${IMAGE_TAG} -f docker/mysql/Dockerfile docker/mysql/
# 检查构建结果
if [ $? -eq 0 ]; then
echo "✅ MySQL image built successfully: ${IMAGE_NAME}:${IMAGE_TAG}"
echo ""
echo "📤 Push to registry:"
echo " docker push ${IMAGE_NAME}:${IMAGE_TAG}"
else
echo "❌ Build failed!"
exit 1
fi
-80
View File
@@ -1,80 +0,0 @@
param()
$ErrorActionPreference = "Stop"
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$RepoRoot = (Resolve-Path (Join-Path $ScriptDir "..")).Path
Write-Host "🚀 启动 IoT 平台 Docker 服务..."
try { docker info | Out-Null } catch { Write-Host "❌ Docker 未运行,请先启动 Docker"; exit 1 }
$useDockerCompose = $false
try { docker compose version | Out-Null; $useDockerCompose = $true } catch { try { docker-compose version | Out-Null } catch { Write-Host "❌ Docker Compose 不可用,请检查安装"; exit 1 } }
New-Item -ItemType Directory -Force -Path (Join-Path $ScriptDir "logs") | Out-Null
New-Item -ItemType Directory -Force -Path (Join-Path $ScriptDir "mysql/conf") | Out-Null
New-Item -ItemType Directory -Force -Path (Join-Path $ScriptDir "mysql/init") | Out-Null
if (-not (Test-Path (Join-Path $ScriptDir ".env"))) { Copy-Item (Join-Path $ScriptDir "env.example") (Join-Path $ScriptDir ".env") -Force }
Write-Host "🛠 检查并构建前后端..."
if (-not (Test-Path (Join-Path $RepoRoot "cn-universal-web/target/cn-universal-web"))) {
$tarPath = Join-Path $RepoRoot "cn-universal-web/target/cn-universal-web.tar.gz"
if (Test-Path $tarPath) {
Write-Host "📦 检测到后端产物 cn-universal-web.tar.gz,正在解压..."
Push-Location (Join-Path $RepoRoot "cn-universal-web/target")
& tar -xzf cn-universal-web.tar.gz
Pop-Location
}
}
if (-not (Test-Path (Join-Path $RepoRoot "cn-universal-web/target/cn-universal-web"))) {
Write-Host "🔨 后端未构建,开始执行 Maven Reactor 构建..."
Push-Location $RepoRoot
& mvn -q -T 1C -DskipTests -pl cn-universal-web -am install
& mvn -q -DskipTests -pl cn-universal-web package
Pop-Location
}
if (-not (Test-Path (Join-Path $RepoRoot "cn-universal-web-ui/dist"))) {
Write-Host "🔨 前端未构建,开始执行 NPM 构建..."
Push-Location (Join-Path $RepoRoot "cn-universal-web-ui")
& npm ci
& npm run build
Pop-Location
}
Write-Host "🔧 构建镜像并启动服务..."
$skipFrontend = $false
try { docker pull nginx:alpine | Out-Null } catch { Write-Host "⚠️ 无法拉取 nginx:alpine,将仅启动后端与基础服务"; $skipFrontend = $true }
Push-Location $ScriptDir
if ($useDockerCompose) {
if ($skipFrontend) { docker compose up -d --build backend mysql redis emqx } else { docker compose up -d --build }
} else {
if ($skipFrontend) { docker-compose up -d --build backend mysql redis emqx } else { docker-compose up -d --build }
}
Pop-Location
Start-Sleep -Seconds 10
Write-Host "📊 服务状态:"
if ($useDockerCompose) { Push-Location $ScriptDir; docker compose ps; Pop-Location } else { Push-Location $ScriptDir; docker-compose ps; Pop-Location }
Write-Host ""
Write-Host "🌐 服务访问地址:"
Write-Host " 前端界面: http://localhost:80"
Write-Host " 后端 API: http://localhost:9092"
Write-Host " EMQX 管理: http://localhost:18083 (admin/public)"
if ($skipFrontend) { Write-Host "⚠️ 已跳过前端。后端接口: http://localhost:9092" }
Write-Host ""
Write-Host "📋 常用命令:"
Write-Host " 查看日志: (cd docker && docker compose logs -f) 或 docker-compose logs -f"
Write-Host " 停止服务: (cd docker && docker compose down) 或 docker-compose down"
Write-Host " 重启服务: (cd docker && docker compose restart) 或 docker-compose restart"
Write-Host " 查看状态: (cd docker && docker compose ps) 或 docker-compose ps"
Write-Host ""
Write-Host "✅ 服务启动完成!"
-101
View File
@@ -1,101 +0,0 @@
#!/bin/bash
# Docker 快速启动脚本
set -e
echo "🚀 启动 IoT 平台 Docker 服务..."
# 统一脚本路径与仓库根路径,保证任意位置执行都正确
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
# 检查 Docker 是否运行
if ! docker info > /dev/null 2>&1; then
echo "❌ Docker 未运行,请先启动 Docker"
exit 1
fi
# 检查 Docker Compose 是否可用
if ! docker-compose version > /dev/null 2>&1; then
echo "❌ Docker Compose 不可用,请检查安装"
exit 1
fi
# 创建必要的目录
echo "📁 创建必要的目录..."
mkdir -p "${SCRIPT_DIR}/logs"
mkdir -p "${SCRIPT_DIR}/mysql/conf" "${SCRIPT_DIR}/mysql/init"
# 检查配置文件
if [ ! -f "${SCRIPT_DIR}/.env" ]; then
echo "📝 创建 .env 文件..."
cp "${SCRIPT_DIR}/env.example" "${SCRIPT_DIR}/.env"
echo "✅ .env 文件已创建,请根据需要修改配置"
fi
# 自动构建(如未构建)
echo "🛠 检查并构建前后端..."
if [ ! -d "${REPO_ROOT}/cn-universal-web/target/cn-universal-web" ] && [ -f "${REPO_ROOT}/cn-universal-web/target/cn-universal-web.tar.gz" ]; then
echo "📦 检测到后端产物 cn-universal-web.tar.gz,正在解压..."
(
cd "${REPO_ROOT}/cn-universal-web/target" && tar -xzf cn-universal-web.tar.gz
)
fi
if [ ! -d "${REPO_ROOT}/cn-universal-web/target/cn-universal-web" ]; then
echo "🔨 后端未构建,开始执行 Maven Reactor 构建..."
(
cd "${REPO_ROOT}"
echo "📦 构建并安装依赖模块 (Reactor -am)..."
mvn -q -T 1C -DskipTests -pl cn-universal-web -am install
echo "📦 打包 cn-universal-web..."
mvn -q -DskipTests -pl cn-universal-web package
)
fi
# 构建前端(如未构建产物)
if [ ! -d "${REPO_ROOT}/cn-universal-web-ui/dist" ]; then
echo "🔨 前端未构建,开始执行 NPM 构建..."
(cd "${REPO_ROOT}/cn-universal-web-ui" && npm ci && npm run build)
fi
# 构建镜像并启动服务
echo "🔧 构建镜像并启动服务..."
SKIP_FRONTEND=0
if ! docker pull --quiet nginx:alpine >/dev/null 2>&1; then
echo "⚠️ 无法从 Docker Hub 拉取 nginx:alpine,前端镜像可能无法构建。将仅启动后端与基础服务。"
SKIP_FRONTEND=1
fi
if [ "$SKIP_FRONTEND" -eq 1 ]; then
(cd "${SCRIPT_DIR}" && docker-compose up -d --build backend mysql redis emqx)
else
(cd "${SCRIPT_DIR}" && docker-compose up -d --build)
fi
# 等待服务启动
echo "⏳ 等待服务启动..."
sleep 10
# 检查服务状态
echo "📊 服务状态:"
(cd "${SCRIPT_DIR}" && docker-compose ps)
# 显示访问信息
echo ""
echo "🌐 服务访问地址:"
echo " 前端界面: http://localhost:80"
echo " 后端 API: http://localhost:9092"
echo " EMQX 管理: http://localhost:18083 (admin/public)"
echo ""
echo "📋 常用命令:"
echo " 查看日志: (cd docker && docker-compose logs -f)"
echo " 停止服务: (cd docker && docker-compose down)"
echo " 重启服务: (cd docker && docker-compose restart)"
echo " 查看状态: (cd docker && docker-compose ps)"
if [ "$SKIP_FRONTEND" -eq 1 ]; then
echo "⚠️ 已跳过前端。原因:无法访问 Docker Hub。后端接口: http://localhost:9092"
fi
echo ""
echo "✅ 服务启动完成!"