当前位置: 首页 > news >正文

react+springboot的Docker部署

 React + Vite 前端 + Spring Boot (Java 17, MyBatis) 后端 + MySQL 项目,提供一个完整的、零错误的部署方案。方案将:

  1. 使用 Docker Compose 的 build 指令直接构建前端(Nginx)和后端(Spring Boot)镜像,省去手动 docker build。
  2. 保留 MyBatis 配置和 ./mysql/db.sql:/docker-entrypoint-initdb.d/db.sql 初始化。
  3. 确保部署后直接通过浏览器访问 http://localhost(Nginx 默认 80 端口)。
  4. 支持云部署,通用且只需修改少量配置。

项目结构

假设项目结构如下(基于 C:\full-stack\admin-react,调整路径如果不同):

text

admin-react/
├── frontend/  # React + Vite 前端
│   ├── vite.config.js
│   ├── package.json
│   ├── src/
│   └── ... (其他文件)
├── backend/   # Spring Boot 后端 (MyBatis)
│   ├── pom.xml
│   ├── src/
│   │   └── main/
│   │       ├── java/   # Java 代码和 MyBatis Mapper 接口
│   │       └── resources/
│   │           ├── application.yml
│   │           └── mapper/  # MyBatis XML Mapper 文件(可选)
│   └── ... (其他文件)
├── mysql/     # MySQL 初始化脚本
│   └── db.sql  # 数据库初始化 SQL
├── nginx/     # Nginx 配置文件
│   └── nginx.conf
├── docker-compose.yml  # Docker Compose 配置
├── Dockerfile.frontend  # 前端 Nginx 构建
├── Dockerfile.backend  # 后端 Spring Boot 构建
└── README.md   # 可选文档

步骤 1: 项目配置

前端 (React + Vite)
  1. vite.config.js (frontend/vite.config.js):

    js

    import { defineConfig } from 'vite';
    import react from '@vitejs/plugin-react';export default defineConfig({plugins: [react()],server: {proxy: {'/api': 'http://localhost:8080',  // 开发时代理到后端},},build: {outDir: 'dist',},
    });
  2. package.json (frontend/package.json):

    json

    "scripts": {"build": "vite build"
    }
后端 (Spring Boot + MyBatis)
  1. application.yml (backend/src/main/resources/application.yml):

    yaml

    server:port: ${SERVER_PORT:8080}spring:datasource:url: jdbc:mysql://${DB_HOST:localhost}:${DB_PORT:3306}/${DB_NAME:mydatabase}?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=trueusername: ${DB_USERNAME:root}password: ${DB_PASSWORD:password}driver-class-name: com.mysql.cj.jdbc.Drivermybatis:mapper-locations: classpath:mapper/*.xml  # 调整为您的 XML Mapper 路径(若无则移除)type-aliases-package: com.example.entity  # 调整为您的实体包路径configuration:map-underscore-to-camel-case: truelogging:level:root: INFOcom.example: DEBUG  # 调整为您的包路径
    • 注意:替换 com.example 为实际包路径。若使用 MyBatis 注解(@Mapper),移除 mapper-locations。
  2. pom.xml (backend/pom.xml):

    xml

    <properties><java.version>17</java.version><mybatis.spring-boot.version>3.0.3</mybatis.spring-boot.version>
    </properties>
    <dependencies><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>${mybatis.spring-boot.version}</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency>
    </dependencies>
    <build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></build>
  3. db.sql (mysql/db.sql):

    sql

    CREATE DATABASE IF NOT EXISTS mydatabase;
    USE mydatabase;CREATE TABLE IF NOT EXISTS users (id BIGINT AUTO_INCREMENT PRIMARY KEY,username VARCHAR(50) NOT NULL UNIQUE,email VARCHAR(100) NOT NULL
    );INSERT IGNORE INTO users (username, email) VALUES ('admin', 'admin@example.com');
    • 注意:IF NOT EXISTS 和 INSERT IGNORE 防止重复执行错误。
  4. MyBatis Mapper
    • 如果用 XML,放置在 backend/src/main/resources/mapper/(e.g., UserMapper.xml)。
    • 如果用注解:

      java

      package com.example.mapper;import org.apache.ibatis.annotations.Mapper;
      import org.apache.ibatis.annotations.Select;@Mapper
      public interface UserMapper {@Select("SELECT * FROM users WHERE id = #{id}")User findById(Long id);
      }
    • 主类添加 @MapperScan:

      java

      import org.mybatis.spring.annotation.MapperScan;
      import org.springframework.boot.SpringApplication;
      import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
      @MapperScan("com.example.mapper")
      public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
      }
Nginx 配置

nginx.conf (nginx/nginx.conf):

nginx

server {listen 80;server_name localhost;root /usr/share/nginx/html;index index.html;# React 单页应用路由location / {try_files $uri $uri/ /index.html;}# 代理 API 到后端location /api/ {proxy_pass http://backend:8080/api/;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}# 静态资源缓存location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot) {expires 1y;access_log off;add_header Cache-Control "public";}error_page 500 502 503 504 /50x.html;location = /50x.html {root /usr/share/nginx/html;}
}

步骤 2: Dockerfiles

前端 (Nginx)

Dockerfile.frontend (C:\full-stack\admin-react\Dockerfile.frontend):

dockerfile

# 构建 React 前端
FROM node:20-alpine AS build
WORKDIR /app
COPY frontend/package*.json ./
RUN npm install
COPY frontend/ ./
RUN npm run build# 运行 Nginx
FROM nginx:1.25-alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx/nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
后端 (Spring Boot)

Dockerfile.backend (C:\full-stack\admin-react\Dockerfile.backend):

dockerfile

FROM maven:3.8.6-amazoncorretto-17 AS build
WORKDIR /app
COPY backend/pom.xml ./
COPY backend/src ./src
RUN mvn clean package -DskipTestsFROM amazoncorretto:17-alpine
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar
EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s CMD wget --quiet --tries=1 --spider http://localhost:8080/actuator/health || exit 1
ENTRYPOINT ["java", "-jar", "/app.jar"]

步骤 3: Docker Compose

docker-compose.yml (C:\full-stack\admin-react\docker-compose.yml):

yaml

services:frontend:build:context: .dockerfile: Dockerfile.frontendports:- "80:80"depends_on:backend:condition: service_healthyrestart: alwayshealthcheck:test: ["CMD", "curl", "-f", "http://localhost"]interval: 30stimeout: 3sretries: 3backend:build:context: .dockerfile: Dockerfile.backendports:- "8080:8080"environment:- SERVER_PORT=8080- DB_HOST=db- DB_PORT=3306- DB_NAME=mydatabase- DB_USERNAME=root- DB_PASSWORD=passworddepends_on:db:condition: service_healthyrestart: alwayshealthcheck:test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:8080/actuator/health"]interval: 30stimeout: 3sretries: 3db:image: mysql:8.0ports:- "3306:3306"environment:- MYSQL_ROOT_PASSWORD=password- MYSQL_DATABASE=mydatabasevolumes:- db-data:/var/lib/mysql- ./mysql/db.sql:/docker-entrypoint-initdb.d/db.sqlrestart: alwayshealthcheck:test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]interval: 10stimeout: 5sretries: 5volumes:db-data:
  • 关键点
    • 移除 image: my-app-frontend:latest 和 image: my-app-backend:latest,直接用 build 指令,Docker Compose 自动构建镜像,无需手动 docker build。
    • frontend 暴露 80 端口,浏览器访问 http://localhost。
    • backend 不暴露端口,Nginx 通过 proxy_pass http://backend:8080/api/ 访问(backend 是服务名)。
    • db 保留 db.sql 初始化。

步骤 4: 本地部署与访问

  1. 运行 Docker Compose

    bash

    cd C:\full-stack\admin-react
    docker-compose up --build
    • --build 强制构建 frontend 和 backend 镜像(从 Dockerfile.frontend 和 Dockerfile.backend)。
    • 自动拉取 mysql:8.0(若网络问题,参考下方调试)。
  2. 浏览器访问
    • 打开浏览器,输入:

      text

      http://localhost
      • Nginx serve React 页面(/usr/share/nginx/html)。
      • API 请求(/api/)代理到后端。
    • 如果 80 端口被占用,修改 docker-compose.yml 的 frontend 端口(e.g., 8080:80),访问 http://localhost:8080。
  3. 验证
    • 检查容器:docker-compose ps(确保 frontend, backend, db 状态为 Up)。
    • 查看日志:

      bash

      docker logs admin-react-frontend-1
      docker logs admin-react-backend-1
      docker logs admin-react-db-1
    • 确认 MySQL 初始化:

      bash

      docker exec -it admin-react-db-1 mysql -uroot -ppassword -e "use mydatabase; show tables;"

步骤 5: 云部署

推送镜像(可选)

如果云部署需要预构建镜像:

  1. 构建:

    bash

    docker-compose build
  2. 打标签并推送:

    bash

    docker tag admin-react-frontend yourusername/my-app-frontend:latest
    docker tag admin-react-backend yourusername/my-app-backend:latest
    docker push yourusername/my-app-frontend:latest
    docker push yourusername/my-app-backend:latest
AWS ECS 示例
  1. 推送镜像到 ECR(若不推送,可在云端用 docker-compose.yml 构建)。
  2. Task Definitions
    • Frontend:

      json

      {"containerDefinitions": [{"name": "frontend","image": "your-ecr-repo/my-app-frontend:latest","portMappings": [{ "containerPort": 80 }],"dependsOn": [{ "containerName": "backend", "condition": "HEALTHY" }]}]
      }
    • Backend:

      json

      {"containerDefinitions": [{"name": "backend","image": "your-ecr-repo/my-app-backend:latest","environment": [{ "name": "SERVER_PORT", "value": "8080" },{ "name": "DB_HOST", "value": "your-rds-endpoint" },{ "name": "DB_PORT", "value": "3306" },{ "name": "DB_NAME", "value": "mydatabase" },{ "name": "DB_USERNAME", "value": "admin" }],"secrets": [{ "name": "DB_PASSWORD", "valueFrom": "arn:aws:ssm:region:account-id:parameter/db-password" }]}]
      }
  3. Service:Fargate,ALB 绑定到 frontend 的 80 端口。
  4. RDS:手动运行 db.sql 初始化。
其他云(GKE/AKS)
  • 用 Kubernetes Deployment/Service,frontend 暴露 80 端口(LoadBalancer)。
  • 数据库:Cloud SQL 或 Azure MySQL,手动初始化 db.sql。

步骤 6: 调试与注意事项

  1. 无法访问 http://localhost
    • 检查端口:netstat -aon | findstr :80.
    • 确认 Nginx 日志:docker logs admin-react-frontend-1.
    • 确保 frontend/dist 构建成功:dir frontend\dist.
  2. API 请求失败
    • 验证 Nginx proxy_pass http://backend:8080/api/(backend 是服务名)。
    • 检查后端日志:docker logs admin-react-backend-1.
  3. MySQL 初始化失败
    • 确认 db.sql 语法:docker exec -it admin-react-db-1 mysql -uroot -ppassword -e "use mydatabase; show tables;".
    • 检查 MyBatis 连接:后端日志是否有 SQL 错误。
  4. Docker Hub 拉取失败(mysql:8.0):
    • 配置镜像源(中国用户):

      json

      // C:\ProgramData\Docker\config\daemon.json
      {"registry-mirrors": ["https://registry.docker-cn.com"]
      }
    • 重启 Docker:net stop com.docker.service && net start com.docker.service.
    • 重试:docker-compose up --build.
  5. 配置修改
    • 数据库名/密码:改 docker-compose.yml 或云 env vars 的 DB_NAME、DB_PASSWORD.
    • 端口:改 frontend 的 ports(e.g., 8080:80)。

总结

  • 改进:移除手动 docker build,Docker Compose 的 build 指令自动构建 frontend 和 backend 镜像。前端由 Nginx 提供,省去复制 dist 的步骤。
  • 访问:运行 docker-compose up --build,浏览器访问 http://localhost(或 http://localhost:8080 如果改端口)。
  • 云部署:推送镜像或直接用 docker-compose.yml 构建,RDS 初始化 db.sql。
  • 零错误:健康检查、IF NOT EXISTS、日志调试确保无误。

如果遇到问题(e.g., 页面空白、API 404),分享 docker logs 输出或错误信息,我可进一步协助!

http://www.dtcms.com/a/496044.html

相关文章:

  • Spring依赖注入
  • 网站代码如何做优化金融投资网站方案
  • 深度剖析:KWDB SQL 编译与优化策略
  • 前端学习 10-3 :验证中的SV
  • Linux小课堂: 用户管理与权限控制机制详解
  • 四川网站seowordpress标题分隔符
  • 前端角度实现网站首页加载慢优化衡阳网站推广优化公司
  • 网站增加关键词正规网站开发需要哪些技术
  • 即墨做砍价小程序最好的网站系统开发
  • 数据库-联表查询
  • 德化网站建设新开的网页游戏大全
  • 仿网站建设平凉哪家做企业网站
  • 长沙岳麓区做网站湘潭做网站选择磐石网络
  • 简述网站设计规划的步骤响应式网站开发
  • CF2124B Minimise Sum 题解
  • 招标网站有哪些成长厉程网站
  • 购物网站哪个最便宜网站建设 统一质量标准
  • 多模态大模型OCR幻觉缓解思路:DianJin-OCR-R1通过“再看一眼”图像减轻幻觉
  • JJJ:SD 卡中的 OCR(Operating Conditions Register)寄存器
  • 手机网站图片切换网站设计师需要什么知识与技能
  • 20251017流程控制Demo
  • 浔川 AI 翻译 v7.0 公测版介绍(即将上线)
  • CPU性能对GPU服务器有影响吗?
  • 安徽省港航建设投资集团网站牛商网网站后台
  • 永磁体的磁导率
  • 亚马逊网站建设进度计划网站怎么做落款
  • h5模板网站西安到北京的高铁
  • wordpress建站两秒打开论坛模板建站
  • AI服务器工作之服务器的种类分类
  • 校园网站建设的目的中国建设机械教育协会网站