docker-compose一键部署全栈项目。springboot后端,react前端

部署总览

  • 前端打包 : 我们将配置 package.json,使用 npm run build (内部调用 vite build) 来打包。这个过程将完全在 Docker 构建镜像的过程中自动完成,你的主机上甚至不需要安装 Node.js。

  • 后端打包 : 我们将配置 pom.xml,使用 mvn clean package 来打包。这一步需要在执行 Docker Compose 之前手动完成一次,以生成 JAR 文件。

  • 部署 : 使用 docker-compose up 一键启动所有服务。

第一步:最终项目结构

请在你的电脑上创建如下的完整目录和文件结构。你只需将已有的代码复制到对应的 src 目录,并用下面提供的内容创建或覆盖配置文件。

复制代码
/my-fullstack-app              # 你的项目根目录
|
├── docker-compose.yml         # ✅ (下面提供内容)
|
├── .env                       # ✅ (下面提供内容)
|
├── backend/                   # 后端 Spring Boot 项目
│   ├── src/main/java/         # 你的 Java 源代码放在这里
│   ├── src/main/resources/
│   │   └── application.properties # ✅ (下面提供内容)
│   ├── pom.xml                # ✅ (下面提供内容)
│   └── Dockerfile             # ✅ (下面提供内容)
|
├── frontend/                  # 前端 Vite + React 项目
│   ├── src/                   # 你的 React 源代码放在这里
│   ├── public/
│   ├── .env.production        # ✅ (下面提供内容)
│   ├── package.json           # ✅ (下面提供内容)
│   └── Dockerfile             # ✅ (下面提供内容)
│   ├── index.html             # ✅ (下面提供内容)
│   └── vite.config.js         # ✅ (下面提供内容)
|
└── nginx/
    └── nginx.conf             # ✅ (下面提供内容)

第二步:配置后端项目 (Spring Boot)

文件 1: backend/pom.xml

这个文件定义了项目依赖和 最重要的打包插件 (spring-boot-maven-plugin)。

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.5</version> <relativePath/> </parent>
    <groupId>com.example</groupId>
    <artifactId>my-backend</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>my-backend</name>
    <description>My Spring Boot Backend</description>

    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>

        </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
文件 2: backend/src/main/resources/application.properties

配置文件,用于从环境变量中读取数据库连接信息。

复制代码
# 服务器端口
server.port=8080

# 数据库连接配置 (值将由 Docker Compose 环境变量注入)
spring.datasource.url=jdbc:mysql://${SPRING_DATASOURCE_HOST:db}:${SPRING_DATASOURCE_PORT:3306}/${MYSQL_DATABASE}?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
spring.datasource.username=${MYSQL_USER}
spring.datasource.password=${MYSQL_PASSWORD}
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# JPA/Hibernate 配置
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
文件 3: backend/Dockerfile

用于构建后端服务镜像。

复制代码
# 使用一个包含 Java 17 JRE 的官方镜像
FROM eclipse-temurin:17-jre-alpine

# 设置工作目录
WORKDIR /app

# 将打包好的 JAR 文件复制到容器中,并重命名为 app.jar
# target/*.jar 会匹配 target 目录下的任何 .jar 文件
COPY target/*.jar app.jar

# 暴露 Spring Boot 应用的端口
EXPOSE 8080

# 容器启动时运行 java -jar 命令
ENTRYPOINT ["java", "-jar", "app.jar"]

第三步:配置前端项目 (Vite + React)

文件 1: frontend/package.json

这个文件定义了前端依赖和 打包脚本 build

复制代码
{
  "name": "my-frontend",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0",
    "preview": "vite preview"
  },
  "dependencies": {
    "axios": "^1.7.2",
    "react": "^18.2.0",
    "react-dom": "^18.2.0"
  },
  "devDependencies": {
    "@types/react": "^18.2.66",
    "@types/react-dom": "^18.2.22",
    "@vitejs/plugin-react": "^4.2.1",
    "eslint": "^8.57.0",
    "eslint-plugin-react": "^7.34.1",
    "eslint-plugin-react-hooks": "^4.6.0",
    "eslint-plugin-react-refresh": "^0.4.6",
    "vite": "^5.2.0"
  }
}
文件 2: frontend/.env.production

生产环境变量,VITE_API_BASE_URL 会在 npm run build 时被嵌入代码。

复制代码
VITE_API_BASE_URL=/api
文件 3: frontend/Dockerfile

多阶段构建 Dockerfile,它会自动执行 npm installnpm run build

复制代码
# ----- Build Stage -----
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
# 运行在 package.json 中定义的 "build" 脚本
RUN npm run build

# ----- Production Stage -----
FROM nginx:stable-alpine
# 从 'builder' 阶段复制构建好的静态文件 (在 /app/dist 目录中)
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

第四步:配置 Nginx 和 Docker Compose

文件 1: nginx/nginx.conf

Nginx 配置文件,用于托管前端静态文件和反向代理后端 API。

复制代码
server {
    listen 80;
    server_name localhost;

    # 根目录指向容器内 Nginx 存放静态文件的位置
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
        # 单页应用(SPA)路由配置,避免刷新404
        try_files $uri $uri/ /index.html;
    }

    # API 反向代理配置
    location /api/ {
        # 将请求转发给名为 'backend' 的服务 (由 Docker Compose 定义)
        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;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
文件 2: .env (在项目根目录)

存放所有密码和配置,此文件绝对不要上传到 Git 仓库

复制代码
# /my-fullstack-app/.env

# --- MySQL 配置 ---
# 请务必修改成你的强密码
MYSQL_ROOT_PASSWORD=your_strong_root_password
MYSQL_DATABASE=my_app_db
MYSQL_USER=my_app_user
MYSQL_PASSWORD=your_strong_password

# --- Spring Boot 将使用的环境变量 ---
SPRING_DATASOURCE_HOST=db
SPRING_DATASOURCE_PORT=3306
文件 3: docker-compose.yml (在项目根目录)

最终的编排文件,它将所有服务串联起来。

复制代码
version: '3.8'

services:
  # 前端服务 (Nginx)
  frontend:
    build:
      context: ./frontend
    container_name: my-app-frontend
    ports:
      - "80:80"
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro
    depends_on:
      - backend
    restart: always
    networks:
      - app-network

  # 后端服务 (Spring Boot)
  backend:
    build:
      context: ./backend
    container_name: my-app-backend
    environment:
      - MYSQL_DATABASE=${MYSQL_DATABASE}
      - MYSQL_USER=${MYSQL_USER}
      - MYSQL_PASSWORD=${MYSQL_PASSWORD}
      - SPRING_DATASOURCE_HOST=${SPRING_DATASOURCE_HOST}
      - SPRING_DATASOURCE_PORT=${SPRING_DATASOURCE_PORT}
    depends_on:
      db:
        condition: service_healthy
    restart: always
    networks:
      - app-network

  # 数据库服务 (MySQL)
  db:
    image: mysql:8.0
    container_name: my-app-db
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
      - MYSQL_DATABASE=${MYSQL_DATABASE}
      - MYSQL_USER=${MYSQL_USER}
      - MYSQL_PASSWORD=${MYSQL_PASSWORD}
    volumes:
      # 持久化数据库数据
      - mysql-data:/var/lib/mysql
      # ✅ 将你的初始化 SQL 文件挂载到容器的初始化目录
      - ./backend/src/main/resources/db.sql:/docker-entrypoint-initdb.d/init.sql
    ports:
      - "3307:3306"
    healthcheck:
      test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost", "-u", "${MYSQL_USER}", "-p${MYSQL_PASSWORD}"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: always
    networks:
      - app-network

# 定义共享网络
networks:
  app-network:
    driver: bridge

# 定义数据卷
volumes:
  mysql-data:
    driver: local

第五步:打包和一键部署的完整命令

现在,万事俱备。你只需要按顺序执行以下命令。

1. 【手动】打包后端 Spring Boot 项目

这是在运行 docker-compose 之前唯一需要手动执行的打包步骤。

复制代码
# 首先,进入后端项目目录
cd backend

# 执行 Maven 打包命令。(-DskipTests 会跳过测试,加快打包速度)
# Mac/Linux:
mvn clean package -DskipTests

# Windows (CMD):
# mvnw.cmd clean package -DskipTests

# 这会在 backend/target/ 目录下生成一个 .jar 文件。

# 完成后,返回项目根目录
cd ..
2. 【自动】一键构建并启动所有服务

确保你在项目根目录 /my-fullstack-app 下执行此命令。 这个命令会自动完成前端的打包(在 Docker 内部)、构建所有镜像并启动容器。

复制代码
# --build: 强制重新构建镜像 (当你修改了代码时使用)
# -d: 后台运行
docker-compose up --build -d
3. 验证部署
  • 访问前端 : 打开浏览器,访问 http://localhost

  • 检查 API: 在你的应用中进行需要调用后端的操作,确认功能正常。

  • 查看日志 : 如果遇到问题,使用 docker-compose logs -f backenddocker-compose logs -f frontend 查看实时日志。

4. 管理服务
复制代码
# 查看所有正在运行的容器
docker-compose ps

# 停止并移除所有容器
docker-compose down
docker-compose down --rmi all --volumes

你现在拥有了一个完整的、可重复的、自动化的部署流程。以后每次更新代码,流程都一样:

  1. 如果后端代码变了,就去 backend 目录执行 mvn clean package -DskipTests

  2. 回到根目录,执行 docker-compose up --build -d。 就是这么简单!

相关推荐
程序员张32 小时前
Maven编译和打包插件
java·spring boot·maven
Johny_Zhao4 小时前
Docker + CentOS 部署 Zookeeper 集群 + Kubernetes Operator 自动化运维方案
linux·网络安全·docker·信息安全·zookeeper·kubernetes·云计算·系统运维
灵犀学长4 小时前
EasyExcel之SheetWriteHandler:解锁Excel写入的高阶玩法
spring boot·excel
代码老y6 小时前
Docker:容器化技术的基石与实践指南
运维·docker·容器
像风一样自由20206 小时前
HTML与JavaScript:构建动态交互式Web页面的基石
前端·javascript·html
aiprtem7 小时前
基于Flutter的web登录设计
前端·flutter
DuelCode7 小时前
Windows VMWare Centos Docker部署Springboot 应用实现文件上传返回文件http链接
java·spring boot·mysql·nginx·docker·centos·mybatis
浪裡遊7 小时前
React Hooks全面解析:从基础到高级的实用指南
开发语言·前端·javascript·react.js·node.js·ecmascript·php
优创学社27 小时前
基于springboot的社区生鲜团购系统
java·spring boot·后端