返回博客列表

低配置服务器上的博客全栈部署复盘

2026-06-169 分钟阅读
工程部署DockerNginx
本文目录
  1. 背景
  2. 遇到的问题
  3. 1. 容器能启动,但 Nginx 找不到后端
  4. 2. 后端因为环境变量格式启动失败
  5. 3. MySQL 初始化和迁移需要分清边界
  6. 4. 低内存服务器需要主动限制资源
  7. 最终收敛
  8. 收获

这篇文章整理我把个人技术博客部署到低配置服务器时遇到的问题,以及最后收敛出的部署方式。这个项目本身不只是一个展示页,还包含 Next.js 前端、FastAPI 后端、MySQL、Redis、Nginx 反向代理和一键部署脚本,所以部署过程比单纯静态站点更接近真实业务系统。

背景

我的目标是让博客成为一个长期可维护的个人技术作品,同时保留后续写文章、AI 生成草稿、编辑发布和后台管理的能力。服务器资源不高,所以不能简单地把所有服务按默认配置跑起来,而是需要控制内存、启动顺序和故障恢复。

最终部署形态是:

模块作用
Next.js前端页面、博客列表、文章详情
FastAPI文章接口、AI 草稿、发布管理
MySQL持久化文章、草稿和基础数据
Redis缓存、状态数据和轻量运行辅助
Nginx对外入口、反向代理前后端
Docker Compose统一编排和一键启动

遇到的问题

1. 容器能启动,但 Nginx 找不到后端

一开始 Nginx 日志提示 upstream 找不到服务。原因是生产环境里容器名称和 Nginx 配置里的 upstream 名称没有完全对齐,导致反向代理启动时解析不到后端地址。

解决思路是统一使用 Docker Compose 网络里的服务名或固定容器名,并确保 Nginx 配置与 compose 文件保持一致。这个问题提醒我,部署不是只看代码能不能跑,还要看服务之间的网络命名、启动顺序和配置一致性。

2. 后端因为环境变量格式启动失败

后端曾经因为 CORS 配置解析失败而反复重启。问题出在环境变量传入的是普通字符串,但配置层按复杂 JSON 类型解析,导致应用启动阶段直接报错。

后续处理方式是让配置解析更宽容:生产环境可以用逗号分隔的字符串,代码里再转换成列表。这样比要求服务器环境变量严格写 JSON 更适合一键部署脚本。

3. MySQL 初始化和迁移需要分清边界

MySQL 容器的 init SQL 只会在数据卷为空时执行,不能依赖它做后续线上 schema 变更。因此我把初始化和迁移分开:首次启动负责基础库表,后续变更走明确的 migration SQL。

这也是一次很实际的经验:部署脚本要考虑“第一次部署”和“已经有数据后的升级”是两种场景。

4. 低内存服务器需要主动限制资源

默认 MySQL、Redis、Node 和 Python 容器都可能占用较多内存。为了让服务稳定运行,我在生产 compose 中对各服务设置了更保守的内存限制,并减少 MySQL buffer、连接数和 Redis maxmemory。

重点不是追求极限性能,而是在资源有限的服务器上保证博客可访问、后端不反复重启、数据库能健康启动。

最终收敛

最终部署脚本做了几件事:

  • 拉取或更新前后端代码。
  • 生成必要的 MySQL、Redis、JWT 环境变量。
  • 构建前端和后端镜像。
  • 启动 MySQL、Redis、FastAPI、Next.js 和 Nginx。
  • 等待数据库健康后执行迁移。
  • 通过连通性检查确认后端接口和首页可访问。

收获

这次部署让我更清楚地理解了一个线上系统的基本闭环:代码只是其中一部分,真正能稳定访问还依赖配置、容器网络、数据库初始化、资源限制、日志排查和回滚思路。

对我来说,这个博客项目的价值不只是“有一个个人网站”,而是我把前端、后端、AI 内容流、数据库和服务器部署真正串起来,形成了一个可以持续维护和演示的作品。