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)路由配置,避免刷新404try_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: ./frontendcontainer_name: my-app-frontendports:- "80:80"volumes:- ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:rodepends_on:- backendrestart: alwaysnetworks:- app-network# 后端服务 (Spring Boot)backend:build:context: ./backendcontainer_name: my-app-backendenvironment:- 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_healthyrestart: alwaysnetworks:- app-network# 数据库服务 (MySQL)db:image: mysql:8.0container_name: my-app-dbenvironment:- 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.sqlports:- "3307:3306"healthcheck:test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost", "-u", "${MYSQL_USER}", "-p${MYSQL_PASSWORD}"]interval: 10stimeout: 5sretries: 5restart: alwaysnetworks:- 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。 就是这么简单!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/87535.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/87535.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MCMC:高维概率采样的“随机游走”艺术

MCMC&#xff08;马尔可夫链蒙特卡洛&#xff09; 是一种从复杂概率分布中高效采样的核心算法&#xff0c;它解决了传统采样方法在高维空间中的“维度灾难”问题。以下是其技术本质、关键算法及实践的深度解析&#xff1a; 本文由「大千AI助手」原创发布&#xff0c;专注用真话…

HarmonyOS免密认证方案 助力应用登录安全升级

6月21日&#xff0c;2025年华为开发者大会"安全与隐私分论坛"在松山湖顺利举办。本论坛聚焦App治理与监管、星盾安全2.0的核心能力等进行深度分享与探讨。其中&#xff0c;HarmonyOS Passkey免密认证方案作为安全技术创新成果备受瞩目。该方案基于FIDO协议实现&#…

flutter flutter_vlc_player播放视频设置循环播放失效、初始化后获取不到视频宽高

插件&#xff1a;flutter_vlc_player: ^7.4.3 问题1&#xff1a;设置循环播放_controller.setLooping(true);无用。 解决方法&#xff1a; //vlcPlayer设置循环播放失效&#xff0c;以这种方式失效循环播放 _setLoopListener() async {if (_videoController!.value.hasError…

React与Vue的主要区别

React和Vue都是当今最流行、最强大的前端Javascript框架&#xff0c;它们都能构建出色的单页面应用。 以下是React和Vue的主要区别&#xff1a; React&#xff1a; React官方自称是一个用于构建用户界面的JavaScript库&#xff08;尤其是UI组件&#xff09;。它专注于视图层。…

浏览器原生控件上传PDF导致hash值不同

用户要求对上传的pdf计算hash排重&#xff0c;上线后发现排重失败 1、postman直接调用接口没有发现问题&#xff0c;每次获取的hash值是一样的 2、apifox网页版&#xff0c;调用接口发现问题&#xff0c;清除缓存后&#xff08;将选择的文件删除重新选择&#xff09;&#xf…

.net 的依赖注入

依赖注入(Dependency Injection,简称 DI)是一种软件设计模式,旨在将对象之间的依赖关系从代码内部解耦出来,通过外部提供的方式来建立依赖关系,从而提高软件的可维护性、可测试性和可扩展性。以下从概念、工作原理、常见类型、在不同框架中的应用等方面进行详细解释: 概…

【unitrix】 4.17 类型级别右移运算实现解析(shr.rs)

一、源码 这段代码实现了类型级别的右移运算&#xff08;>>&#xff09;&#xff0c;包括对整数和定点数的支持。 /*类型级别的右移运算实现* 编制人: $ource* 修改版次:0版完成版* 本版次创建时间: 2025年6月27日* 最后修改时间: 2025年7月2日 Sub1修改* 待完善问题&a…

Java 并发核心:AQS(AbstractQueuedSynchronizer) 详解

一、什么是 AQS&#xff1f; AbstractQueuedSynchronizer&#xff08;简称 AQS&#xff09;是 Java 并发包 java.util.concurrent.locks 中的一个核心同步框架&#xff0c;用于构建锁和同步器&#xff0c;如&#xff1a; ReentrantLockReentrantReadWriteLockCountDownLatchS…

LoRA 实战指南:NLP 与 CV 场景的高效微调方法全解析

大模型已成 AI 应用的“标配”&#xff0c;但高昂的训练和部署成本让很多企业望而却步。LoRA&#xff08;Low-Rank Adaptation&#xff09;作为一种轻量级微调方案&#xff0c;正成为 NLP 与 CV 场景中低成本定制的利器。本文详细通过详细介绍 LoRA 的核心原理、在文本与图像任…

centos指令

一、python 1、查询运行中脚本 ps aux | grep python2、关闭脚本进程 kill -15 <PID> # 优雅终止&#xff08;SIGTERM&#xff09; kill -9 <PID> # 强制终止&#xff08;SIGKILL&#xff09;

用c语言写一个找两张图片不同处的游戏

回答 思考完成 我们计划开发一个用C语言实现的查找两张图片不同之处的游戏。这个程序需要加载两张图片&#xff0c;然后允许用户通过点击等方式标记出差异的位置。我们将使用一个简单的图形库&#xff08;例如SDL&#xff09;来处理图像和用户交互。步骤&#xff1a;1.加载两…

【深度学习:进阶篇】--4.3.seq2seq与Attention机制

学习目标 目标 掌握seq2seq模型特点掌握集束搜索方式掌握BLEU评估方法掌握Attention机制 应用 应用Keras实现seq2seq对日期格式的翻译 目录 学习目标 1.seq2seq 1.1.定义 1.2.条件语言模型理解 1.3.应用场景 2.注意力机制 2.1.长句子问题 2.2.定义 2.3.公式 3.机器…

MYSQL与PostgreSQL的差异

一、架构设计的根本差异 进程模型 vs 线程模型 ​PostgreSQL​&#xff1a;采用多进程架构&#xff08;每个连接独立进程&#xff09;&#xff0c;通过共享内存通信。优势在于进程隔离性强&#xff0c;单连接崩溃不影响整体服务&#xff0c;但资源消耗较高。 ​MySQL​&…

Wpf布局之StackPanel!

文章目录 前言一、引言二、使用步骤 前言 Wpf布局之StackPanel&#xff01; 一、引言 StackPanel面板在水平或垂直的堆栈中放置元素。这个布局容器通常用于更大、更复杂窗口中的一些区域。 二、使用步骤 StackPanel默认是垂直堆叠 <Grid><StackPanel><Butt…

【MySQL】 内置函数

目录 1.时间函数2.字符串函数3.数学函数4.其他函数 1.时间函数 函数名称描述current_date()当前日期current_time()当前时间current_timestamp()当前时间戳date(datetime)返回datetime参数的日期部分date_add(date,interval d_value_type)在date中添加日期/时间&#xff0c;in…

【RK3568+PG2L50H开发板实验例程】Linux部分/FAN 检测案例

本原创文章由深圳市小眼睛科技有限公司创作&#xff0c;版权归本公司所有&#xff0c;如需转载&#xff0c;需授权并注明出处&#xff08;www.meyesemi.com) 1.案例简介 本案例旨在介绍如何测试开发板上风扇接口控制风扇启停与调速功能 2. FAN接口介绍 开发板上 FAN接口是一个…

Spring AI ETL Pipeline使用指南

前言&#xff08;Introduction&#xff09; 版本声明&#xff1a;本文基于 Spring AI 1.0.0 版本编写。由于 Spring AI 目前仍处于活跃开发阶段&#xff0c;API 和组件可能在后续版本中发生变化&#xff0c;请注意及时关注官方文档更新以保持兼容性。 在当今大数据和人工智能快…

Docker 入门教程(九):容器网络与通信机制

文章目录 &#x1f433; Docker 入门教程&#xff08;九&#xff09;&#xff1a;容器网络与通信机制一、Docker 网络模型二、Docker 的四种网络类型三、容器间通信机制四、相关指令 &#x1f433; Docker 入门教程&#xff08;九&#xff09;&#xff1a;容器网络与通信机制 一…

从进攻性安全角度简析 Windows PowerShell

PowerShell 是 Windows 系统中强大的脚本语言和命令行工具&#xff0c;因其灵活性和与 .NET 框架的深度集成&#xff0c;成为攻击者执行恶意操作的热门选择。从进攻性安全视角看&#xff0c;PowerShell 的语言模式、执行策略&#xff08;Execution Policy&#xff09;、AMSI 绕…

MySQL的深度分页如何优化!

MySQL深度分页&#xff08;例如 LIMIT 1000000, 20&#xff09;性能差的主要原因在于 OFFSET 需要扫描并跳过大量数据&#xff0c;即使这些数据最终并不返回。随着 OFFSET 增大&#xff0c;性能会急剧下降。 以下是优化深度分页的常用策略&#xff0c;根据场景选择最适合的方案…