title: "14.3.4 部署前后端分离应用" 14.3.4 部署前后端分离应用 本节目标:掌握前后端分离架构的通用部署流程,学会用 Claude Code 辅助配置反向代理,适用于任何技术栈(Node.js / Python / PHP / Java / Go / .NET 等)。 14.3.2:适合 Next.js 这种"前后端一体"的全栈框架,一个容器搞定 本节(14.3.4):适合"前后端分离"的架构,前端和后端是独立的项目,需要分别部署 如果你的项目是 Next.js/Nuxt 等全栈框架,直接看 14.3.2 即可。如果你的前端是 React/Vue,后端是独立的 API 服务(Node.js/Python/Java 等),那就需要本节的方案。
title: "14.3.4 部署前后端分离应用"
本节目标:掌握前后端分离架构的通用部署流程,学会用 Claude Code 辅助配置反向代理,适用于任何技术栈(Node.js / Python / PHP / Java / Go / .NET 等)。
::: tip 本节与 14.3.2 的区别
如果你的项目是 Next.js/Nuxt 等全栈框架,直接看 14.3.2 即可。如果你的前端是 React/Vue,后端是独立的 API 服务(Node.js/Python/Java 等),那就需要本节的方案。
:::
小明的全栈项目有前端、后端 API、数据库三个部分。"之前在 Vercel 上是一个项目搞定,现在要分开部署?"
老师傅说:"Vercel 帮你把这些打包在一起了,但在自己的服务器上,你需要理解它们各自的角色。好处是——你对每一层都有完全的控制权。"
他画了一张图:"前后端分离的架构长这样——"
用户浏览器 │ ▼ OpenResty(反向代理):80 │ ├── / → 前端静态文件(HTML/CSS/JS) ├── /api/* → 后端服务(容器端口 3000/8000/8080...) │ └── 后端服务 │ ▼ 数据库(PostgreSQL/MySQL/MongoDB...)
三个服务各司其职:
::: tip 什么是反向代理?
反向代理就像一个"前台接待员":
/ → 返回前端页面/api/users → 转发给后端服务好处:
小明画了一张简单的图:用户请求先到 OpenResty,OpenResty 看路径——如果是 /api 开头就转给后端,其他的就返回前端页面。"原来 Vercel 在背后也是这么干的,只不过它帮我把这些全藏起来了。"
它们都运行在 Docker 容器里,通过容器网络互相通信。
无论你的后端是什么技术栈,部署流程都是类似的:
根据项目需求,在 1Panel 应用商店安装对应的数据库:
安装完成后,创建应用专用数据库和用户,记下连接信息(主机名、端口、用户名、密码)。
::: tip 1Panel 数据库容器命名规则
1Panel 创建的数据库容器名遵循 1Panel-{数据库类型}-{随机4位字母} 的格式:
1Panel-postgresql-ukow1Panel-redis-w94p1Panel-mysql-abcd1Panel-mongodb-xyz1如何查看实际的容器名:
在 1Panel 的「容器」页面,列表的第一列就是容器名。你也可以在「数据库」页面点击对应数据库的「详情」查看连接信息。
后端应用通过容器名(而非 localhost)连接数据库。
:::
::: details 常见数据库连接字符串示例
PostgreSQL:
DATABASE_URL="postgresql://用户名:密码@1Panel-postgresql-ukow:5432/数据库名"
MySQL:
DATABASE_URL="mysql://用户名:密码@1Panel-mysql-abcd:3306/数据库名"
Redis(有密码):
REDIS_URL="redis://:密码@1Panel-redis-w94p:6379"
Redis(无密码):
REDIS_URL="redis://1Panel-redis-w94p:6379"
MongoDB:
MONGODB_URI="mongodb://用户名:密码@1Panel-mongodb-xyz1:27017/数据库名"
:::
根据后端技术栈选择部署方式:
| 技术栈 | 1Panel 运行环境(语言) | 启动命令参考 |
|---|---|---|
| Node.js / Next.js | Node.js | git pull && pnpm build && pnpm start |
| Python / FastAPI | Python | git pull && pip install -r requirements.txt && uvicorn main:app --host 0.0.0.0 |
| PHP / Laravel | PHP | PHP-FPM 自动启动,通过 OpenResty 反向代理访问 |
| Java / Spring Boot | Java | java -jar app.jar |
| Go | Go | ./app |
| .NET / ASP.NET Core | .NET | dotnet run --urls http://0.0.0.0:5000 |
::: tip 运行环境 = Docker 容器
1Panel 的「运行环境」本质上是 Docker 容器。每种语言(Node.js、Python、PHP、Java、Go、.NET)对应一个预配置好的基础镜像,你选择语言和版本后,1Panel 会用 docker-compose 帮你管理容器的创建和启动。
:::
关键配置:
小明的项目是 Node.js,他在「运行环境」中创建了一个容器,填了项目目录、启动命令、环境变量。几分钟后,后端 API 跑起来了。他在浏览器访问 http://服务器IP:3001/api/health,看到了 JSON 响应。
前端通常需要先在本地构建,然后上传到服务器:
# 在本地电脑上 cd your-project # 设置环境变量(指向服务器的后端 API) echo "VITE_API_URL=http://你的服务器IP:3001" > .env.production # 构建前端 npm run build # 或 pnpm build / yarn build # 构建产物通常在 dist/ 或 build/ 或 out/ 目录
上传到服务器:
# 方式一:使用 scp scp -r dist/* root@你的服务器IP:/opt/your-frontend/ # 方式二:使用 FinalShell 拖拽上传
在 1Panel 中创建静态网站:
yourdomain.com(或先用 IP 测试)/opt/your-frontend小明用 FinalShell 把构建好的前端文件拖到服务器上,然后在 1Panel 创建了静态网站。浏览器访问服务器 IP,前端页面出来了——但他试着登录,发现报错:"跨域请求被阻止"。
现在前端和后端是分开的——前端在 80 端口,后端在 3001 端口。前端发起的 API 请求会遇到跨域问题。解决方案是配置反向代理,让前端和后端在同一个域名下。
在 1Panel 中,进入刚创建的静态网站的设置页面,点击「配置文件」选项卡,复制整个配置内容。
打开本地的 Claude Code,发送以下 prompt:
我需要配置 OpenResty 反向代理,实现前后端分离部署。 当前 1Panel 默认配置: [粘贴你复制的配置] 我的需求: - 前端静态文件在 /opt/your-frontend - 后端 API 容器名是 your-backend,端口 3000 - 所有 /api/* 请求转发到后端 - 其他请求返回前端页面(SPA 路由支持) 请帮我完善这个配置。
Claude Code 会根据你的实际情况生成完整的配置,包括:
proxy_pass 地址try_files)把 Claude Code 生成的配置复制回 1Panel 的「配置文件」编辑框,点击「保存并重载」。
小明把 1Panel 的默认配置复制到本地 Claude Code,说明了自己的需求。Claude Code 很快生成了完整的配置,包括反向代理规则、请求头设置、超时配置。小明复制回 1Panel,点击保存——刷新浏览器,这次登录成功了!
::: tip 为什么推荐这个工作流?
:::
::: warning 如果 Claude Code 生成的配置有问题怎么办?
proxy_pass 的路径是否正确如果多次尝试仍然失败,可以参考本节末尾的"典型的反向代理配置示例"手动修改。
:::
Claude Code 生成的配置通常长这样:
server { listen 80; server_name yourdomain.com; # 前端静态文件 location / { root /opt/your-frontend; try_files $uri $uri/ /index.html; # SPA 路由支持 } # 后端 API 反向代理 location /api/ { proxy_pass http://your-backend:3000/api/; 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; # 超时设置 proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; } }
反向代理配置好后,前端的 API 地址应该改成相对路径(因为前端和后端在同一个域名下了):
# 在本地电脑上 echo "VITE_API_URL=/api" > .env.production # 或 NEXT_PUBLIC_API_URL=/api # 重新构建 npm run build # 重新上传到服务器 scp -r dist/* root@你的服务器IP:/opt/your-frontend/
小明重新构建并上传了前端。刷新浏览器,所有功能都正常了——"前端、后端、数据库,三个部分在自己的服务器上协同工作了。"
虽然部署流程类似,但不同技术栈有一些细节差异:
pnpm build && pnpm startDATABASE_URL、NODE_ENV=productionpip install -r requirements.txt && uvicorn main:app --host 0.0.0.0 --port 8000DATABASE_URL、PYTHONUNBUFFERED=1DB_CONNECTION、DB_HOST(填容器名)、APP_ENV=productionjava -jar app.jarSPRING_DATASOURCE_URL、SPRING_PROFILES_ACTIVE=prod./appdotnet run --urls http://0.0.0.0:5000ConnectionStrings__DefaultConnection、ASPNETCORE_ENVIRONMENT=Production部署完成后,测试以下功能确保一切正常:
http://你的服务器IP → 看到前端页面小明把这些功能都测试了一遍,全部正常。他打开开发者工具的 Network 面板,看到前端页面是从 / 加载的,API 请求是发往 /api/xxx 的——"用户完全感觉不到后面有三个服务在跑。"
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 前端页面打不开 | 安全组没开 80 端口 | 去云厂商控制台开放 80 端口 |
| API 请求 404 | 反向代理配置错误 | 检查 proxy_pass 的容器名和路径 |
| API 请求 502 | 后端容器没启动 | 在「运行环境」中查看日志,重启容器 |
| 数据库连接失败 | DATABASE_URL 主机名填错 |
用容器名(如 postgresql)替代 localhost |
| 跨域错误 | 反向代理未生效 | 确认 OpenResty 配置已保存并重载 |
| SPA 路由 404 | 缺少 try_files 配置 |
让 Claude Code 补充 SPA 路由支持 |
::: tip 遇到问题时的调试流程
ping postgresql 测试网络连通性:::
通过前后端分离部署,你获得了:
小明回想起在 Vercel 上部署时,一个 vercel deploy 就搞定了。现在虽然步骤多了,但他理解了每一步在做什么——"Vercel 帮我做的事情,我现在自己也能做了。而且有 Claude Code 帮忙写配置,也没那么难。"
::: info 下一步
应用部署完成了,但现在只能通过 IP 访问,不够专业。接下来配置域名和 HTTPS——14.4 配置域名与证书。
:::