作为一名长期做后端和 AI 应用落地的开发者,我最近被问得最多的问题就是:"项目都跑起来了,怎么稳定部署到服务器,还能方便更新?"
以前我也踩过很多坑:配置文件写对了但 Nginx 不生效、容器都启动了但健康检查失败、更新代码后线上还是旧版本。
现在我的答案很简单:用一套固定的部署流程,把"启动、验证、更新、回滚"全部标准化。
如果你也在纠结"能跑"和"能稳定上线"的差距,这篇文章我直接给你可复制执行的方案。
一、先厘清:部署到底在做什么
很多人以为部署就是 git pull + docker compose up,实则部署是"环境、配置、服务、网关、验证"五件事一起闭环。
简单说,部署就像给项目搭一条生产流水线:代码只是原材料,真正上线还要把数据库、缓存、对象存储、反向代理都串起来。
本章小结
| 核心要点 | 关键收获 |
|---|---|
| 部署不是单步命令 | 明确了部署是完整闭环,不是只拉代码 |
| 核心链路 | 理清了应用层(前后端)和基础设施层(PG/Redis/MinIO/Ollama) |
| 验证优先 | 先看健康检查,再看业务接口 |
二、核心方案:这套项目的生产部署架构
我这套项目采用 Docker Compose,一次起全套服务,外部用宝塔 Nginx 做反向代理。
| 维度 | 方案A:纯本机启动 | 方案B:Docker Compose(推荐) | 方案C:K8s |
|---|---|---|---|
| 特点 | 适合开发调试 | 上手快、运维成本低、可复制 | 灵活但复杂度高 |
| 适用场景 | 本地开发 | 单机云服务器、个人/小团队 | 企业级多节点 |
| 优缺点 | 优点:简单;缺点:环境漂移 | 优点:一致性高;缺点:需管理镜像与卷 | 优点:弹性强;缺点:学习和维护成本高 |
注意 :对于你当前项目规模,Compose 是性价比最高的方案。
避坑提醒:不要一开始就上复杂编排,先把单机稳定性跑通。
本章小结
| 核心要点 | 关键收获 |
|---|---|
| 选型原则 | 先稳定上线,再考虑复杂扩展 |
| 推荐方案 | Compose + 宝塔反代最实用 |
| 风险控制 | 通过标准命令和检查项降低事故率 |
三、实战部署:可直接照抄的步骤
Step 1:准备目录与环境变量
bash
cd /www/wwwroot
git clone <你的仓库地址> MyProject-SDAgent
cd MyProject-SDAgent/deploy
# 复制模板(推荐)
cp .env.example .env
nano .env
🔴 重点:.env 至少要正确填写这些值:DASHSCOPE_API_KEY、APP_JWT_SECRET、POSTGRES_PASSWORD、MINIO_PASSWORD。
⚠️ 如果这些缺失,后端常见现象就是"容器启动后很快重置连接"。
Step 2:构建并启动服务
bash
cd /www/wwwroot/MyProject-SDAgent/deploy
docker compose --env-file .env up -d --build
docker compose ps
预期结果:
postgres/redis/minio/ollama为healthy。backend/frontend先starting,稍后转healthy。
Step 3:健康检查(必须等后端就绪)
bash
# 等待后端健康
until [ "$(docker inspect -f '{{.State.Health.Status}}' policy-agent-backend)" = "healthy" ]; do
echo "backend not healthy yet..."
sleep 3
done
curl -f http://127.0.0.1:8080/actuator/health
curl -f http://127.0.0.1:8080/api/chat/health
curl -f http://127.0.0.1:5173/health
Step 4:宝塔 Nginx 反代
在宝塔"站点主配置 + 自定义配置"中确保只保留一个 location /,避免重复冲突。
nginx
# 自定义配置示例(不要包 server{})
client_max_body_size 50m;
location /api/ {
proxy_pass http://127.0.0.1:8080/api/;
proxy_http_version 1.1;
proxy_set_header Connection "";
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_buffering off;
proxy_cache off;
proxy_read_timeout 600s;
proxy_send_timeout 600s;
}
避坑提醒 :出现
duplicate location "/",说明同一个server里写了两个location /。
Step 5:初始化后操作
- 立即修改管理员默认密码
admin/admin。 - 立即轮换曾经暴露过的 API Key/JWT 密钥。
- 把敏感信息放
.env,不要进 Git。
部署流程图
否
是
准备 .env
Compose 启动
容器是否 healthy
看 logs 排错
执行健康检查
配置宝塔反代
域名联调
上线完成
本章小结
| 核心要点 | 关键收获 |
|---|---|
| 步骤清晰 | 直接按 Step 执行可上线 |
| 验证顺序 | 先容器健康,再接口检查,再域名联调 |
| 高频故障 | 主要来自 .env 缺项和 Nginx 重复 location |
四、生产级更新与调试
4.1 标准更新流程
bash
cd /www/wwwroot/MyProject-SDAgent
git fetch --all
git checkout main
git pull
cd deploy
docker compose --env-file .env up -d --build
docker compose ps
一句话总结:git pull 只更新代码,compose up --build 才会让线上服务生效。
4.2 回滚流程
bash
cd /www/wwwroot/MyProject-SDAgent
git log --oneline -n 10
git checkout <上一个稳定commit>
cd deploy
docker compose --env-file .env up -d --build
4.3 调试常用命令
bash
docker compose logs -f backend frontend
docker compose logs --tail=200 backend
docker stats --no-stream
docker exec -it policy-agent-backend sh
💡 实操建议:每次发布打 tag(如 v1.0.3),回滚速度会快很多。
本章小结
| 核心要点 | 关键收获 |
|---|---|
| 更新闭环 | 拉代码后必须重建容器 |
| 回滚可控 | 用 commit/tag 快速恢复 |
| 调试抓手 | 状态、日志、资源、容器内排查四件套 |
五、总结:你真正需要记住的 4 件事
- 先健康后联调 :容器
healthy之前的curl失败不代表部署失败。 - 配置优先于代码 :线上故障大多是
.env、Nginx 路由、端口映射问题。 - 更新必须重建 :
git pull后要docker compose up -d --build。 - 永远准备回滚:上线前确认上一稳定版本可一键恢复。
验证清单(实操后必查)
- ⭐ [ ]
docker compose ps中核心服务均正常。 - ⭐ [ ]
8080/actuator/health与8080/api/chat/health返回成功。 - 域名访问前端页面正常,接口可用。
- 管理员默认密码已修改。
- API Key/JWT 密钥未暴露在仓库中。
行动清单
- 先把当前部署流程写成你自己的
DEPLOY.md。 - 再加一个一键脚本(更新、检查、日志导出)。
- 遇到异常先按"健康检查→日志→反代配置"顺序排查。
- 完成后补上 HTTPS 和自动备份策略。
希望这篇博客能帮助你把"项目能跑"升级为"项目能稳定上线并可持续更新"。如果你愿意,我下一篇可以直接写"这套项目的一键发布脚本(含失败自动回滚)"。
参考资源
-
官方文档\] Docker Compose 文档:https://docs.docker.com/compose/
-
官方文档\] Spring Boot Actuator:https://docs.spring.io/spring-boot/reference/actuator/
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。