部署 · Docker

Docker + Nginx 部署架构:小团队如何把系统稳定上线?

小团队部署业务系统时,可以用 Docker 管理应用环境,用 Nginx 做反向代理和 HTTPS,用数据卷、备份和健康检查降低上线风险。

很多项目开发完成后,真正麻烦的是上线:环境不一致、端口冲突、证书过期、数据库丢失、日志难查。Docker + Nginx 是小团队比较稳的部署组合,可以把运行环境、域名入口、HTTPS、数据持久化和重启策略统一起来。

典型架构链路

  1. 用户浏览器
  2. Nginx 80/443
  3. HTTPS 证书 / 跳转规则
  4. Docker Compose
  5. 应用容器
  6. 数据库 / 数据卷
  7. 日志 / 备份 / 健康检查

Docker 解决环境一致性

把 Python、Node、依赖包、启动命令放进镜像,服务器不需要手工配置一堆运行环境。以后换服务器或回滚版本更简单。

Docker Compose 管理应用和数据卷

Compose 可以定义端口、环境变量、数据卷、重启策略和健康检查。数据库文件、上传文件等持久化数据不要放在容器临时层里。

Nginx 负责公网入口

Nginx 监听 80/443,把请求转发到本机应用端口。它还可以处理 HTTPS、静态缓存、请求体大小和基础安全头。

HTTPS 和证书续期要自动化

证书申请成功不代表结束,还要确认 443 端口放行、HTTP 跳 HTTPS、证书定时续期和续期后自动 reload Nginx。

健康检查和日志让问题可定位

容器要有健康检查,应用要有访问日志和错误日志。线上问题发生时,先判断是 DNS、Nginx、容器、应用还是数据库。

备份和回滚是上线底线

小系统也要有数据库备份、部署前版本备份和镜像回滚策略。否则一次误操作就可能影响真实业务。

脱敏项目复盘:单机 Docker 部署也要具备可恢复能力

中小业务首期常用一台云服务器承载官网、接口、后台和数据库。单机不等于可以忽略工程设计:证书过期、磁盘写满、数据库迁移失败、容器反复重启,都可能让一个功能不复杂的系统长时间不可用。部署方案首先要回答可接受停机时间和可接受数据丢失量。

业务与产品形态

我们把发布、备份、恢复、证书和健康检查当成系统功能,而不是开发人员电脑上的命令。管理者能看到服务状态、最近备份和磁盘告警;发布人员有固定脚本、版本号和回滚入口;业务人员在维护期间看到明确提示,而不是浏览器连接失败。

技术解决方案

Nginx 负责 HTTPS、静态资源缓存、限流和反向代理,应用与数据库用 Docker Compose 编排,持久数据落在独立卷并定期异地备份。配置和密钥不进入镜像,日志输出到标准流并配置轮转。每次构建产生不可变版本,应用、镜像和数据库迁移都有对应编号,健康检查覆盖进程、数据库连接和关键依赖。

难点设计

真正危险的是“容器正常但业务不可用”。因此数据库变更采用向前兼容步骤:先增加结构、再部署兼容代码、完成数据回填后才清理旧字段;发布前自动备份,恢复脚本定期在隔离环境演练。外部请求设置超时、重试上限和请求标识,防止依赖故障拖垮线程;证书、磁盘、内存和备份时效都设置告警。

用户体验

部署时尽量无感切换,确实需要维护时保留只读查询或清晰的维护页。表单提交等操作必须幂等,用户刷新或重试不会产生两条数据;长任务中断后可以继续,错误提示给出可执行建议。运维界面使用业务名称显示服务,而不是暴露容器哈希和内部端口。

产品效果与验收

验收要实际执行重启、旧版本回滚、数据库恢复、证书续期模拟和磁盘告警测试。记录恢复耗时、备份可用率、部署失败回滚时间、关键接口成功率和静态资源命中率。成本有限时可以不做复杂集群,但不能省略备份验证、监控和可重复发布,这些才是系统能长期运行的底线。

一次可靠发布要解决的不只是“容器启动了”

Docker 能把运行环境封装起来,但不会自动解决配置泄露、数据库升级、流量切换和数据恢复。我们通常把镜像、运行配置和持久化数据分开:镜像只包含应用和固定依赖;域名、密钥、数据库连接通过环境或密钥文件注入;数据库、上传文件和备份放在独立数据卷。这样重建容器不会把业务数据一起删掉。

镜像必须可追踪,配置必须可审计

生产环境不应长期使用不可追踪的 latest 标签。镜像版本应能对应到代码提交和构建时间,部署记录要保留本次使用的镜像、配置变更和执行人。密钥不写进镜像、不提交到代码仓库,也不直接打印到日志。开发、测试和生产使用相同镜像,通过配置差异运行,减少“测试能跑、线上不行”。

数据库变更要向前兼容

应用回滚容易,数据库回滚困难。增加字段时先允许旧版本继续读写,再发布新应用,最后清理旧字段;大表索引和字段回填要拆成后台任务,避免一次 DDL 长时间锁表。发布前需要备份,但更重要的是在独立环境做过恢复演练,确认备份文件真的能用、恢复需要多久。

Nginx 与健康检查共同完成流量切换

健康检查不能只判断端口打开,还应该验证应用能访问关键依赖。新容器启动后先通过 readiness 检查,再让 Nginx 转发流量;旧容器等待正在处理的请求结束后退出。静态资源设置长期缓存并使用版本文件名,HTML 保持短缓存,API 禁止被代理缓存。出现异常时可以快速切回上一镜像,而不是临时登录服务器改代码。

排障需要结构化日志和资源指标

容器日志应输出到标准输出并由宿主机轮转,避免磁盘被单个日志文件写满。每条请求带请求 ID,错误日志包含业务上下文但不打印密码和完整联系方式。CPU、内存、磁盘、容器重启次数、接口延迟和数据库连接数都需要基础监控。很多“网站偶尔打不开”最后并不是代码错误,而是磁盘满、证书续期失败或连接池耗尽。

我们验收部署方案时,看的不只是容器有没有启动

构建产物必须固定,配置和密钥必须分开

生产环境不使用会随时间变化的 latest 标签,也不在服务器上临时安装依赖。镜像由同一份 Dockerfile 构建,记录提交号和镜像摘要;数据库口令、短信密钥和证书通过环境文件或密钥管理注入,不写进镜像。这样才能明确线上运行的究竟是哪一版,也避免把敏感配置带进代码仓库。

健康检查要反映“能接请求”,不是进程还活着

应用要区分存活检查与就绪检查:进程存活不代表数据库连接池、迁移和关键依赖已经准备好。Nginx 的连接、读取和上传超时要按业务设置,容器退出时先停止接收新流量,再等待正在执行的请求完成。否则滚动重启时,用户会看到偶发 502,长任务也可能执行到一半被终止。

数据库迁移和备份必须进入发布顺序

发布前先生成可验证的备份,再执行向前兼容的 migration,最后切换应用。大表变更要评估锁表时间,必要时拆成“加字段、回填、切读写、清理旧字段”几次发布。备份文件存在不等于能恢复,我们会在独立目录或测试实例定期恢复,并核对表数量、关键记录和附件完整性。

回滚要写成命令和条件,不能只写一句“支持回滚”

每次上线记录旧镜像、新镜像、迁移版本和变更窗口。接口错误率、核心流程失败率或队列积压超过阈值时,按 runbook 回切旧镜像;如果迁移不可逆,则使用兼容代码或数据修复方案。应用、Nginx 和数据库日志统一带 request_id,并设置保留周期,才能在发布后快速判断问题来自代理、应用还是数据层。

落地前建议确认

  • 应用是否容器化
  • 数据是否放在持久化卷
  • HTTPS 是否自动续期
  • 是否有备份、日志和回滚方案
需要把架构落到你的业务里?

先描述你的业务场景、现有工具和数据流,我们帮你判断该从哪一层开始做。

快速描述您的需求