将Vue前端和Spring Boot后端部署在同一台服务器如何实现?

将 Vue 前端和 Spring Boot 后端部署在同一台服务器上是常见且高效的部署方式。通常的做法是:使用 Spring Boot 作为后端服务处理 API 请求,同时托管编译后的 Vue 前端静态资源(HTML、JS、CSS 等)。以下是详细实现步骤:


🧩 一、项目结构规划

假设你的服务器上运行一个 Java 应用(Spring Boot),你希望它同时提供前端页面。

your-spring-boot-project/
├── src/
│   └── main/
│       ├── java/             # 后端代码
│       ├── resources/
│       │   ├── static/       # Vue 打包后的文件放在这里
│       │   │   ├── css/
│       │   │   ├── js/
│       │   │   └── index.html
│       │   └── application.yml
│       └── resources/static/ # 或者直接放这里也行
└── pom.xml

✅ 步骤 1:构建 Vue 项目(生成静态文件)

在本地开发完成后,执行打包命令:

npm run build
# 或 yarn build

这会在 dist/ 目录下生成生产环境的静态文件,例如:

dist/
├── index.html
├── assets/css/app.xxxx.css
├── assets/js/app.xxxx.js

✅ 步骤 2:将 Vue 静态文件复制到 Spring Boot 的 static 目录

dist 文件夹下的所有内容复制到 Spring Boot 项目的 src/main/resources/static/ 目录中。

⚠️ 注意:不要复制整个 dist 文件夹,而是复制其内部的内容。

例如:

cp -r dist/* your-spring-boot-project/src/main/resources/static/

这样访问根路径 / 时,Spring Boot 就会自动返回 index.html


✅ 步骤 3:配置 Spring Boot 支持单页应用(SPA)路由

Vue Router 使用 history 模式时,刷新页面会出现 404 错误,因为后端没有对应路径的接口。

解决方法:添加一个兜底路由,将所有未知请求都转发到 index.html

方法一:使用 @Controller 返回 index.html

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class SpaController {

    @GetMapping(value = {"/", "/login", "/dashboard", "/user/**", "/api-docs/**"}) // 添加你需要支持的前端路由
    public String index() {
        return "index.html"; // 返回 static 目录下的 index.html
    }
}

💡 注意:这个方法只适用于非 API 路由。确保你的 API 是以 /api 开头,避免冲突。

方法二:使用 WebMvcConfigurer(推荐)

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**")
                .addResourceLocations("classpath:/static/")
                .setCachePeriod(3600)
                .resourceChain(true);
    }

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/{spring:\w+}")
                .setViewName("forward:/index.html");
        registry.addViewController("/**/{spring:\w+}")
                .setViewName("forward:/index.html");
        registry.addViewController("/{spring:\w+}/**{spring:?!(\.js|\.css|\.png|\.jpg|\.gif|\.ico|\.svg)$}")
                .setViewName("forward:/index.html");
    }
}

或者更简单粗暴的方式(适合 history 模式):

@Bean
public ViewResolver viewResolver() {
    return new InternalResourceViewResolver() {{
        setPrefix("/static/");
        setSuffix(".html");
    }};
}

// 兜底路由
@GetMapping("/{path:[^\.]*}")
public String redirectApi() {
    return "forward:/";
}

✅ 步骤 4:确保 API 和静态资源路径不冲突

建议将所有后端 API 接口统一加上前缀,如 /api/**,避免与前端路由混淆。

@RestController
@RequestMapping("/api/user")
public class UserController {
    // ...
}

✅ 步骤 5:打包并部署到服务器

打包 Spring Boot 应用

mvn clean package

生成 target/your-app.jar

上传到服务器并运行

scp target/your-app.jar user@your-server:/opt/app/
ssh user@your-server

# 运行
nohup java -jar your-app.jar > app.log 2>&1 &

或使用 systemd 守护进程管理。


✅ 步骤 6:(可选)使用 Nginx 反向(推荐用于生产)

虽然可以直接通过 Spring Boot 提供前端,但更推荐使用 Nginx 来托管静态资源,提高性能和安全性。

Nginx 配置示例:

server {
    listen 80;
    server_name your-domain.com;

    # 托管 Vue 静态文件
    location / {
        root /var/www/vue-app;
        try_files $uri $uri/ /index.html;
    }

    # 将 API 请求到 Spring Boot
    location /api/ {
        proxy_pass http://localhost:8080/api/;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

此时 Spring Boot 只负责提供 API,不托管前端文件。


🔁 总结:两种主流方案对比

方案 说明 优点 缺点
Spring Boot 托管前端 把 Vue 打包文件放入 static,由 Spring Boot 返回 简单,一键部署 静态资源性能较差,占用 Java 内存
Nginx 托管前端 + Spring Boot 提供 API Nginx 处理静态资源,反向 API 到 Spring Boot 高性能、安全、可扩展 部署稍复杂

✅ 推荐生产环境使用 Nginx + Spring Boot 分离部署


🛠️ 补充建议

  • 使用 CI/CD 自动化构建部署流程(如 Jenkins、GitHub Actions)
  • 配置 HTTPS(Let’s Encrypt)
  • 设置 CORS(开发阶段),生产建议同源部署避免跨域

如有需要,我可以提供完整的项目结构示例或自动化脚本。欢迎继续提问!