使用 nginx 同域名下部署多个 vue 项目,并使用反向代理
实际开发中,需要将多个 Vue 项目部署在同一台服务器,通过统一的域名/IP + 不同路径访问不同项目。
本文以 project1、project2 两个 Vue 项目为例,讲解如何通过 Vue 配置 + Nginx 反向代理实现以下访问效果:
# 访问 Nginx 根页面(自带的 index.html)
http://localhost:8080/
# 访问项目一
http://localhost:8080/project1
# 访问项目二
http://localhost:8080/project2
Vue 项目配置
以 Vue-CLI 2 为例搭建项目,核心是修改静态资源公共路径、接口代理前缀、路由基础路径三个关键配置,确保打包后的项目能适配 Nginx 的路径规则。
1. 配置静态资源公共路径
修改项目根目录下 config/index.js 文件,调整 build.assetsPublicPath(打包后的静态资源访问路径),需与后续 Nginx 配置的路径一致:
// project1 配置
module.exports = {
dev: {
// 开发环境配置(无需修改)
assetsPublicPath: '/'
},
build: {
// 生产环境配置:指定静态资源根路径为 /project1/
assetsPublicPath: '/project1/' // 注意:前后斜杠必须保留,否则会导致静态资源加载失败
}
}
// project2 配置
module.exports = {
dev: {
assetsPublicPath: '/'
},
build: {
assetsPublicPath: '/project2/' // 对应 Nginx 中的 /project2 路径
}
}
2. 配置接口代理前缀
修改 config/prod.env.js 文件,定义生产环境的接口请求前缀(需与 Nginx 的反向代理路径对应):
// project1 配置
module.exports = {
NODE_ENV: '"production"',
BASE_API: '"/api/pro1"' // 接口请求前缀,后续 Nginx 会代理此路径到后端服务
}
// project2 配置
module.exports = {
NODE_ENV: '"production"',
BASE_API: '"/api/pro2"' // 与 project1 区分,避免接口路径冲突
}
[注意] 如果你的项目中接口代理前缀不是 BASE_API,请替换为自己项目中的变量名(如 VUE_APP_BASE_API)。
3. 配置 Vue-Router 基础路径
修改路由配置文件(通常是 src/router/index.js),设置 base 属性(需与 build.assetsPublicPath 一致),并启用 history 模式(消除 URL 中的 #):
// project1 路由配置
import VueRouter from 'vue-router'
export default new VueRouter({
base: '/project1/', // 与 build.assetsPublicPath 完全一致
mode: 'history', // 采用 history 模式(hash 模式同理,无需额外修改)
scrollBehavior: () => ({ y: 0 }), // 路由切换时滚动到顶部
routes: [/* 你的路由规则 */]
})
// project2 路由配置
export default new VueRouter({
base: '/project2/', // 对应 project2 的路径
mode: 'history',
scrollBehavior: () => ({ y: 0 }),
routes: [/* 你的路由规则 */]
})
[注意] 执行 npm run build 时,若出现 .tap(*) 相关报错,是因为 html-webpack-plugin 版本兼容问题,需重新安装指定版本:
# 安装与项目兼容的版本(以 package.json 中记录的版本为准)
$ npm i html-webpack-plugin@4.0.0-alpha -D
Nginx 的配置
目录结构说明
首先确保 Nginx 目录结构符合要求(本文使用 Nginx 原生的 html 文件夹,便于快速验证):
.
├─conf
│ ├─... # 其他配置文件
│ └─nginx.conf # 核心配置文件
├─html # 静态资源根目录
│ ├─project1 # project1 打包后的文件(npm run build 输出)
│ │ ├─index.html
│ │ └─static # 静态资源(css/js/fonts 等)
│ ├─project2 # project2 打包后的文件
│ │ ├─index.html
│ │ └─static
│ ├─index.html # Nginx 原生根页面(自定义链接入口)
│ └─50x.html # 错误页面
└─... # 其他无关目录
[提示] 若需自定义目录,只需修改 Nginx 配置中的 root 路径即可,建议先按此结构验证,再调整为自己的目录。
2. nginx.conf 核心配置
修改 conf/nginx.conf 文件,核心配置在 http 模块下的 server 节点,以下是完整的关键配置(无关代码用 ... 省略):
# ... 其他全局配置
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
# 开启高效文件传输
sendfile on;
# 长连接超时时间
keepalive_timeout 65;
# 解决大文件上传问题
client_max_body_size 20M;
client_body_buffer_size 10M;
large_client_header_buffers 4 128k;
# 配置后端服务集群(示例:单节点,可扩展为多节点负载均衡)
upstream p1_server {
server localhost:8081; # project1 对应的后端服务地址
}
upstream p2_server {
server localhost:8082; # project2 对应的后端服务地址
}
# 核心服务器配置
server {
listen 8080; # 监听 8080 端口
server_name localhost; # 域名/IP,本地测试用 localhost
charset utf-8; # 避免中文乱码
# 代理超时配置
proxy_connect_timeout 180;
proxy_send_timeout 180;
proxy_read_timeout 180;
# 传递真实请求信息到后端
proxy_set_header Host $host;
proxy_set_header X-Forwarder-For $remote_addr;
root html; # 指定静态资源根目录(对应上面的 html 文件夹)
# 总的项目路由,我偷懒直接写在了同一个文件
# 如果有很多可以在配置多个 conf 文件,使用 include 关联进来
# 根路径:访问 http://localhost:8080/ 指向 html/index.html
location / {
try_files $uri $uri/ /index.html; # 解决 history 模式刷新 404 问题
}
# project1 路径:访问 http://localhost:8080/project1 指向 html/project1/index.html
# 这里就是刚刚我们在 vue 项目中 config/index.js 的配置 build.assetsPublicPath,
# 也是 vue 项目中配置的 router 中的 base
location ^~ /project1 {
try_files $uri $uri/ /project1/index.html; # 关键:匹配不到资源时返回项目入口文件
}
# project2 路径:同理 project1
location ^~ /project2 { #
try_files $uri $uri/ /project2/index.html;
}
# project1 接口代理:匹配 /api/pro1 前缀的请求,转发到 p1_server
location /api/pro1 { # 在 vue 项目中 prod.env.js 的配置 BASE_API
proxy_redirect off;
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_pass http://p1_server; # 转发到 upstream 配置的后端服务
}
# project2 接口代理:同理 project1
location /api/pro2 {
proxy_redirect off;
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_pass http://p2_server;
}
# ... 其他配置(如错误页面、日志等)
}
# ... 其他 server 配置
}
自定义 Nginx 根页面(index.html)
修改 html/index.html 文件,添加两个项目的访问链接(追加到原有内容后):
...
<!-- 原有内容 -->
<p><em>Thank you for using nginx.</em></p>
<!-- 新增:项目访问链接 -->
<hr>
<a href="/project1">项目一</a> | <a href="/project2">项目二</a>
<!-- 原有内容 -->
</body>
调试验证
打包部署
- 分别对
project1、project2执行npm run build; - 将打包后的
dist目录下的所有文件,分别复制到 Nginx 的html/project1、html/project2目录; - 保存 Nginx 配置文件,重启 Nginx(命令参考):
# Windows
nginx -s reload
# Linux/Mac
sudo nginx -s reload
访问验证
- 打开浏览器,输入
http://localhost:8080,可看到 Nginx 根页面及两个项目的链接; - 点击「项目一」,URL 变为
http://localhost:8080/project1,正常加载 project1 页面; - 点击「项目二」,URL 变为
http://localhost:8080/project2,正常加载 project2 页面; - 验证接口:项目中发起的
/api/pro1、/api/pro2前缀请求,能正确转发到对应的后端服务。
踩坑小记
配置完成后若启动 Nginx 报错,可先检查:
- 配置文件语法错误(执行
nginx -t验证); - Vue 配置中的路径是否带全斜杠(如
/project1/而非/project1); - Nginx 目录权限(确保能读取 html 文件夹);
- 端口是否被占用(8080/8081/8082)。
[强行解释一下玄学] 那天配置好了,一启动就报错,弄的我最后放弃了。但是第二天,准备在检查下,一启动竟然全好了,我都一脸懵逼啊! 如果你也遇到和我一样的问题,先放放,说不定隔天就好了。
总结
- 核心原则:Vue 项目的
assetsPublicPath、router.base需与 Nginx 的location路径完全一致,接口前缀需与 Nginx 代理路径匹配; - 关键配置:
try_files $uri $uri/ /xxx/index.html是解决 Vue history 模式刷新 404 的核心; - 扩展建议:若项目较多,可将每个项目的 Nginx 配置拆分到单独文件(如
conf.d/project1.conf),通过include引入,提升可维护性。
2026 年补充说明
若使用 Vue-CLI 3+ 或 Vite 构建项目,配置逻辑一致,但配置文件位置不同:
- Vue-CLI 3+:静态资源路径改为
vue.config.js中的publicPath; - Vite:静态资源路径改为
vite.config.js中的base,路由base配置不变;

浙公网安备 33010602011771号