项目根目录
├── docker-compose.yml # Docker Compose 编排文件,定义三个服务的启动顺序和网络配置
├── mysql-init/ # MySQL 初始化脚本目录
│ └── init.sql # 数据库建库建表脚本,首次启动时自动执行
├── mysql-data/ # MySQL 数据持久化目录,存放数据库文件
├── hwtest/ # 后端 Spring Boot 项目(Java 17 + Gradle + Spring Boot 3.5)
│ ├── src/ # Java 源代码目录(Controller、Service、Mapper、Entity)
│ ├── build/libs/ # Gradle 打包产物目录(jar 文件)
│ ├── Dockerfile # 后端镜像构建文件,基于 eclipse-temurin:17-jre-alpine
│ ├── build.gradle # Gradle 构建脚本,配置 JDK 17 和依赖
│ ├── gradlew # Gradle Wrapper 启动脚本
│ └── application.yml # Spring Boot 配置文件(数据源、端口等)
└── testfornt/ # 前端 Vue 3 + TypeScript 项目
├── src/ # Vue 源代码目录(组件、路由、API 接口)
├── dist/ # 前端打包产物目录(npm run build 生成)
├── nginx.conf # Nginx 配置文件,含反向代理到后端
└── Dockerfile # 前端镜像构建文件,基于 nginx:alpine
技术栈说明:
- JDK 版本:Java 17(build.gradle 中配置
JavaLanguageVersion.of(17)) - 后端框架:Spring Boot 3.5.16
- 构建工具:Gradle 8.14.5(使用 Gradle Wrapper,无需本地安装 Gradle)
- 数据库:MySQL 8.0 + MyBatis 3.0.5
- 前端框架:Vue 3 + TypeScript + Vite + shadcn-ui
- 部署方式:Docker Compose 一键部署(MySQL + 后端 + Nginx 前端)
version: '3.8'
networks:
app-net:
services:
mysql:
image: mysql:8.0
container_name: mysql8-server
networks:
- app-net
ports:
- '3306:3306'
volumes:
- ./mysql-data:/var/lib/mysql
- ./mysql-init:/docker-entrypoint-initdb.d
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_ROOT_HOST: '%'
MYSQL_DATABASE: hwtest_db
restart: always
command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
backend:
build: ./hwtest
container_name: backend
networks:
- app-net
ports:
- '8080:8080'
depends_on:
- mysql
restart: always
web:
build: ./testfornt
container_name: web-vue
networks:
- app-net
ports:
- '80:80'
depends_on:
- backend
restart: alwaysCREATE DATABASE IF NOT EXISTS hwtest_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE hwtest_db;
DROP TABLE IF EXISTS `user`;
CREATE TABLE user
(
id int auto_increment comment '主键自增ID' primary key,
username varchar(100) null comment '用户名',
age int null comment '年龄'
);FROM openjdk:17-jdk-slim
WORKDIR /app
COPY target/hwtest.jar app.jar
ENTRYPOINT ["java","-jar","app.jar"]spring:
datasource:
url: jdbc:mysql://mysql:3306/hwtest_db?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
username: root
password: 123456FROM nginx:alpine
COPY dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80server {
listen 80;
server_name localhost;
root /usr/share/nginx/html;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /hwtest/ {
proxy_pass http://backend:8080/hwtest/;
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;
}
}baseURL: '/hwtest';npm run build./gradlew.bat clean build -x test或使用 Unix/Linux:
./gradlew clean build -x test使用 Gradle Wrapper 打包,无需本地安装 Gradle。产物位于
build/libs/目录。
docker-compose down
Remove-Item -Recurse -Force ./mysql-data -ErrorAction SilentlyContinue
docker-compose up -d --build等待40秒MySQL初始化完成,访问:http://localhost
# 更新前端
npm run build
docker-compose up -d --build web
# 重载Nginx配置
docker exec web-vue nginx -s reload
# 更新后端
./gradlew.bat clean build -x test
docker-compose up -d --build backend
# 查看日志
docker logs -f backend
docker logs -f mysql8-server
docker logs -f web-vue| 报错现象 | 原因 | 解决方案 |
|---|---|---|
| 容器已存在冲突 | 旧容器残留 | docker rm -f 容器名 |
| Host禁止连接MySQL | 默认仅本地访问 | MYSQL_ROOT_HOST: '%' |
| Unknown database | 脚本后缀错/启动太快 | 后缀.sql,等待40秒 |
| 接口404 | proxy_pass路径不匹配 | 统一/hwtest前缀 |
| PowerShell换行报错 | 不支持\换行 | 命令写单行 |
| nginx配置不生效 | 打包进镜像 | --build web重建 |
| MySQL密码错误 | 旧数据残留 | 删除mysql-data重建 |
# 删除占用名字的旧容器
docker rm mysql8-server
补充:如果容器正在运行删不掉,加 -f 强制删除:
docker rm -f mysql8-server- 日常迭代不要执行docker-compose down
- mysql-data只在首次部署时清理
- 容器内互通域名:mysql、backend