若依ruoyi前后端分离项目自定义context-path的Nginx配置实战
1. 为什么需要自定义context-path在实际开发中我们经常会遇到需要修改SpringBoot项目默认context-path的情况。比如多个项目需要部署在同一台服务器上或者需要给API接口添加统一的前缀。以若依(RuoYi)框架为例默认的访问路径是/但你可能希望改成/cnAdminRy/这样的自定义路径。我遇到过这样一个场景客户要求所有管理系统的URL都要以公司缩写开头。这时候就需要修改context-path但改完之后发现前端页面访问后端接口全部404。这就是典型的context-path修改后Nginx配置没有同步调整导致的。2. 修改SpringBoot项目的context-path首先我们需要在SpringBoot项目中修改context-path。这个配置通常在application.yml或application.properties文件中server: servlet: context-path: /cnAdminRy修改后启动项目你会发现所有接口的访问路径都变成了http://localhost:8118/cnAdminRy/xxx。这一步很简单但很多人会忽略接下来需要同步修改前端配置。3. 调整Vue前端配置前后端分离项目中前端需要知道后端API的基础路径。在若依框架中这个配置在vue.config.js文件中module.exports { publicPath: process.env.NODE_ENV production ? /cnAdminRy/ : /, devServer: { proxy: { /cnAdminRy: { target: http://localhost:8118, changeOrigin: true, pathRewrite: { ^/cnAdminRy: /cnAdminRy } } } } }这里有两个关键点需要注意publicPath必须和后端的context-path保持一致开发环境下的代理配置也需要相应调整4. Nginx核心配置详解接下来是最关键的Nginx配置部分。假设你的前端项目部署在/usr/share/nginx/html/cn-ruoyi-admin目录后端运行在8118端口server { listen 80; server_name yourdomain.com; root /usr/share/nginx/html/cn-ruoyi-admin; location /cnAdminRy/ { try_files $uri $uri/ /cnAdminRy/index.html; } location /cnAdminRy/prod-api/ { proxy_pass http://localhost:8118/cnAdminRy/; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 解决POST请求变成GET的问题 proxy_method POST; if ($request_method OPTIONS) { add_header Access-Control-Allow-Methods GET, POST, OPTIONS; add_header Access-Control-Allow-Headers DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range; add_header Access-Control-Max-Age 1728000; add_header Content-Type text/plain; charsetutf-8; add_header Content-Length 0; return 204; } } }这个配置有几个关键点前端路由处理要使用try_files指向index.html代理路径必须包含context-path特别注意斜杠的使用少一个斜杠可能导致代理失败5. 常见问题排查指南在实际部署过程中我遇到过不少坑这里分享几个典型问题的解决方法问题1页面能打开但所有接口返回404检查Nginx的proxy_pass是否包含context-path确认后端服务确实运行在指定的context-path下问题2刷新页面后出现404确保location块中有正确的try_files配置检查root指令指向的目录是否正确问题3POST请求变成了GET添加proxy_method POST配置检查OPTIONS请求的处理问题4静态资源加载失败确认publicPath配置正确检查Nginx的root目录权限6. 性能优化建议配置正确后还可以考虑以下优化措施启用gzip压缩gzip on; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xmlrss text/javascript;静态资源缓存location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ { expires 365d; add_header Cache-Control public, no-transform; }连接池优化upstream backend { server localhost:8118; keepalive 32; } location /cnAdminRy/prod-api/ { proxy_pass http://backend/cnAdminRy/; proxy_http_version 1.1; proxy_set_header Connection ; }7. 容器化部署注意事项如果你使用Docker部署有几个额外需要注意的点Nginx容器和后端服务容器的网络通信静态资源目录的挂载环境变量的传递一个典型的docker-compose配置示例version: 3 services: nginx: image: nginx:alpine ports: - 80:80 volumes: - ./dist:/usr/share/nginx/html/cn-ruoyi-admin - ./nginx.conf:/etc/nginx/conf.d/default.conf depends_on: - backend backend: image: your-springboot-image environment: - SERVER_SERVLET_CONTEXT_PATH/cnAdminRy ports: - 8118:81188. 实际项目中的经验分享在最近的一个政府项目中我们遇到了一个特殊需求需要在同一个域名下部署多个若依系统每个系统有独立的context-path。比如/systemA/ 对应第一个管理系统/systemB/ 对应第二个管理系统最终的Nginx配置是这样的server { listen 80; server_name gov.example.com; location ^~ /systemA/ { alias /usr/share/nginx/html/systemA/; try_files $uri $uri/ /systemA/index.html; location /systemA/prod-api/ { proxy_pass http://localhost:8118/systemA/; # 其他代理配置... } } location ^~ /systemB/ { alias /usr/share/nginx/html/systemB/; try_files $uri $uri/ /systemB/index.html; location /systemB/prod-api/ { proxy_pass http://localhost:8119/systemB/; # 其他代理配置... } } }这个方案成功实现了多个系统共存的需求关键点在于使用alias而不是root指令每个系统有独立的前端构建目录和后端服务端口注意location匹配顺序使用^~确保精确匹配