diff --git a/docker/.env b/docker/.env deleted file mode 100644 index 75b67c2..0000000 --- a/docker/.env +++ /dev/null @@ -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 diff --git a/docker/README.md b/docker/README.md deleted file mode 100644 index 1477cbb..0000000 --- a/docker/README.md +++ /dev/null @@ -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. 网络环境信息 diff --git a/docker/RELEASE_DEPLOYMENT.md b/docker/RELEASE_DEPLOYMENT.md deleted file mode 100644 index b7baa09..0000000 --- a/docker/RELEASE_DEPLOYMENT.md +++ /dev/null @@ -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` 做一次完整起跑验证,确保无本地路径依赖。 \ No newline at end of file diff --git a/docker/build-docker.ps1 b/docker/build-docker.ps1 deleted file mode 100644 index 9069fbb..0000000 --- a/docker/build-docker.ps1 +++ /dev/null @@ -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 -Frontend " -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" diff --git a/docker/build-docker.sh b/docker/build-docker.sh deleted file mode 100755 index 7b6fbb6..0000000 --- a/docker/build-docker.sh +++ /dev/null @@ -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" diff --git a/docker/docker-compose.release.yml b/docker/docker-compose.release.yml deleted file mode 100644 index d52ec09..0000000 --- a/docker/docker-compose.release.yml +++ /dev/null @@ -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 \ No newline at end of file diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml deleted file mode 100644 index da0e54b..0000000 --- a/docker/docker-compose.yml +++ /dev/null @@ -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 diff --git a/docker/env.example b/docker/env.example deleted file mode 100644 index 5f80efa..0000000 --- a/docker/env.example +++ /dev/null @@ -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 diff --git a/docker/mysql/Dockerfile b/docker/mysql/Dockerfile deleted file mode 100644 index 66c1c93..0000000 --- a/docker/mysql/Dockerfile +++ /dev/null @@ -1,7 +0,0 @@ -FROM mysql:8.0 - -# 复制初始化 SQL 文件到容器 -COPY init/*.sql /docker-entrypoint-initdb.d/ - -# 设置权限 -RUN chmod -R 755 /docker-entrypoint-initdb.d/ diff --git a/docker/mysql/build-mysql.bat b/docker/mysql/build-mysql.bat deleted file mode 100644 index 5ee1266..0000000 --- a/docker/mysql/build-mysql.bat +++ /dev/null @@ -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 diff --git a/docker/mysql/build-mysql.sh b/docker/mysql/build-mysql.sh deleted file mode 100644 index e8b70ab..0000000 --- a/docker/mysql/build-mysql.sh +++ /dev/null @@ -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 diff --git a/docker/start-docker.ps1 b/docker/start-docker.ps1 deleted file mode 100644 index ce48492..0000000 --- a/docker/start-docker.ps1 +++ /dev/null @@ -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 "✅ 服务启动完成!" diff --git a/docker/start-docker.sh b/docker/start-docker.sh deleted file mode 100755 index 9326a13..0000000 --- a/docker/start-docker.sh +++ /dev/null @@ -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 "✅ 服务启动完成!"