diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..8bf368b --- /dev/null +++ b/.dockerignore @@ -0,0 +1,41 @@ +# Git +.git +.gitignore + +# IDE +.idea +.vscode +*.iml +*.ipr +*.iws + +# Maven +target/ +!ruoyi-admin/target/*.jar + +# Logs +logs/ +*.log + +# Temp files +*.tmp +*.bak +*.swp +*~ + +# OS +.DS_Store +Thumbs.db + +# Docker +Dockerfile* +docker-compose* +.dockerignore + +# Documentation +*.md +doc/ + +# Frontend build (will be built in container) +ruoyi-ui/node_modules/ +ruoyi-ui/dist/ diff --git a/DOCKER_DEPLOY.md b/DOCKER_DEPLOY.md new file mode 100644 index 0000000..a71c200 --- /dev/null +++ b/DOCKER_DEPLOY.md @@ -0,0 +1,353 @@ +# 若依项目 Docker 部署指南 + +## 概述 + +本文档说明如何使用 Docker 和 Docker Compose 部署若依项目,并通过子路径 `/ashai-wecom-test` 访问。 + +## 前提条件 + +- Docker 已安装(版本 20.10+) +- Docker Compose 已安装(版本 1.29+) +- 服务器 80 端口已被占用,需要使用其他端口(如 8081) + +## 项目结构 + +``` +wecom-dashboards/ +├── Dockerfile.backend # 后端 Dockerfile +├── docker-compose.yml # Docker Compose 编排文件 +├── ruoyi-ui/ +│ ├── Dockerfile # 前端 Dockerfile +│ └── nginx.conf # Nginx 配置文件 +├── ruoyi-admin/ +│ └── src/main/resources/ +│ ├── application.yml # 后端主配置 +│ └── application-prod.yml # 生产环境配置 +└── sql/ # 数据库初始化脚本 +``` + +## 配置说明 + +### 1. 前端配置 + +前端已配置为使用子路径 `/ashai-wecom-test`: + +- **vue.config.js**: `publicPath` 设置为 `/ashai-wecom-test` +- **.env.production**: `VUE_APP_BASE_API` 设置为 `/prod-api` +- **nginx.conf**: 配置了子路径访问和 API 代理 + +### 2. 后端配置 + +后端配置支持环境变量注入: + +- **数据库连接**: 通过环境变量 `SPRING_DATASOURCE_URL`、`SPRING_DATASOURCE_USERNAME`、`SPRING_DATASOURCE_PASSWORD` +- **Redis 连接**: 通过环境变量 `SPRING_REDIS_HOST`、`SPRING_REDIS_PORT` +- **上传路径**: 使用 Docker 卷挂载 `/home/ruoyi/uploadPath` + +### 3. Docker Compose 配置 + +包含以下服务: + +- **mysql**: MySQL 5.7 数据库 +- **redis**: Redis 6 缓存 +- **backend**: Spring Boot 后端服务 +- **frontend**: Nginx 前端服务 + +## 部署步骤 + +### 步骤 1: 准备数据库脚本 + +确保 `sql/` 目录下有数据库初始化脚本: + +```bash +cd Ruoyi-Vue-2/wecom-dashboards +ls sql/ +# 应该包含: ry_20250522.sql, quartz.sql, schema.sql 等 +``` + +### 步骤 2: 修改配置(可选) + +如果需要修改数据库密码或其他配置,编辑 `docker-compose.yml`: + +```yaml +services: + mysql: + environment: + MYSQL_ROOT_PASSWORD: your_password # 修改数据库密码 + + backend: + environment: + SPRING_DATASOURCE_PASSWORD: your_password # 同步修改 +``` + +### 步骤 3: 构建和启动服务 + +```bash +# 进入项目目录 +cd Ruoyi-Vue-2/wecom-dashboards + +# 构建并启动所有服务 +docker-compose up -d --build + +# 查看服务状态 +docker-compose ps + +# 查看日志 +docker-compose logs -f +``` + +### 步骤 4: 等待服务启动 + +首次启动需要等待: + +1. MySQL 初始化数据库(约 1-2 分钟) +2. 后端服务启动(约 30 秒) +3. 前端服务启动(约 10 秒) + +查看后端日志确认启动成功: + +```bash +docker-compose logs -f backend +# 看到 "Started RuoYiApplication" 表示启动成功 +``` + +### 步骤 5: 访问应用 + +前端服务运行在 8081 端口,通过以下 URL 访问: + +``` +http://your-server-ip:8081/ashai-wecom-test +``` + +默认登录账号: +- 用户名: `admin` +- 密码: `admin123` + +## 集成到现有 Nginx + +如果你的服务器 80 端口已经有 Nginx 在运行,可以通过反向代理将请求转发到容器: + +### 方案 1: Nginx 反向代理(推荐) + +在你现有的 Nginx 配置中添加: + +```nginx +# /etc/nginx/conf.d/ruoyi.conf 或在主配置文件中添加 + +server { + listen 80; + server_name your-domain.com; # 替换为你的域名 + + # 其他现有配置... + + # 若依项目代理 + location /ashai-wecom-test { + proxy_pass http://localhost:8081/ashai-wecom-test; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_connect_timeout 600; + proxy_read_timeout 600; + } +} +``` + +重启 Nginx: + +```bash +nginx -t # 测试配置 +nginx -s reload # 重新加载配置 +``` + +现在可以通过以下 URL 访问: + +``` +http://your-domain.com/ashai-wecom-test +``` + +### 方案 2: 修改 Docker Compose 端口映射 + +如果不想使用反向代理,可以修改 `docker-compose.yml` 中的端口映射: + +```yaml +services: + frontend: + ports: + - "8081:80" # 改为其他未占用的端口 +``` + +## 常用命令 + +```bash +# 启动服务 +docker-compose up -d + +# 停止服务 +docker-compose down + +# 重启服务 +docker-compose restart + +# 查看日志 +docker-compose logs -f [service_name] + +# 进入容器 +docker-compose exec backend bash +docker-compose exec frontend sh + +# 重新构建并启动 +docker-compose up -d --build + +# 清理所有数据(包括数据库) +docker-compose down -v +``` + +## 数据持久化 + +Docker Compose 配置了以下数据卷: + +- `mysql-data`: MySQL 数据库文件 +- `redis-data`: Redis 持久化数据 +- `upload-data`: 文件上传目录 + +数据会持久化保存,即使容器重启也不会丢失。 + +## 备份和恢复 + +### 备份数据库 + +```bash +docker-compose exec mysql mysqldump -uroot -ppassword ruoyi > backup.sql +``` + +### 恢复数据库 + +```bash +docker-compose exec -T mysql mysql -uroot -ppassword ruoyi < backup.sql +``` + +### 备份上传文件 + +```bash +docker cp ruoyi-backend:/home/ruoyi/uploadPath ./uploadPath_backup +``` + +## 故障排查 + +### 1. 前端无法访问 + +检查前端容器日志: + +```bash +docker-compose logs frontend +``` + +确认 Nginx 配置正确: + +```bash +docker-compose exec frontend cat /etc/nginx/conf.d/default.conf +``` + +### 2. 后端无法连接数据库 + +检查后端日志: + +```bash +docker-compose logs backend +``` + +确认 MySQL 已启动: + +```bash +docker-compose ps mysql +``` + +进入 MySQL 容器检查: + +```bash +docker-compose exec mysql mysql -uroot -ppassword -e "SHOW DATABASES;" +``` + +### 3. API 请求失败 + +检查 Nginx 代理配置: + +```bash +docker-compose exec frontend cat /etc/nginx/conf.d/default.conf +``` + +确认后端服务可访问: + +```bash +curl http://localhost:8080/ +``` + +### 4. 前端静态资源 404 + +确认前端构建时 `publicPath` 配置正确: + +```bash +# 检查 vue.config.js +cat ruoyi-ui/vue.config.js | grep publicPath +``` + +确认 Nginx 中的文件路径: + +```bash +docker-compose exec frontend ls -la /usr/share/nginx/html/ashai-wecom-test +``` + +## 性能优化 + +### 1. 调整 JVM 参数 + +修改 `Dockerfile.backend`,在 `ENTRYPOINT` 中添加 JVM 参数: + +```dockerfile +ENTRYPOINT ["java", "-Xms512m", "-Xmx1024m", "-jar", "app.jar"] +``` + +### 2. 启用 Nginx Gzip + +前端 Dockerfile 已配置 gzip 压缩,确保 Nginx 配置中启用: + +```nginx +gzip on; +gzip_types text/plain text/css application/json application/javascript text/xml application/xml; +``` + +### 3. 调整数据库连接池 + +修改 `application-prod.yml` 中的 Druid 配置。 + +## 安全建议 + +1. **修改默认密码**: 修改 MySQL root 密码和应用管理员密码 +2. **配置 Redis 密码**: 在生产环境中为 Redis 设置密码 +3. **使用 HTTPS**: 配置 SSL 证书,使用 HTTPS 访问 +4. **限制端口访问**: 使用防火墙限制数据库和 Redis 端口的外部访问 +5. **定期备份**: 设置定时任务定期备份数据库和文件 + +## 更新部署 + +当代码更新后,重新部署: + +```bash +# 拉取最新代码 +git pull + +# 重新构建并启动 +docker-compose up -d --build + +# 查看日志确认启动成功 +docker-compose logs -f +``` + +## 联系支持 + +如有问题,请查看: + +- 若依官方文档: http://doc.ruoyi.vip +- Docker 官方文档: https://docs.docker.com +- 项目 README: ./README.md diff --git a/Dockerfile.backend b/Dockerfile.backend new file mode 100644 index 0000000..85828b6 --- /dev/null +++ b/Dockerfile.backend @@ -0,0 +1,35 @@ +# 后端 Dockerfile +FROM maven:3.8.5-openjdk-8 AS build + +# 设置工作目录 +WORKDIR /app + +# 复制 pom.xml 和源代码 +COPY pom.xml . +COPY ruoyi-admin ./ruoyi-admin +COPY ruoyi-common ./ruoyi-common +COPY ruoyi-framework ./ruoyi-framework +COPY ruoyi-generator ./ruoyi-generator +COPY ruoyi-quartz ./ruoyi-quartz +COPY ruoyi-system ./ruoyi-system +COPY excel-handle ./excel-handle + +# 构建项目 +RUN mvn clean package -DskipTests + +# 运行阶段 +FROM openjdk:8-jre-slim + +WORKDIR /app + +# 复制构建好的 jar 包 +COPY --from=build /app/ruoyi-admin/target/*.jar app.jar + +# 创建上传目录 +RUN mkdir -p /home/ruoyi/uploadPath + +# 暴露端口 +EXPOSE 8080 + +# 启动应用 +ENTRYPOINT ["java", "-jar", "app.jar"] diff --git a/deploy/CONFIG-FILE.md b/deploy/CONFIG-FILE.md new file mode 100644 index 0000000..234cc3c --- /dev/null +++ b/deploy/CONFIG-FILE.md @@ -0,0 +1,180 @@ +# 配置文件说明 + +## 外部配置文件方案 + +为了解决 Druid 配置无法通过环境变量覆盖的问题,我们使用外部配置文件方案。 + +## 文件结构 + +``` +deploy/backend/ +├── Dockerfile +├── entrypoint.sh +├── application-druid.yml # 外部配置文件 +└── ruoyi-admin.jar # 你的 jar 包 +``` + +## 配置文件说明 + +### application-druid.yml + +这个文件会覆盖 jar 包内的 `application-druid.yml` 配置。 + +**重要配置项**: + +```yaml +spring: + datasource: + druid: + master: + url: jdbc:mysql://host.docker.internal:3316/ry-vue?... + username: root + password: jiong1114 # 修改为你的密码 + + redis: + host: host.docker.internal + port: 6379 + password: # 如果有密码,填写这里 +``` + +### 修改配置 + +如果需要修改数据库连接信息,编辑 [application-druid.yml](backend/application-druid.yml): + +1. **数据库地址**: 修改 `master.url` +2. **数据库用户名**: 修改 `master.username` +3. **数据库密码**: 修改 `master.password` +4. **Redis 地址**: 修改 `redis.host` +5. **Redis 密码**: 修改 `redis.password` + +## 工作原理 + +Spring Boot 会按以下顺序加载配置(后面的会覆盖前面的): + +1. jar 包内的 `application.yml` +2. jar 包内的 `application-druid.yml` +3. jar 包外的 `application.yml`(如果存在) +4. jar 包外的 `application-druid.yml` ✅ **我们使用这个** + +## 重新部署 + +修改配置后,需要重新构建镜像: + +```bash +# 停止并删除旧容器 +docker stop wecom-backend +docker rm wecom-backend + +# 重新构建并启动 +cd deploy +docker compose up -d --build backend + +# 查看日志 +docker compose logs -f backend +``` + +## 不需要重新构建的方案 + +如果你想修改配置而不重新构建镜像,可以使用卷挂载: + +### 修改 docker-compose.yml + +```yaml +services: + backend: + volumes: + - upload_data:/home/ruoyi/uploadPath + - ./backend/application-druid.yml:/app/application-druid.yml # 挂载配置文件 +``` + +这样修改 `backend/application-druid.yml` 后,只需重启容器: + +```bash +docker compose restart backend +``` + +## 验证配置 + +### 1. 检查配置文件是否被复制 + +```bash +docker exec -it wecom-backend cat /app/application-druid.yml +``` + +### 2. 查看启动日志 + +```bash +docker compose logs backend | grep -i "datasource\|redis" +``` + +### 3. 测试数据库连接 + +```bash +# 进入容器 +docker exec -it wecom-backend sh + +# 测试 MySQL 连接(需要安装 telnet 或 nc) +nc -zv host.docker.internal 3316 + +# 测试 Redis 连接 +nc -zv host.docker.internal 6379 +``` + +## 常见问题 + +### 1. 配置文件没有生效 + +确认配置文件在正确的位置: +```bash +docker exec -it wecom-backend ls -la /app/ +``` + +应该看到 `application-druid.yml` 文件。 + +### 2. 数据库名称不匹配 + +确保 MySQL 中存在对应的数据库: +```bash +docker exec -it mysql-jijin-test mysql -uroot -pjiong1114 -e "SHOW DATABASES;" +``` + +如果没有 `ry-vue` 数据库,创建它: +```bash +docker exec -it mysql-jijin-test mysql -uroot -pjiong1114 -e "CREATE DATABASE IF NOT EXISTS \`ry-vue\` DEFAULT CHARACTER SET utf8mb4;" +``` + +### 3. 仍然报配置错误 + +检查 jar 包的 Spring Boot 版本和配置加载方式。某些版本可能需要使用 `--spring.config.location` 参数: + +修改 `entrypoint.sh`: +```bash +#!/bin/sh +exec java -Dspring.profiles.active=prod \ + --spring.config.location=classpath:/,file:/app/ \ + -jar app.jar +``` + +## 完整的部署流程 + +```bash +# 1. 准备文件 +deploy/backend/ +├── ruoyi-admin.jar # 你的 jar 包 +├── application-druid.yml # 已创建 +├── entrypoint.sh # 已创建 +└── Dockerfile # 已创建 + +# 2. 修改配置(如果需要) +vim deploy/backend/application-druid.yml + +# 3. 构建并启动 +cd deploy +docker compose up -d --build backend + +# 4. 查看日志 +docker compose logs -f backend + +# 5. 验证启动成功 +# 看到 "Started RuoYiApplication" 表示成功 +``` diff --git a/deploy/CONFIG.md b/deploy/CONFIG.md new file mode 100644 index 0000000..90dbe2e --- /dev/null +++ b/deploy/CONFIG.md @@ -0,0 +1,266 @@ +# 使用现有 MySQL 和 Redis 容器的配置说明 + +## 📋 当前配置 + +你的现有容器: +- **MySQL**: `mysql-jijin-test` (端口 3316) +- **Redis**: `redis` (端口 6379) + +## 🔧 配置步骤 + +### 1. 修改 docker-compose.yml + +已经配置为使用 `host.docker.internal` 连接宿主机的容器。 + +关键配置: +```yaml +environment: + # MySQL 连接(注意端口是 3316) + - SPRING_DATASOURCE_URL=jdbc:mysql://host.docker.internal:3316/ry-vue?... + - SPRING_DATASOURCE_USERNAME=root + - SPRING_DATASOURCE_PASSWORD=password # 修改为你的密码 + + # Redis 连接 + - SPRING_REDIS_HOST=host.docker.internal + - SPRING_REDIS_PORT=6379 + - SPRING_REDIS_PASSWORD= # 如果有密码,填写这里 + +extra_hosts: + - "host.docker.internal:host-gateway" # 允许容器访问宿主机 +``` + +### 2. 修改数据库配置 + +**重要**:请根据你的实际情况修改以下配置: + +#### 数据库名称 +默认使用 `ry-vue`,如果你的数据库名称不同,修改: +```yaml +SPRING_DATASOURCE_URL=jdbc:mysql://host.docker.internal:3316/你的数据库名?... +``` + +#### 数据库密码 +修改为你的 MySQL root 密码: +```yaml +SPRING_DATASOURCE_PASSWORD=你的密码 +``` + +#### Redis 密码 +如果你的 Redis 设置了密码,修改: +```yaml +SPRING_REDIS_PASSWORD=你的redis密码 +``` + +### 3. 准备数据库 + +在你的 MySQL 容器中创建数据库并导入数据: + +```bash +# 方式 1: 进入 MySQL 容器 +docker exec -it mysql-jijin-test mysql -uroot -p + +# 创建数据库 +CREATE DATABASE IF NOT EXISTS `ry-vue` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; + +# 退出 +exit + +# 方式 2: 导入 SQL 文件 +docker exec -i mysql-jijin-test mysql -uroot -p你的密码 ry-vue < /path/to/your.sql +``` + +### 4. 启动服务 + +```bash +cd deploy +docker-compose up -d +``` + +## 🔍 验证连接 + +### 检查后端日志 +```bash +docker-compose logs -f backend +``` + +如果看到类似以下内容,说明连接成功: +``` +Started RuoYiApplication in X seconds +``` + +### 测试数据库连接 +```bash +# 进入后端容器 +docker exec -it wecom-backend sh + +# 测试 MySQL 连接 +wget -O- http://host.docker.internal:3316 2>&1 | grep -i mysql + +# 测试 Redis 连接 +ping host.docker.internal +``` + +## 🐛 常见问题 + +### 1. 无法连接到 host.docker.internal + +**Windows/Mac**: `host.docker.internal` 自动可用 + +**Linux**: 需要手动添加,已在 docker-compose.yml 中配置: +```yaml +extra_hosts: + - "host.docker.internal:host-gateway" +``` + +### 2. 数据库连接被拒绝 + +检查 MySQL 容器是否允许远程连接: + +```bash +# 进入 MySQL 容器 +docker exec -it mysql-jijin-test mysql -uroot -p + +# 检查用户权限 +SELECT host, user FROM mysql.user WHERE user='root'; + +# 如果 host 只有 localhost,需要授权 +GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '你的密码'; +FLUSH PRIVILEGES; +``` + +### 3. 端口连接错误 + +确认你的 MySQL 端口是 3316: +```bash +docker ps | grep mysql +``` + +如果端口不同,修改 docker-compose.yml 中的端口号。 + +### 4. Redis 连接失败 + +检查 Redis 是否允许远程连接: + +```bash +# 查看 Redis 配置 +docker exec -it redis redis-cli CONFIG GET bind + +# 如果绑定了 127.0.0.1,需要修改为 0.0.0.0 +docker exec -it redis redis-cli CONFIG SET bind "0.0.0.0" +``` + +## 🔄 替代方案:使用 Docker 网络 + +如果 `host.docker.internal` 不工作,可以让新容器加入现有容器的网络: + +### 1. 查看现有容器的网络 +```bash +docker inspect mysql-jijin-test | grep NetworkMode +docker inspect redis | grep NetworkMode +``` + +### 2. 修改 docker-compose.yml + +假设现有容器在 `bridge` 网络: + +```yaml +services: + backend: + # ... 其他配置 + environment: + # 直接使用容器名连接 + - SPRING_DATASOURCE_URL=jdbc:mysql://mysql-jijin-test:3306/ry-vue?... + - SPRING_REDIS_HOST=redis + networks: + - default + +networks: + default: + external: true + name: bridge # 或者你的网络名称 +``` + +### 3. 或者创建自定义网络 + +```bash +# 创建网络 +docker network create my-network + +# 将现有容器连接到网络 +docker network connect my-network mysql-jijin-test +docker network connect my-network redis + +# 修改 docker-compose.yml +networks: + wecom-network: + external: true + name: my-network +``` + +## 📝 完整配置示例 + +### docker-compose.yml(使用 host.docker.internal) + +```yaml +version: '3.8' + +services: + backend: + build: + context: ./backend + dockerfile: Dockerfile + container_name: wecom-backend + restart: always + ports: + - "8080:8080" + volumes: + - upload_data:/home/ruoyi/uploadPath + environment: + - SPRING_PROFILES_ACTIVE=prod + - TZ=Asia/Shanghai + - SPRING_DATASOURCE_URL=jdbc:mysql://host.docker.internal:3316/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + - SPRING_DATASOURCE_USERNAME=root + - SPRING_DATASOURCE_PASSWORD=your_password + - SPRING_REDIS_HOST=host.docker.internal + - SPRING_REDIS_PORT=6379 + - SPRING_REDIS_PASSWORD= + extra_hosts: + - "host.docker.internal:host-gateway" + networks: + - wecom-network + + frontend: + build: + context: ./frontend + dockerfile: Dockerfile + container_name: wecom-frontend + restart: always + ports: + - "8081:80" + depends_on: + - backend + networks: + - wecom-network + +volumes: + upload_data: + driver: local + +networks: + wecom-network: + driver: bridge +``` + +## 🎯 快速检查清单 + +- [ ] 修改了 MySQL 密码配置 +- [ ] 修改了数据库名称(如果不是 ry-vue) +- [ ] 修改了 Redis 密码(如果有) +- [ ] 确认 MySQL 端口是 3316 +- [ ] 确认 Redis 端口是 6379 +- [ ] 在 MySQL 中创建了数据库 +- [ ] 导入了数据库初始化脚本 +- [ ] MySQL 允许远程连接 +- [ ] Redis 允许远程连接 + +完成以上检查后,运行 `docker-compose up -d` 即可启动服务。 diff --git a/deploy/DOCKER-IMAGE-FIX.md b/deploy/DOCKER-IMAGE-FIX.md new file mode 100644 index 0000000..fe59aa6 --- /dev/null +++ b/deploy/DOCKER-IMAGE-FIX.md @@ -0,0 +1,85 @@ +# Docker 镜像问题说明 + +## 问题原因 + +`openjdk:8-jre-alpine` 镜像已被弃用,无法从 Docker Hub 拉取。 + +## 解决方案 + +已将 Dockerfile 中的基础镜像更改为 `eclipse-temurin:8-jre-alpine`。 + +### Eclipse Temurin 是什么? + +- Eclipse Temurin 是 OpenJDK 的官方继任者 +- 由 Eclipse Adoptium 项目维护 +- 完全兼容 OpenJDK +- 持续更新和维护 + +## 其他可用的 Java 8 镜像 + +如果 `eclipse-temurin:8-jre-alpine` 也无法拉取,可以尝试以下替代方案: + +### 1. Amazon Corretto(推荐) +```dockerfile +FROM amazoncorretto:8-alpine-jre +``` + +### 2. Eclipse Temurin(非 Alpine) +```dockerfile +FROM eclipse-temurin:8-jre +``` +注意:体积较大(约 200MB vs 85MB) + +### 3. Azul Zulu +```dockerfile +FROM azul/zulu-openjdk-alpine:8-jre +``` + +### 4. 使用国内镜像加速 + +如果网络问题导致拉取失败,可以配置 Docker 镜像加速器: + +#### 阿里云镜像加速 +```json +{ + "registry-mirrors": [ + "https://docker.m.daocloud.io", + "https://registry.docker-cn.com", + "https://docker.mirrors.ustc.edu.cn" + ] +} +``` + +配置位置: +- **Windows**: Docker Desktop -> Settings -> Docker Engine +- **Linux**: `/etc/docker/daemon.json` + +配置后重启 Docker: +```bash +# Linux +sudo systemctl restart docker + +# Windows +重启 Docker Desktop +``` + +## 当前配置 + +已修改 [backend/Dockerfile](backend/Dockerfile) 使用: +```dockerfile +FROM eclipse-temurin:8-jre-alpine +``` + +现在可以重新尝试构建: +```bash +docker compose up -d +``` + +## 如果仍然失败 + +1. 检查网络连接 +2. 配置镜像加速器 +3. 或者使用非 Alpine 版本(体积更大但更稳定): + ```dockerfile + FROM eclipse-temurin:8-jre + ``` diff --git a/deploy/NO-COMPOSE.md b/deploy/NO-COMPOSE.md new file mode 100644 index 0000000..0350e75 --- /dev/null +++ b/deploy/NO-COMPOSE.md @@ -0,0 +1,204 @@ +# 不使用 docker-compose 的部署方案 + +如果你没有安装 docker-compose,可以使用以下两种方式: + +## 方式 1: 使用 Docker Compose V2(推荐) + +Docker Desktop 和新版 Docker 已经内置了 Compose V2,命令是 `docker compose`(注意是空格,不是连字符)。 + +### 测试是否可用 +```bash +docker compose version +``` + +如果可用,只需将所有 `docker-compose` 命令改为 `docker compose`: + +```bash +# 启动服务 +docker compose up -d + +# 查看日志 +docker compose logs -f + +# 停止服务 +docker compose down +``` + +## 方式 2: 使用纯 Docker 命令 + +如果 `docker compose` 也不可用,可以使用纯 Docker 命令手动启动容器。 + +### 1. 创建网络 +```bash +docker network create wecom-network +``` + +### 2. 构建镜像 + +#### 构建后端镜像 +```bash +cd deploy/backend +docker build -t wecom-backend:latest . +cd ../.. +``` + +#### 构建前端镜像 +```bash +cd deploy/frontend +docker build -t wecom-frontend:latest . +cd ../.. +``` + +### 3. 启动容器 + +#### 启动后端容器 +```bash +docker run -d \ + --name wecom-backend \ + --restart always \ + --network wecom-network \ + -p 8080:8080 \ + -v wecom-upload-data:/home/ruoyi/uploadPath \ + -e SPRING_PROFILES_ACTIVE=prod \ + -e TZ=Asia/Shanghai \ + -e SPRING_DATASOURCE_URL="jdbc:mysql://host.docker.internal:3316/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8" \ + -e SPRING_DATASOURCE_USERNAME=root \ + -e SPRING_DATASOURCE_PASSWORD=你的MySQL密码 \ + -e SPRING_REDIS_HOST=host.docker.internal \ + -e SPRING_REDIS_PORT=6379 \ + -e SPRING_REDIS_PASSWORD= \ + --add-host host.docker.internal:host-gateway \ + wecom-backend:latest +``` + +#### 启动前端容器 +```bash +docker run -d \ + --name wecom-frontend \ + --restart always \ + --network wecom-network \ + -p 8081:80 \ + wecom-frontend:latest +``` + +### 4. 常用管理命令 + +```bash +# 查看运行中的容器 +docker ps + +# 查看所有容器(包括停止的) +docker ps -a + +# 查看后端日志 +docker logs -f wecom-backend + +# 查看前端日志 +docker logs -f wecom-frontend + +# 停止容器 +docker stop wecom-backend wecom-frontend + +# 启动容器 +docker start wecom-backend wecom-frontend + +# 重启容器 +docker restart wecom-backend wecom-frontend + +# 删除容器 +docker rm -f wecom-backend wecom-frontend + +# 删除网络 +docker network rm wecom-network + +# 删除数据卷 +docker volume rm wecom-upload-data +``` + +### 5. 更新部署 + +#### 更新后端 +```bash +# 停止并删除旧容器 +docker stop wecom-backend +docker rm wecom-backend + +# 重新构建镜像 +cd deploy/backend +docker build -t wecom-backend:latest . +cd ../.. + +# 启动新容器(使用上面的 docker run 命令) +docker run -d \ + --name wecom-backend \ + --restart always \ + --network wecom-network \ + -p 8080:8080 \ + -v wecom-upload-data:/home/ruoyi/uploadPath \ + -e SPRING_PROFILES_ACTIVE=prod \ + -e TZ=Asia/Shanghai \ + -e SPRING_DATASOURCE_URL="jdbc:mysql://host.docker.internal:3316/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8" \ + -e SPRING_DATASOURCE_USERNAME=root \ + -e SPRING_DATASOURCE_PASSWORD=你的MySQL密码 \ + -e SPRING_REDIS_HOST=host.docker.internal \ + -e SPRING_REDIS_PORT=6379 \ + -e SPRING_REDIS_PASSWORD= \ + --add-host host.docker.internal:host-gateway \ + wecom-backend:latest +``` + +#### 更新前端 +```bash +# 停止并删除旧容器 +docker stop wecom-frontend +docker rm wecom-frontend + +# 重新构建镜像 +cd deploy/frontend +docker build -t wecom-frontend:latest . +cd ../.. + +# 启动新容器 +docker run -d \ + --name wecom-frontend \ + --restart always \ + --network wecom-network \ + -p 8081:80 \ + wecom-frontend:latest +``` + +## 方式 3: 使用部署脚本(最简单) + +我可以为你创建一个 Shell 脚本,自动执行所有 Docker 命令。 + +### Windows (PowerShell) +创建 `deploy.ps1` 脚本 + +### Linux/Mac (Bash) +创建 `deploy.sh` 脚本 + +需要我创建这些脚本吗? + +## 🔍 检查 Docker Compose 可用性 + +```bash +# 检查 docker-compose(旧版) +docker-compose --version + +# 检查 docker compose(新版) +docker compose version + +# 检查 Docker 版本 +docker --version +``` + +## 📝 推荐方案 + +1. **最推荐**: 使用 `docker compose`(Docker Compose V2) +2. **次推荐**: 使用部署脚本(我可以帮你创建) +3. **备选**: 手动执行 docker 命令 + +你想使用哪种方式?我可以帮你: +- 测试 `docker compose` 是否可用 +- 创建自动化部署脚本 +- 提供完整的手动命令清单 diff --git a/deploy/PORT-CONFIG.md b/deploy/PORT-CONFIG.md new file mode 100644 index 0000000..64cb415 --- /dev/null +++ b/deploy/PORT-CONFIG.md @@ -0,0 +1,181 @@ +# 端口配置说明 + +## 当前端口配置 + +### 后端服务 +- **容器内端口**: 8888 +- **宿主机端口**: 8888 +- **访问地址**: `http://your-server-ip:8888` + +### 前端服务 +- **容器内端口**: 80 +- **宿主机端口**: 8889 +- **访问地址**: `http://your-server-ip:8889/ashai-wecom-test` + +## 配置文件位置 + +### 1. 后端端口配置 +**文件**: [backend/application-druid.yml](backend/application-druid.yml) +```yaml +server: + port: 8888 +``` + +### 2. Docker 端口映射 +**文件**: [docker-compose.yml](docker-compose.yml) +```yaml +services: + backend: + ports: + - "8888:8888" # 宿主机:容器 + + frontend: + ports: + - "8889:80" # 宿主机:容器 +``` + +### 3. Dockerfile 暴露端口 +**文件**: [backend/Dockerfile](backend/Dockerfile) +```dockerfile +EXPOSE 8888 +``` + +## 修改端口 + +如果需要修改端口,需要同时修改以上三个地方: + +### 示例:改为 9000 端口 + +1. **修改 application-druid.yml**: +```yaml +server: + port: 9000 +``` + +2. **修改 docker-compose.yml**: +```yaml +ports: + - "9000:9000" +``` + +3. **修改 Dockerfile**: +```dockerfile +EXPOSE 9000 +``` + +4. **修改 healthcheck**: +```yaml +healthcheck: + test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:9000/"] +``` + +## 重新部署 + +修改端口后需要重新构建: + +```bash +# 停止并删除旧容器 +docker stop wecom-backend wecom-frontend +docker rm wecom-backend wecom-frontend + +# 重新构建并启动 +cd deploy +docker compose up -d --build + +# 查看日志 +docker compose logs -f +``` + +## 验证端口 + +### 检查容器端口 +```bash +docker ps +``` + +应该看到类似: +``` +CONTAINER ID IMAGE PORTS +xxx deploy-backend 0.0.0.0:8888->8888/tcp +xxx deploy-frontend 0.0.0.0:8889->80/tcp +``` + +### 测试后端访问 +```bash +curl http://localhost:8888 +``` + +### 测试前端访问 +```bash +curl http://localhost:8889/ashai-wecom-test +``` + +## 常见问题 + +### 1. 端口被占用 + +如果启动时报错端口被占用: + +```bash +# 查看端口占用 +netstat -tulpn | grep 8888 + +# 或使用 lsof(Mac/Linux) +lsof -i :8888 + +# Windows +netstat -ano | findstr 8888 +``` + +解决方案: +- 停止占用端口的程序 +- 或修改为其他未占用的端口 + +### 2. 容器内外端口不一致 + +如果宿主机 8080 被占用,可以只修改宿主机端口: + +```yaml +ports: + - "9000:8888" # 宿主机 9000 映射到容器 8888 +``` + +这样: +- 容器内应用仍运行在 8888 +- 外部通过 9000 访问 + +### 3. 前端无法连接后端 + +确保前端 Nginx 配置中的后端地址正确: + +**文件**: [frontend/nginx.conf](frontend/nginx.conf) +```nginx +location /ashai-wecom-test/prod-api/ { + proxy_pass http://backend:8888/; # 使用容器名和容器内端口 + ... +} +``` + +注意: +- 容器间通信使用**容器名**和**容器内端口** +- 不是宿主机端口 + +## 完整的访问流程 + +``` +用户浏览器 + ↓ +http://server-ip:8889/ashai-wecom-test + ↓ +宿主机 8889 端口 + ↓ +前端容器 80 端口 (Nginx) + ↓ +API 请求: /ashai-wecom-test/prod-api/* + ↓ +Nginx 代理到: http://backend:8888/ + ↓ +后端容器 8888 端口 (Spring Boot) + ↓ +返回数据 +``` diff --git a/deploy/README.md b/deploy/README.md new file mode 100644 index 0000000..4a29898 --- /dev/null +++ b/deploy/README.md @@ -0,0 +1,293 @@ +# 简化版 Docker 部署指南 + +这是一个简化的 Docker 部署方案,直接使用已经打包好的 jar 包和 dist 文件,无需在容器内重新构建。 + +## 📁 目录结构 + +``` +deploy/ +├── docker-compose.yml # Docker Compose 配置文件 +├── backend/ # 后端部署目录 +│ ├── Dockerfile # 后端 Dockerfile +│ └── ruoyi-admin.jar # 【需要放置】后端 jar 包 +├── frontend/ # 前端部署目录 +│ ├── Dockerfile # 前端 Dockerfile +│ ├── nginx.conf # Nginx 配置文件 +│ └── dist/ # 【需要放置】前端打包文件 +└── sql/ # 【可选】数据库初始化脚本 + └── ry_20xx.sql +``` + +## 🚀 快速部署步骤 + +### 1. 准备文件 + +将以下文件上传到服务器的 `deploy` 目录: + +```bash +# 1. 将后端 jar 包放到 backend 目录 +deploy/backend/ruoyi-admin.jar + +# 2. 将前端 dist 文件夹放到 frontend 目录 +deploy/frontend/dist/ + +# 3. (可选)将数据库初始化脚本放到 sql 目录 +deploy/sql/ry_20xx.sql +``` + +### 2. 修改配置 + +编辑 `docker-compose.yml`,根据需要修改以下配置: + +```yaml +# MySQL 配置 +environment: + MYSQL_ROOT_PASSWORD: password # 修改为你的密码 + MYSQL_DATABASE: ry-vue # 数据库名称 + +# 端口配置(如果端口冲突,可以修改) +ports: + - "3306:3306" # MySQL + - "6379:6379" # Redis + - "8080:8080" # 后端 + - "8081:80" # 前端 +``` + +### 3. 启动服务 + +```bash +# 进入 deploy 目录 +cd deploy + +# 启动所有服务 +docker-compose up -d + +# 查看服务状态 +docker-compose ps + +# 查看日志 +docker-compose logs -f +``` + +### 4. 访问应用 + +- **前端地址**: `http://your-server-ip:8081/ashai-wecom-test` +- **后端 API**: `http://your-server-ip:8080` +- **默认账号**: admin / admin123 + +## 📝 常用命令 + +```bash +# 启动所有服务 +docker-compose up -d + +# 停止所有服务 +docker-compose down + +# 重启某个服务 +docker-compose restart backend +docker-compose restart frontend + +# 查看服务日志 +docker-compose logs -f backend +docker-compose logs -f frontend + +# 查看服务状态 +docker-compose ps + +# 进入容器 +docker exec -it wecom-backend sh +docker exec -it wecom-frontend sh + +# 重新构建并启动 +docker-compose up -d --build + +# 停止并删除所有容器、网络、数据卷 +docker-compose down -v +``` + +## 🔄 更新部署 + +### 更新后端 + +```bash +# 1. 停止后端服务 +docker-compose stop backend + +# 2. 替换 jar 包 +cp new-ruoyi-admin.jar backend/ruoyi-admin.jar + +# 3. 重新构建并启动 +docker-compose up -d --build backend +``` + +### 更新前端 + +```bash +# 1. 停止前端服务 +docker-compose stop frontend + +# 2. 替换 dist 文件 +rm -rf frontend/dist +cp -r new-dist frontend/dist + +# 3. 重新构建并启动 +docker-compose up -d --build frontend +``` + +## 🔧 配置说明 + +### 后端配置 + +后端使用 `--spring.profiles.active=prod` 启动,确保你的 jar 包中包含正确的生产环境配置: + +- 数据库连接:`jdbc:mysql://mysql:3306/ry-vue` +- Redis 连接:`redis://redis:6379` + +如果需要修改配置,可以通过环境变量或重新打包 jar。 + +### 前端配置 + +前端通过 Nginx 提供服务,配置文件在 [frontend/nginx.conf](frontend/nginx.conf): + +- 访问路径:`/ashai-wecom-test` +- API 代理:`/ashai-wecom-test/prod-api/` → `http://backend:8080/` + +### 数据库初始化 + +首次启动时,如果 `sql` 目录中有 `.sql` 文件,MySQL 会自动执行这些脚本。 + +如果需要手动导入: + +```bash +# 复制 SQL 文件到容器 +docker cp ry_20xx.sql wecom-mysql:/tmp/ + +# 进入 MySQL 容器 +docker exec -it wecom-mysql bash + +# 导入数据库 +mysql -uroot -ppassword ry-vue < /tmp/ry_20xx.sql +``` + +## 🌐 集成到现有 Nginx(80 端口) + +如果服务器 80 端口已有 Nginx,可以添加反向代理配置: + +```nginx +# 在你的 Nginx 配置中添加 +location /ashai-wecom-test { + proxy_pass http://localhost:8081/ashai-wecom-test; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; +} +``` + +然后重启 Nginx: + +```bash +nginx -t +nginx -s reload +``` + +## 🐛 故障排查 + +### 1. 后端无法连接数据库 + +```bash +# 检查 MySQL 是否启动 +docker-compose ps mysql + +# 查看 MySQL 日志 +docker-compose logs mysql + +# 检查网络连接 +docker exec -it wecom-backend ping mysql +``` + +### 2. 前端无法访问后端 API + +```bash +# 检查后端是否启动 +docker-compose ps backend + +# 查看后端日志 +docker-compose logs backend + +# 测试后端接口 +curl http://localhost:8080/ +``` + +### 3. 前端页面 404 + +```bash +# 检查 dist 文件是否正确放置 +docker exec -it wecom-frontend ls -la /usr/share/nginx/html/ashai-wecom-test + +# 查看 Nginx 日志 +docker-compose logs frontend + +# 检查 Nginx 配置 +docker exec -it wecom-frontend cat /etc/nginx/conf.d/default.conf +``` + +### 4. 端口被占用 + +```bash +# 查看端口占用 +netstat -tulpn | grep 8080 +netstat -tulpn | grep 8081 + +# 修改 docker-compose.yml 中的端口映射 +ports: + - "8082:8080" # 改为其他端口 +``` + +### 5. 容器启动失败 + +```bash +# 查看详细日志 +docker-compose logs -f + +# 检查容器状态 +docker-compose ps + +# 重新构建 +docker-compose down +docker-compose up -d --build +``` + +## 📊 数据持久化 + +所有数据都通过 Docker 卷持久化: + +- `mysql_data`: MySQL 数据 +- `redis_data`: Redis 数据 +- `upload_data`: 文件上传目录 + +即使删除容器,数据也不会丢失。如需完全清理: + +```bash +docker-compose down -v +``` + +## 🔒 安全建议 + +1. **修改默认密码**:修改 MySQL root 密码和应用管理员密码 +2. **限制端口访问**:使用防火墙限制数据库端口的外部访问 +3. **使用 HTTPS**:在生产环境配置 SSL 证书 +4. **定期备份**:定期备份数据库和上传文件 + +## 📈 性能优化 + +1. **调整 JVM 参数**:在 [backend/Dockerfile](backend/Dockerfile) 中添加 JVM 参数 +2. **配置 Nginx 缓存**:已在 [frontend/nginx.conf](frontend/nginx.conf) 中配置 +3. **数据库优化**:根据实际情况调整 MySQL 配置 + +## 💡 提示 + +- 首次启动可能需要等待 1-2 分钟,等待数据库初始化 +- 确保服务器有足够的内存(建议至少 2GB) +- 生产环境建议使用外部数据库,而不是容器内的数据库 diff --git a/deploy/TROUBLESHOOTING.md b/deploy/TROUBLESHOOTING.md new file mode 100644 index 0000000..f1415ee --- /dev/null +++ b/deploy/TROUBLESHOOTING.md @@ -0,0 +1,184 @@ +# 后端启动配置问题修复 + +## 问题描述 + +后端启动时报错: +``` +Could not resolve placeholder 'spring.datasource.druid.initialSize' +``` + +## 原因分析 + +若依项目使用了 Druid 数据源,配置在 `application-druid.yml` 中。环境变量无法直接覆盖 Druid 的嵌套配置属性。 + +## 解决方案 + +### 1. 创建启动脚本 + +已创建 [entrypoint.sh](backend/entrypoint.sh),使用 Java 系统属性覆盖配置: + +```bash +#!/bin/sh + +exec java \ + -Dspring.profiles.active=prod \ + -Dspring.datasource.druid.master.url="${SPRING_DATASOURCE_URL}" \ + -Dspring.datasource.druid.master.username="${SPRING_DATASOURCE_USERNAME}" \ + -Dspring.datasource.druid.master.password="${SPRING_DATASOURCE_PASSWORD}" \ + -Dspring.redis.host="${SPRING_REDIS_HOST}" \ + -Dspring.redis.port="${SPRING_REDIS_PORT}" \ + -jar app.jar +``` + +### 2. 修改 Dockerfile + +已修改 [backend/Dockerfile](backend/Dockerfile),使用启动脚本: + +```dockerfile +# 复制启动脚本 +COPY entrypoint.sh /entrypoint.sh +RUN chmod +x /entrypoint.sh + +# 启动应用 +ENTRYPOINT ["/entrypoint.sh"] +``` + +## 重新部署 + +### 1. 停止并删除旧容器 +```bash +docker stop wecom-backend +docker rm wecom-backend +``` + +### 2. 重新构建并启动 +```bash +cd deploy +docker compose up -d --build backend +``` + +### 3. 查看日志 +```bash +docker compose logs -f backend +``` + +## 验证启动成功 + +查看日志中是否有以下内容: +``` +Started RuoYiApplication in X seconds +``` + +## 其他可能的问题 + +### 1. 数据库连接失败 + +检查 MySQL 容器是否允许远程连接: +```bash +docker exec -it mysql-jijin-test mysql -uroot -p + +# 授权远程访问 +GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'jiong1114'; +FLUSH PRIVILEGES; +``` + +### 2. 数据库不存在 + +创建数据库: +```bash +docker exec -it mysql-jijin-test mysql -uroot -pjiong1114 + +CREATE DATABASE IF NOT EXISTS `ry-vue` DEFAULT CHARACTER SET utf8mb4; +``` + +### 3. Redis 连接失败 + +检查 Redis 是否允许远程连接: +```bash +docker exec -it redis redis-cli CONFIG GET bind + +# 如果绑定了 127.0.0.1,需要修改 +docker exec -it redis redis-cli CONFIG SET bind "0.0.0.0" +``` + +### 4. 端口配置不匹配 + +注意 docker-compose.yml 中配置的是 8888 端口: +```yaml +ports: + - "8888:8888" # 宿主机:容器 +``` + +但 Dockerfile 暴露的是 8080 端口。需要修改其中一个保持一致。 + +#### 方案 A: 修改 docker-compose.yml(推荐) +```yaml +ports: + - "8888:8080" # 宿主机 8888 映射到容器 8080 +``` + +#### 方案 B: 修改应用端口 +在 docker-compose.yml 中添加环境变量: +```yaml +environment: + - SERVER_PORT=8888 +``` + +## 完整的 docker-compose.yml 配置 + +```yaml +version: '3.8' + +services: + backend: + build: + context: ./backend + dockerfile: Dockerfile + container_name: wecom-backend + restart: always + ports: + - "8888:8080" # 宿主机 8888 映射到容器 8080 + volumes: + - upload_data:/home/ruoyi/uploadPath + environment: + - SPRING_PROFILES_ACTIVE=prod + - TZ=Asia/Shanghai + - SPRING_DATASOURCE_URL=jdbc:mysql://host.docker.internal:3316/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + - SPRING_DATASOURCE_USERNAME=root + - SPRING_DATASOURCE_PASSWORD=jiong1114 + - SPRING_REDIS_HOST=host.docker.internal + - SPRING_REDIS_PORT=6379 + - SPRING_REDIS_PASSWORD= + extra_hosts: + - "host.docker.internal:host-gateway" + networks: + - wecom-network + healthcheck: + test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:8080/"] + interval: 30s + timeout: 10s + retries: 3 + + frontend: + build: + context: ./frontend + dockerfile: Dockerfile + container_name: wecom-frontend + restart: always + ports: + - "8889:80" + depends_on: + - backend + networks: + - wecom-network + +volumes: + upload_data: + driver: local + +networks: + wecom-network: + driver: bridge +``` + +注意 healthcheck 中使用的是容器内部端口 8080。 diff --git a/deploy/backend/Dockerfile b/deploy/backend/Dockerfile new file mode 100644 index 0000000..6697085 --- /dev/null +++ b/deploy/backend/Dockerfile @@ -0,0 +1,30 @@ +# 简化版后端 Dockerfile - 直接使用已打包的 jar 文件 +# 使用 Eclipse Temurin(OpenJDK 的官方替代品) +FROM eclipse-temurin:8-jre-alpine + +# 设置工作目录 +WORKDIR /app + +# 复制 jar 包到容器 +# 使用时将 jar 包放在与 Dockerfile 同级目录 +COPY *.jar app.jar + +# 复制外部配置文件(会覆盖 jar 包内的配置) +COPY application-druid.yml /app/application-druid.yml + +# 复制启动脚本 +COPY entrypoint.sh /entrypoint.sh +RUN chmod +x /entrypoint.sh + +# 创建上传文件目录 +RUN mkdir -p /home/ruoyi/uploadPath + +# 暴露端口 +EXPOSE 8888 + +# 设置时区 +ENV TZ=Asia/Shanghai +RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone + +# 启动应用 +ENTRYPOINT ["/entrypoint.sh"] diff --git a/deploy/backend/application-druid.yml b/deploy/backend/application-druid.yml new file mode 100644 index 0000000..1f436b1 --- /dev/null +++ b/deploy/backend/application-druid.yml @@ -0,0 +1,79 @@ +# 数据源配置 +spring: + datasource: + type: com.alibaba.druid.pool.DruidDataSource + driverClassName: com.mysql.cj.jdbc.Driver + druid: + # 主库数据源 + master: + url: jdbc:mysql://host.docker.internal:3316/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + username: root + password: jiong1114 + # 从库数据源 + slave: + # 从数据源开关/默认关闭 + enabled: false + url: + username: + password: + # 初始连接数 + initialSize: 5 + # 最小连接池数量 + minIdle: 10 + # 最大连接池数量 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置连接超时时间 + connectTimeout: 30000 + # 配置网络超时时间 + socketTimeout: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + # 配置一个连接在池中最大生存的时间,单位是毫秒 + maxEvictableIdleTimeMillis: 900000 + # 配置检测连接是否有效 + validationQuery: SELECT 1 FROM DUAL + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + webStatFilter: + enabled: true + statViewServlet: + enabled: true + # 设置白名单,不填则允许所有访问 + allow: + url-pattern: /druid/* + # 控制台管理用户名和密码 + login-username: ruoyi + login-password: 123456 + filter: + stat: + enabled: true + # 慢SQL记录 + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true + + # Redis 配置 + redis: + host: host.docker.internal + port: 6379 + password: + database: 0 + timeout: 10s + lettuce: + pool: + min-idle: 0 + max-idle: 8 + max-active: 8 + max-wait: -1ms + +# 服务器端口配置 +server: + port: 8888 diff --git a/deploy/backend/entrypoint.sh b/deploy/backend/entrypoint.sh new file mode 100644 index 0000000..d4148dc --- /dev/null +++ b/deploy/backend/entrypoint.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +# 启动 Spring Boot 应用 +# 外部配置文件 application-druid.yml 会自动被加载并覆盖 jar 包内的配置 +exec java -Dspring.profiles.active=prod -jar app.jar diff --git a/deploy/docker-compose.yml b/deploy/docker-compose.yml new file mode 100644 index 0000000..6048745 --- /dev/null +++ b/deploy/docker-compose.yml @@ -0,0 +1,58 @@ +version: '3.8' + +services: + # 后端服务 + backend: + build: + context: ./backend + dockerfile: Dockerfile + container_name: wecom-backend + restart: always + ports: + - "8888:8888" + volumes: + - upload_data:/home/ruoyi/uploadPath + environment: + - SPRING_PROFILES_ACTIVE=prod + - TZ=Asia/Shanghai + # 数据库连接配置(连接到宿主机的 MySQL 容器) + - SPRING_DATASOURCE_URL=jdbc:mysql://host.docker.internal:3316/ry-vue?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + - SPRING_DATASOURCE_USERNAME=root + - SPRING_DATASOURCE_PASSWORD=jiong1114 + # Redis 连接配置(连接到宿主机的 Redis 容器) + - SPRING_REDIS_HOST=host.docker.internal + - SPRING_REDIS_PORT=6379 + - SPRING_REDIS_PASSWORD= + extra_hosts: + - "host.docker.internal:host-gateway" + networks: + - wecom-network + healthcheck: + test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:8888/"] + interval: 30s + timeout: 10s + retries: 3 + + # 前端服务 + frontend: + build: + context: ./frontend + dockerfile: Dockerfile + container_name: wecom-frontend + restart: always + ports: + - "8889:80" + depends_on: + - backend + networks: + - wecom-network + +# 数据卷 +volumes: + upload_data: + driver: local + +# 网络 +networks: + wecom-network: + driver: bridge diff --git a/deploy/frontend/Dockerfile b/deploy/frontend/Dockerfile new file mode 100644 index 0000000..c114340 --- /dev/null +++ b/deploy/frontend/Dockerfile @@ -0,0 +1,15 @@ +# 简化版前端 Dockerfile - 直接使用已打包的 dist 文件 +FROM nginx:alpine + +# 复制 dist 文件到 Nginx 的子路径目录 +# 使用时将 dist 目录放在与 Dockerfile 同级目录 +COPY dist /usr/share/nginx/html/ashai-wecom-test + +# 复制 Nginx 配置文件 +COPY nginx.conf /etc/nginx/conf.d/default.conf + +# 暴露端口 +EXPOSE 80 + +# 启动 Nginx +CMD ["nginx", "-g", "daemon off;"] diff --git a/deploy/frontend/nginx.conf b/deploy/frontend/nginx.conf new file mode 100644 index 0000000..5341a84 --- /dev/null +++ b/deploy/frontend/nginx.conf @@ -0,0 +1,83 @@ +server { + listen 80; + server_name localhost; + + # Gzip 压缩配置 + gzip on; + gzip_min_length 1k; + gzip_comp_level 6; + gzip_types text/plain text/css text/javascript application/json application/javascript application/x-javascript application/xml; + gzip_vary on; + gzip_disable "MSIE [1-6]\."; + + # API 代理到后端(不带项目路径前缀) + location /prod-api/ { + proxy_pass http://backend:8888/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_connect_timeout 600; + proxy_read_timeout 600; + proxy_send_timeout 600; + + # 支持 WebSocket + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } + + # 前端静态文件路径(带项目路径前缀) + location /ashai-wecom-test { + alias /usr/share/nginx/html/ashai-wecom-test; + try_files $uri $uri/ /ashai-wecom-test/index.html; + index index.html; + + # 静态资源缓存配置 + location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { + expires 7d; + add_header Cache-Control "public, immutable"; + } + } + + # API 代理到后端(带项目路径前缀) + location /ashai-wecom-test/prod-api/ { + proxy_pass http://backend:8888/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_connect_timeout 600; + proxy_read_timeout 600; + proxy_send_timeout 600; + + # 支持 WebSocket + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } + + # 根路径重定向到项目路径 + location = / { + return 301 /ashai-wecom-test/; + } + + # 其他所有路径都尝试从项目目录加载(支持 Vue Router History 模式) + location / { + root /usr/share/nginx/html/ashai-wecom-test; + try_files $uri $uri/ /index.html; + index index.html; + + # 静态资源缓存配置 + location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { + expires 7d; + add_header Cache-Control "public, immutable"; + } + } + + # 错误页面 + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..4b8369c --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,79 @@ +version: '3.8' + +services: + # MySQL 数据库 + mysql: + image: mysql:5.7 + container_name: ruoyi-mysql + environment: + MYSQL_ROOT_PASSWORD: password + MYSQL_DATABASE: ruoyi + TZ: Asia/Shanghai + ports: + - "3306:3306" + volumes: + - mysql-data:/var/lib/mysql + - ./sql:/docker-entrypoint-initdb.d + command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci + networks: + - ruoyi-network + restart: unless-stopped + + # Redis 缓存 + redis: + image: redis:6-alpine + container_name: ruoyi-redis + ports: + - "6379:6379" + volumes: + - redis-data:/data + networks: + - ruoyi-network + restart: unless-stopped + + # 后端服务 + backend: + build: + context: . + dockerfile: Dockerfile.backend + container_name: ruoyi-backend + environment: + SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/ruoyi?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + SPRING_DATASOURCE_USERNAME: root + SPRING_DATASOURCE_PASSWORD: password + SPRING_REDIS_HOST: redis + SPRING_REDIS_PORT: 6379 + SERVER_SERVLET_CONTEXT_PATH: / + ports: + - "8080:8080" + volumes: + - upload-data:/home/ruoyi/uploadPath + depends_on: + - mysql + - redis + networks: + - ruoyi-network + restart: unless-stopped + + # 前端 Nginx + frontend: + build: + context: ./ruoyi-ui + dockerfile: Dockerfile + container_name: ruoyi-frontend + ports: + - "8081:80" + depends_on: + - backend + networks: + - ruoyi-network + restart: unless-stopped + +networks: + ruoyi-network: + driver: bridge + +volumes: + mysql-data: + redis-data: + upload-data: diff --git a/excel-handle/src/main/java/com/ruoyi/excel/wecom/vo/CustomerStatisticsDataVO.java b/excel-handle/src/main/java/com/ruoyi/excel/wecom/vo/CustomerStatisticsDataVO.java index b9d58e7..c68b170 100644 --- a/excel-handle/src/main/java/com/ruoyi/excel/wecom/vo/CustomerStatisticsDataVO.java +++ b/excel-handle/src/main/java/com/ruoyi/excel/wecom/vo/CustomerStatisticsDataVO.java @@ -3,6 +3,7 @@ package com.ruoyi.excel.wecom.vo; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.format.DateTimeFormat; import com.alibaba.excel.annotation.write.style.ColumnWidth; +import com.ruoyi.common.annotation.Excel; import java.io.Serializable; import java.util.Date; @@ -16,55 +17,68 @@ public class CustomerStatisticsDataVO implements Serializable { private static final long serialVersionUID = 1L; @ExcelProperty("统计日期") + @Excel(name ="统计日期") @DateTimeFormat("yyyy-MM-dd") @ColumnWidth(20) private Date curDate; @ExcelProperty("重要指标") + @Excel(name ="重要指标") @ColumnWidth(30) private String indicatorName; @ExcelProperty("N组") + @Excel(name ="N组(投放)") @ColumnWidth(15) private String nGroup; @ExcelProperty("O组(公司孵化)") + @Excel(name ="O组(公司孵化)") @ColumnWidth(20) private String oGroup; @ExcelProperty("P组(商务)") + @Excel(name ="P组(商务)") @ColumnWidth(15) private String pGroup; @ExcelProperty("W组(A1组)") + @Excel(name ="W组(A1组)") @ColumnWidth(15) private String wGroup; @ExcelProperty("X组(B1组)") + @Excel(name ="X组(B1组)") @ColumnWidth(15) private String xGroup; @ExcelProperty("Y组(C1组)") + @Excel(name ="Y组(C1组)") @ColumnWidth(15) private String yGroup; @ExcelProperty("Z组(D1组)") + @Excel(name ="Z组(D1组)") @ColumnWidth(15) private String zGroup; @ExcelProperty("AA组(E1组)") + @Excel(name ="AA组(E1组)") @ColumnWidth(15) private String aaGroup; @ExcelProperty("AC组(自然流)") + @Excel(name ="AC组(自然流)") @ColumnWidth(20) private String acGroup; @ExcelProperty("AD组(F1组)") + @Excel(name ="AD组(F1组)") @ColumnWidth(15) private String adGroup; @ExcelProperty("AE组(G1组)") + @Excel(name ="AE组(G1组)") @ColumnWidth(15) private String aeGroup; diff --git a/excel-handle/src/main/java/com/ruoyi/excel/wecom/vo/DepartmentStatisticsDataVO.java b/excel-handle/src/main/java/com/ruoyi/excel/wecom/vo/DepartmentStatisticsDataVO.java index c2569e0..a850d5b 100644 --- a/excel-handle/src/main/java/com/ruoyi/excel/wecom/vo/DepartmentStatisticsDataVO.java +++ b/excel-handle/src/main/java/com/ruoyi/excel/wecom/vo/DepartmentStatisticsDataVO.java @@ -3,6 +3,7 @@ package com.ruoyi.excel.wecom.vo; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.annotation.format.DateTimeFormat; import com.alibaba.excel.annotation.write.style.ColumnWidth; +import com.ruoyi.common.annotation.Excel; import lombok.Data; import java.io.Serializable; @@ -18,28 +19,34 @@ public class DepartmentStatisticsDataVO implements Serializable { private static final long serialVersionUID = 1L; @ExcelProperty("统计日期") + @Excel(name ="统计日期") @DateTimeFormat("yyyy-MM-dd") @ColumnWidth(15) private Date statDate; @ExcelProperty("部门路径") + @Excel(name ="部门路径") @ColumnWidth(40) private String departmentPath; @ExcelProperty("当日总承接数") + @Excel(name ="当日总承接数") @ColumnWidth(15) private Integer dailyTotalAccepted; @ExcelProperty("当日总成单数") + @Excel(name ="当日总成单数") @ColumnWidth(15) private Integer dailyTotalOrders; @ExcelProperty("当日转化率") + @Excel(name ="当日转化率") @ColumnWidth(15) private BigDecimal dailyConversionRate; @ExcelProperty("排序号") + @Excel(name ="排序号") @ColumnWidth(10) private Integer sortNo; } diff --git a/excel-handle/src/main/resources/mapper/wecom/DepartmentStatisticsDataMapper.xml b/excel-handle/src/main/resources/mapper/wecom/DepartmentStatisticsDataMapper.xml index 65157d0..0088892 100644 --- a/excel-handle/src/main/resources/mapper/wecom/DepartmentStatisticsDataMapper.xml +++ b/excel-handle/src/main/resources/mapper/wecom/DepartmentStatisticsDataMapper.xml @@ -95,7 +95,8 @@