服务器部署
部署到云服务器/公网时,和本机体验最大的区别:必须改前端配置 + 给后端和 MinIO 配 Nginx 反代,否则页面打得开、却完全用不了。
本文一共就两件事:① 一次性改完前端
app.config.js;② 一次性配好 Nginx。别像某些教程把同类操作拆成好几步、让前端重建好几遍——这里每样只做一次。
1. 为什么需要改
默认配置是为本机体验设计的,前端 app.config.js 里两个地址都写死成本机回环地址:
"VITE_GLOB_API_URL": "http://localhost:7026", // 后端接口
"VITE_GLOB_FILE_URL": "http://127.0.0.1:9000" // MinIO 文件
前端代码是在用户浏览器里执行的,这两个地址里的 localhost / 127.0.0.1 指向的是用户自己的电脑,根本连不到服务器。结果就是:页面能打开,但登录、菜单、文件等请求全部失败。
解决办法:把这些地址改成服务器对外域名,再通过 Nginx 把后端、MinIO 反代到对外域名下。后端、MinIO 容器内部连接走 Docker 内网,完全不用动。
2. 先把服务跑起来
按 Docker 部署 在服务器上 docker compose up -d 拉起全套服务,确认端口已就绪:
| 容器 | 对外端口 | 作用 |
|---|---|---|
| sparkx-frontend | 8189 | 前端(Nginx 托管静态页) |
| sparkx-backend | 7026 | 后端(Spring Boot) |
| sparkx-minio | 9000 / 9001 | 对象存储 / 控制台 |
docker compose ps
此时直接访问 http://服务器IP:8189 能看到页面,但登录会失败——这正是本文要解决的问题。
假设你的域名是
your-domain.com,MinIO 用子域名minio.your-domain.com。下文按这两个举例,换成你自己的即可。两个域名的 DNS 都要解析到这台服务器。
3. 第一步:改前端配置(一次性改完)
前端的运行时配置在 docker/frontend/app.config.js(通过 bind mount 挂载进容器,改完重建即可,不用重新构建镜像)。
把里面的两个地址一次性改成对外域名:
window.__PRODUCTION__SPARKX智能体平台__CONF__ = {
"VITE_GLOB_APP_TITLE": "SparkX智能体平台",
"VITE_GLOB_APP_SHORT_NAME": "SparkX智能体平台",
"VITE_GLOB_API_URL": "http://your-domain.com", // ⬅️ 后端接口,改这里
"VITE_GLOB_API_URL_PREFIX": "",
"VITE_GLOB_UPLOAD_URL": "",
"VITE_GLOB_FILE_URL": "http://minio.your-domain.com" // ⬅️ MinIO 文件,改这里
};
字段说明:
| 字段 | 说明 | 示例 |
|---|---|---|
VITE_GLOB_API_URL |
后端接口域名,指向 Nginx 反代后的地址(不直接填 :7026) |
http://your-domain.com |
VITE_GLOB_FILE_URL |
MinIO 文件访问域名,指向 MinIO 的 Nginx 反代子域名 | http://minio.your-domain.com |
⚠️ 地址要用用户浏览器能访问到的那一个,不能用
localhost、127.0.0.1或 Docker 内网地址。结尾不要带端口(统一走 80)、不要带斜杠。
两个地址都改完后,重建前端容器一次即可生效:
docker compose up -d frontend
4. 第二步:配 Nginx 反代(一次性配完)
后端接口和 MinIO 都要反代。新建一个站点配置(或合并到已有的),例如 /etc/nginx/conf.d/sparkx.conf,一次性写完两个 server 块:
# ① 主站:前端 + 后端接口(同源,消除跨域)
server {
listen 80;
server_name your-domain.com;
# 前端静态页:8189 反代到 80
location / {
proxy_pass http://127.0.0.1:8189;
proxy_set_header Host $host;
}
# 后端接口:Spring Boot 在 7026,context-path 为 /
location /api/ {
proxy_pass http://127.0.0.1:7026/;
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_set_header X-Forwarded-Proto $scheme;
# 对话接口走流式输出(SSE),必须关缓冲,否则回答会卡很久一次性吐出
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_buffering off;
proxy_read_timeout 300s;
}
}
# ② MinIO 文件服务:子域名反代到 9000
server {
listen 80;
server_name minio.your-domain.com;
client_max_body_size 1024m; # 文件可能较大,放宽上传限制
location / {
proxy_pass http://127.0.0.1:9000;
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_read_timeout 300s;
}
}
要点说明:
| 配置 | 作用 |
|---|---|
主站 location / → 8189 |
对外只开 80,前端不再暴露 8189 |
主站 location /api/ → 7026 |
后端接口与前端同源,消除跨域;末尾 / 去掉 /api 前缀 |
主站 proxy_buffering off |
流式对话(SSE)必须关,否则体验异常 |
| MinIO 子域名 → 9000 | 文件走独立子域名,9000 端口可关闭对外访问 |
client_max_body_size 1024m |
MinIO 上传大文件需要 |
⚠️
location /api/前缀要和前端实际请求路径对得上。后端 context-path 是/,接口本身就是/api/xxx,前端VITE_GLOB_API_URL_PREFIX留空即可。
一次校验并生效:
nginx -t # 校验语法
nginx -s reload # 重新加载
💡 为什么不用动后端和 MinIO? 后端在容器里通过 Docker 内网域名
http://minio:9000连 MinIO,容器间直连,没问题;只有浏览器端的请求需要走对外域名,所以才只配前端 + Nginx。
5. 访问验证
浏览器打开:
http://your-domain.com
用 admin / 123456 登录。判断成功的标志:
- ✅ 能正常登录、左侧菜单加载出来 → 后端接口通了
- ✅ 进对话页,提问后回答逐字流式出现 → SSE 反代缓冲已关
- ✅ 上传文件后能下载/预览 → MinIO 地址配对了
- ❌ 登录 404 / 接口报错 →
VITE_GLOB_API_URL没改对,或 Nginx 反代没生效 - ❌ 控制台报 CORS → 前端还在直连 7026,没走 Nginx 反代
- ❌ 文件打不开、报「无法解析 127.0.0.1」→
VITE_GLOB_FILE_URL没改成子域名 - ❌ 文件报 502 / 连接被拒 → MinIO 子域名 DNS 没解析到服务器,或 Nginx 没 reload
6. 安全建议(生产环境)
至此系统已可用。生产环境建议再加固:
- 关闭对外端口:防火墙只放行 80(和 443),把
8189、7026、9000、9001等端口限制为只允许本机访问——前端、后端、MinIO 全部走 Nginx 域名反代,不必直接暴露这些端口 - 上 HTTPS:用 certbot 申请免费证书,Nginx 监听 443 并把 80 跳转过去,两个域名(
your-domain.com、minio.your-domain.com)都配上证书;同时把app.config.js里的VITE_GLOB_API_URL、VITE_GLOB_FILE_URL都改成https:// - 改默认密码:
admin/123456务必第一时间改掉;MinIO 的minioadmin/minioadmin也建议通过 compose 环境变量改掉
部署完成后,前往 完成第一个智能体 开始使用。