Java 前后端可部署落地架构方案

适配上面开发管理规范,单体 / 微服务两套架构,包含目录结构、Docker 部署、Nginx 配置、环境配置、数据库脚本示例,可直接复制落地,技术栈:SpringBoot2.7.x + Vue3 + MyBatis‑Plus + Mysql8 + Redis6,容器化 Docker Compose 一键部署。

一、整体架构分层

复制代码
客户端浏览器
     ↓
Nginx(静态前端资源、反向代理、负载均衡、跨域、SSL)
     ↓
┌───────────────┐
│ Java后端服务   │ Controller → Service → Mapper → Mysql
│               │ 缓存层:Redis
└───────────────┘

环境严格区分 dev/test/prod三套,配置外置;生产禁止硬编码密钥,日志按文件滚动,优雅停机。

二、后端 SpringBoot 工程目录(可直接创建)

复制代码
backend-java/
├── src/main/java/com/company/demo
│   ├── controller        # 接口控制器,只做参数接收返回,无业务
│   ├── service
│   │   └── impl          # 业务实现,事务写在此层
│   ├── mapper            # MyBatis‑Plus Mapper接口
│   ├── entity            # 数据库实体
│   ├── dto               # 入参对象
│   ├── vo                # 返回前端出参对象,禁止直接返回entity
│   ├── common
│   │   ├── result        # 统一返回体 Result<T>
│   │   ├── exception     # 全局异常处理器、自定义业务异常
│   │   ├── constant      # 常量
│   │   └── util          # 工具类
│   ├── config            # Web配置、拦截器、线程池、MybatisPlus配置
│   └── DemoApplication.java  # 启动类
├── src/main/resources
│   ├── mapper            # xml文件
│   ├── application.yml        # 公共配置
│   ├── application-dev.yml    # 开发环境
│   ├── application-test.yml    # 测试环境
│   └── application-prod.yml   # 生产环境(密钥使用环境变量注入)
├── src/test/java          # 单元测试
├── Dockerfile             # 后端docker构建文件
└── pom.xml

pom.xml 核心依赖片段

复制代码
<?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>2.7.18</version>
        <relativePath/>
    </parent>
    <groupId>com.company</groupId>
    <artifactId>demo‑backend</artifactId>
    <version>1.0.0</version>
    <properties>
        <java.version>1.8</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‑validation</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis‑plus‑boot‑starter</artifactId>
            <version>3.5.3.1</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql‑connector‑java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring‑boot‑maven‑plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

application.yml 公共配置

复制代码
spring:
  profiles:
    active: prod
  jackson:
    date‑format: yyyy‑MM‑dd HH:mm:ss
    time‑zone: GMT+8

mybatis‑plus:
  mapper‑locations: classpath:mapper/**/*.xml
  configuration:
    map‑underscore‑to‑camel‑case: true
    log‑impl: org.apache.ibatis.logging.nologging.NoLogImpl #生产关闭sql打印

logging:
  config: classpath:logback‑spring.xml

application‑prod.yml(生产配置,密码从环境变量读取,禁止写死)

复制代码
spring:
  datasource:
    driver‑class‑name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://mysql:3306/demo_db?useUnicode=true&characterEncoding=utf‑8&serverTimezone=Asia/Shanghai
    username: ${DB_USER}
    password: ${DB_PWD}
  redis:
    host: redis
    port: 6379
    password: ${REDIS_PWD}

server:
  port: 8080
  shutdown: graceful #优雅停机

后端 Dockerfile

复制代码
FROM openjdk:8‑jre‑slim
WORKDIR /app
COPY target/demo‑backend‑1.0.0.jar app.jar
EXPOSE 8080
ENV JAVA_OPTS="-Xms512m -Xmx512m"
ENTRYPOINT ["sh","-c","java $JAVA_OPTS -jar app.jar"]

三、前端 Vue3 工程目录(Vite)

复制代码
frontend‑vue/
├── src
│   ├── api            # 接口请求统一封装,禁止页面直接写axios
│   ├── views          # 页面组件
│   ├── components     # 公共组件
│   ├── router         # 路由
│   ├── store          # pinia状态管理
│   ├── utils
│   │   └── request.js # axios拦截器
│   └── assets         # 静态资源
├── .env.development
├── .env.production
├── vite.config.js
├── Dockerfile
└── package.json

.env.production

复制代码
VITE_API_BASE_URL=/api

前端 Dockerfile(构建静态资源,Nginx 承载)

复制代码
FROM node:16‑alpine as build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx","‑g","daemon off;"]

nginx.conf(关键:前端静态 + 后端接口反向代理)

复制代码
server {
    listen 80;
    root /usr/share/nginx/html;
    index index.html;

    # history模式路由
    location / {
        try_files $uri $uri/ /index.html;
    }

    # 将/api请求转发java后端
    location /api/ {
        proxy_pass http://backend‑java:8080/;
        proxy_set_header Host $host;
        proxy_set_header X‑Real‑IP $remote_addr;
        proxy_set_header X‑Forwarded‑For $proxy_add_x_forwarded_for;
    }
}

四、docker‑compose.yml 一键编排(整套启动)

放在项目根目录,docker compose up -d直接拉起整套环境:mysql、redis、java 后端、nginx 前端

复制代码
version: "3.8"
services:
  mysql:
    image: mysql:8.0
    container_name: demo‑mysql
    environment:
      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PWD}
      MYSQL_DATABASE: demo_db
    volumes:
      - ./mysql‑data:/var/lib/mysql
      - ./init‑sql:/docker‑entrypoint‑initdb.d
    ports:
      - "3306:3306"
    restart: always

  redis:
    image: redis:6‑alpine
    container_name: demo‑redis
    command: redis‑server --requirepass ${REDIS_PWD}
    volumes:
      - ./redis‑data:/data
    ports:
      - "6379:6379"
    restart: always

  backend‑java:
    build: ./backend‑java
    container_name: demo‑backend
    environment:
      DB_USER: root
      DB_PWD: ${DB_ROOT_PWD}
      REDIS_PWD: ${REDIS_PWD}
    depends_on:
      - mysql
      - redis
    restart: always

  frontend‑nginx:
    build: ./frontend‑vue
    container_name: demo‑frontend
    ports:
      - "80:80"
    depends_on:
      - backend‑java
    restart: always

.env 环境变量文件(docker compose 读取,不要提交 git)

复制代码
DB_ROOT_PWD=MyDbPass123!
REDIS_PWD=MyRedisPass456!

五、数据库初始化脚本 init‑sql/init.sql

复制代码
CREATE DATABASE IF NOT EXISTS demo_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE demo_db;

CREATE TABLE `sys_user` (
  `id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',
  `username` varchar(64) NOT NULL COMMENT '账号',
  `password` varchar(128) NOT NULL COMMENT '密码',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';

六、上线部署操作步骤(匹配前面发版规范)

  1. 后端:mvn clean package -DskipTests,生成 jar 包
  2. 前端:npm run build生成 dist 静态资源
  3. 将整套代码传到服务器,.env配置生产真实密码
  4. 初始化数据库脚本
  5. docker compose up -d --build构建并启动全部服务
  6. 访问服务器 IP 即可打开前端页面,接口由 Nginx 转发到 Java 后端
  7. 查看日志:docker compose logs -f backend‑java排查后端问题

七、生产环境关键约束(和管理手册对齐)

  1. git 禁止提交 .env、本地配置;密码全部通过容器环境变量注入
  2. 生产 profile 关闭 swagger、关闭 SQL 打印日志
  3. JVM 参数在 docker 环境变量JAVA_OPTS调整,根据服务器内存设置
  4. 数据库、redis 数据目录挂载宿主机,定时备份挂载目录
  5. 发版:更新代码后执行 docker compose up -d --build;回滚直接使用旧镜像版本
  6. 服务器不要直接暴露 mysql、redis 端口到公网,docker 内部网络互通
相关推荐
IT小白杨1 小时前
跨境电商账号关联归因链路拆解与可落地环境配置
服务器·网络·经验分享·安全·指纹浏览器
OpenTiny社区1 小时前
从开发到运行:OpenTiny NEXT 如何构建 Agent 时代的 Web 应用
前端·开源·ai编程·opentiny
feixing_fx1 小时前
伪类与伪元素的魔法:纯 CSS 打造炫酷的按钮悬停特效
前端·css·css3
动恰客流统计1 小时前
用客流数据优化门店排班:高峰不缺人、平峰不浪费的落地路径
大数据·前端·人工智能
网硕互联的小客服1 小时前
可以把服务器当成DNS服务器使用吗?如何操作?
运维·服务器·网络
广州山泉婚姻1 小时前
前后端分离的核心优势
前端·后端
志尊宝1 小时前
Vue3 零基础每日笔记(043):defineModel 与 defineExpose 的 TS 用法——3.4+ 新 API 进阶
前端·javascript·vue·html·vue3
洛兮银儿1 小时前
前端页面引入cesium
前端·cesium
梦想平凡1 小时前
情怀棋牌源代码焕新记录(一):全新国风UI与原版工程梳理
java·服务器·数据库·websocket·网络协议·cocos2d