前后端分离已成为Web开发的主流模式。前端专注于页面交互,后端专注于数据处理,通过API接口通信。这种架构提升了开发效率和系统的可维护性,但也带来了一个关键问题:如何将开发完成的前后端项目正确地打包并部署到服务器上?
本文将基于常见的**Vue.js(前端)和Spring Boot(后端)**项目,详细介绍从打包到部署全流程。
一、前端打包(以Vue为例)
1.1 打包命令
在Vue项目中,我们使用npm或yarn进行构建。通常,开发环境和生产环境的配置会有所区别(如API地址不同),因此需要准备对应的环境变量文件(.env.production)。
执行以下命令进行打包:
bash
npm run build
# 或
yarn build
执行成功后,会在项目根目录下生成一个**dist文件夹**,里面包含了压缩后的HTML、CSS、JS以及静态资源。
1.2 打包配置注意事项
-
publicPath :如果你的应用不是部署在域名的根路径下(例如部署在
http://example.com/myapp/),需要修改vue.config.js中的publicPath:javascript
module.exports = { publicPath: process.env.NODE_ENV === 'production' ? '/myapp/' : '/' } -
路由模式 :Vue Router默认使用hash模式(带
#),如果需要美观的history模式,需要在服务端做相应配置(如Nginx的try_files),否则直接访问子路由会404。 -
环境变量 :打包时会将
process.env.VUE_APP_API_BASE_URL等变量替换为实际值,确保API地址指向正确的后端服务器。
二、后端打包(以Spring Boot为例)
2.1 打包为可执行JAR
Spring Boot项目通常打包为可执行的JAR文件,内置了Tomcat服务器。使用Maven执行:
bash
mvn clean package
或使用Gradle:
bash
gradle bootJar
打包后,在target目录下会生成一个*.jar文件,比如myapp-0.0.1-SNAPSHOT.jar。
2.2 配置文件管理
生产环境的数据库连接、Redis地址等配置与开发环境不同,建议通过以下几种方式管理:
-
application-{profile}.yml :使用Spring的Profile机制,如
application-prod.yml,启动时指定--spring.profiles.active=prod。 -
外部配置文件:将配置文件放在jar包同级目录下,Spring Boot会自动加载。
-
环境变量 :通过操作系统的环境变量覆盖配置,如
export DB_URL=...。
2.3 打包为WAR(可选)
如果需要部署到外部Tomcat容器,可以将打包方式改为WAR。修改pom.xml:
xml
<packaging>war</packaging>
并排除内置Tomcat依赖。这里不再详述,JAR方式更为简单普遍。
三、部署方式对比
部署可以简单分为传统部署 (直接放在服务器上)和容器化部署(使用Docker等)。下面我们分别介绍两种方式的典型步骤。
四、传统部署步骤(Nginx + JAR)
4.1 环境准备
-
一台Linux服务器(本文以Ubuntu 20.04为例)
-
安装Java运行时(如OpenJDK 11)
-
安装Nginx
-
如果有数据库(如MySQL),也需要安装并初始化数据
4.2 后端部署
-
上传JAR包 :将打包好的JAR文件上传到服务器,例如放在
/opt/app/目录下。 -
启动脚本 :创建一个简单的启动脚本
start.sh:bash
#!/bin/bash nohup java -jar myapp.jar --spring.profiles.active=prod > app.log 2>&1 &赋予执行权限:
chmod +x start.sh,然后执行./start.sh启动。 -
检查运行状态 :
ps aux | grep java查看进程,或者访问http://服务器IP:8080/actuator/health(需引入Actuator依赖)。 -
防火墙放行 :如果使用云服务器,需要在安全组中开放8080端口(或自定义端口);本地服务器则使用
ufw allow 8080。
4.3 前端部署
-
上传dist目录 :将打包好的
dist文件夹上传到服务器,例如放在/var/www/html/下。 -
配置Nginx :编辑Nginx配置文件(如
/etc/nginx/sites-available/default),设置根目录并代理API请求:nginx
server { listen 80; server_name your_domain.com; # 前端静态文件 root /var/www/html/dist; index index.html; # 处理Vue history模式下的404问题 location / { try_files $uri $uri/ /index.html; } # 反向代理后端API location /api/ { proxy_pass http://localhost:8080/api/; # 后端地址 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } -
测试配置并重启Nginx:
bash
nginx -t systemctl reload nginx -
域名解析:将你的域名解析到服务器IP,即可通过域名访问前端页面。
4.4 跨域问题
如果你的前端和后端部署在不同的域名或端口下,就会遇到跨域问题。解决方法有两种:
-
后端添加CORS配置 :在Spring Boot中通过
@CrossOrigin或全局CORS配置允许前端域名访问。 -
Nginx反向代理 :如上面配置所示,将
/api/路径代理到后端,前端请求同域下的/api,自然不存在跨域。
建议使用Nginx代理方式,更安全且简洁。
五、容器化部署(Docker)
如果你熟悉Docker,容器化部署会更加一致和可移植。
5.1 前端Docker化
创建Dockerfile.frontend:
dockerfile
# 构建阶段
FROM node:14 as build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# 生产阶段
FROM nginx:stable-alpine
COPY --from=build-stage /app/dist /usr/share/nginx/html
# 如果有自定义nginx配置,可以复制
COPY nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
5.2 后端Docker化
创建Dockerfile.backend:
dockerfile
FROM openjdk:11-jre-slim
COPY target/myapp.jar /app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar", "--spring.profiles.active=prod"]
5.3 使用docker-compose统一编排
创建docker-compose.yml:
yaml
version: '3'
services:
backend:
build:
context: ./backend
dockerfile: Dockerfile.backend
ports:
- "8080:8080"
environment:
- SPRING_PROFILES_ACTIVE=prod
networks:
- app-net
frontend:
build:
context: ./frontend
dockerfile: Dockerfile.frontend
ports:
- "80:80"
depends_on:
- backend
networks:
- app-net
networks:
app-net:
然后在服务器上安装docker和docker-compose,上传项目,执行docker-compose up -d即可启动所有服务。
六、常见问题与解决方法
6.1 前端刷新后404(History模式)
如前面所述,在Nginx中添加try_files $uri $uri/ /index.html;即可。
6.2 后端端口被占用
使用lsof -i:8080查看端口占用,然后kill对应进程,或修改后端端口。
6.3 静态资源加载失败
检查Nginx的root路径是否正确,以及资源引用路径是否使用了正确的publicPath。
6.4 跨域问题(未使用Nginx代理)
若前后端分离部署在不同端口,后端需要允许跨域。Spring Boot示例:
java
@Configuration
public class CorsConfig {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://your-frontend-domain.com")
.allowedMethods("*");
}
};
}
}
七、自动化部署展望
手动上传文件、重启服务虽然可行,但容易出错且繁琐。更进一步的优化是使用CI/CD工具(如Jenkins、GitLab CI、GitHub Actions)实现自动化部署:代码推送后自动打包、测试、上传服务器并重启服务。这部分内容较多,可以作为后续文章的专题。
总结
前后端分离项目的打包部署并不复杂,关键是要理解每个环节的作用以及它们之间的协作方式。本文介绍了前端Vue的打包、后端Spring Boot的打包,并分别演示了传统Nginx+JAR部署和Docker容器化部署。希望这些内容能帮助你顺利地将项目发布到线上。