Nginx 蓝绿部署实战:在单台 VPS 上实现无停机版本切换

Nginx 蓝绿部署在单台 VPS 上的版本切换示意

Nginx 蓝绿部署的核心价值,是帮助你在单台 [VPS](https://cn.hostease.com/vps/)([虚拟专用服务器](https://cn.hostease.com/vps/))上把“发版”和“回滚”变成可控动作,而不是把所有访问直接压到刚更新的目录。本文教你用两个应用目录、一个 Nginx upstream 和一套健康检查命令,解决小团队上线时最常见的 502、静态资源错配和回滚慢问题。

这个方案适合个人站长、中小企业后台、外贸展示站和轻量 API 服务。它不能替代完整集群,也不等于高可用架构;但在只有一台 VPS(虚拟[专用服务器](https://cn.hostease.com/dedicated-server/))的预算下,它能把版本切换时间压缩到一次 reload,并把失败回滚控制在几十秒内。准备服务器基础环境时,可以先参考美国 VPS 服务器部署教程完成系统更新、用户权限和基础服务安装。

先理解蓝绿部署在单机里的边界

蓝绿部署不是“同时跑两套线上系统”这么简单。单台 VPS(虚拟专用服务器)的 CPU、内存和磁盘 I/O 都是共享的,所以更合理的做法是:蓝色环境承接当前流量,绿色环境提前部署新版本;验证通过后,只把 Nginx 的转发目标切到绿色环境。旧版本暂时保留,便于快速回滚。

为了避免概念混乱,可以把目录和端口固定下来。假设应用监听本机端口,蓝色环境使用 127.0.0.1:8081,绿色环境使用 127.0.0.1:8082;代码目录分别为 /var/www/app-blue/var/www/app-green;当前生效版本由一个软链接 /etc/nginx/conf.d/app-upstream.conf 指向具体配置文件。

单台 VPS 上蓝绿两个应用环境的隔离方式

这种设计有 3 个直接好处:新版本启动失败不会影响旧版本;Nginx reload 通常不会中断已建立连接;如果新版本出现业务异常,可以把 upstream 切回旧端口。关于反向代理的基础配置和转发逻辑,可延伸阅读Nginx 反向代理与负载均衡配置指南

准备目录、进程和 Nginx upstream

开始前,请确认服务器已经安装 Nginx、应用运行时和 systemd。下面用两个 systemd 服务表示蓝绿环境,你也可以换成 Docker Compose、PM2 或其他进程管理工具,关键是两个版本必须能在不同端口独立启动。

sudo mkdir -p /var/www/app-blue /var/www/app-green
sudo chown -R deploy:deploy /var/www/app-blue /var/www/app-green

## 示例:蓝色环境监听 8081,绿色环境监听 8082
sudo systemctl status app-blue
sudo systemctl status app-green

接着准备两份 upstream 文件。每份文件只定义一个后端目标,主站点配置通过 include 引入它。这样切换版本时,不需要修改整段 server 配置,减少误改证书、日志路径或缓存规则的概率。

# /etc/nginx/conf.d/upstream-blue.conf
upstream app_backend {
    server 127.0.0.1:8081 max_fails=2 fail_timeout=10s;
}

## /etc/nginx/conf.d/upstream-green.conf
upstream app_backend {
    server 127.0.0.1:8082 max_fails=2 fail_timeout=10s;
}

主站点配置保持稳定,只引用当前生效的 upstream。若站点已经启用 SSL(安全传输协议)证书,证书段也应固定在 server 配置里,不要跟随版本目录一起切换。

include /etc/nginx/conf.d/app-upstream.conf;

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://app_backend;
        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_connect_timeout 3s;
        proxy_read_timeout 30s;
    }
}

用健康检查决定能不能切流量

真正降低风险的不是“有两个目录”,而是切换前的验证。建议至少检查 4 项:进程状态、健康检查接口、关键静态资源和一次真实业务请求。对于 WordPress、Node.js、Python API 等站点,健康检查接口可以返回版本号、数据库连接状态和缓存连接状态,但不要暴露敏感配置。

#!/usr/bin/env bash
set -euo pipefail
TARGET_PORT="$1"

curl -fsS "http://127.0.0.1:${TARGET_PORT}/health" | grep -q "ok"
curl -fsS "http://127.0.0.1:${TARGET_PORT}/" >/dev/null
curl -fsS "http://127.0.0.1:${TARGET_PORT}/assets/app.css" >/dev/null

echo "health check passed on ${TARGET_PORT}"

如果健康检查失败,本轮发布应直接停止,不要继续 reload。这里的目标不是追求复杂,而是把“上线前看一眼”变成脚本化门槛。服务器防火墙也要保持最小暴露:公网只开放 80、443 和必要的管理端口,8081、8082 应限制为本机访问。相关安全策略可参考VPS 防火墙配置指南

健康检查通过后再切换 upstream 的发布路径

执行切换,并保留可回滚窗口

假设当前蓝色环境在线,新版本部署到绿色环境。通过健康检查后,把 upstream 软链接切到绿色配置,再执行 nginx -t 和 reload。完整动作可以写成一个脚本,但每一步都要保留失败退出,避免半切换状态。

sudo ln -sfn /etc/nginx/conf.d/upstream-green.conf /etc/nginx/conf.d/app-upstream.conf
sudo nginx -t
sudo systemctl reload nginx
curl -I http://127.0.0.1/

切换后建议观察 10-15 分钟,重点看 Nginx access log、error log、应用错误率和接口耗时。如果发现 502 增多、登录异常或静态资源 404,立即切回蓝色配置:

sudo ln -sfn /etc/nginx/conf.d/upstream-blue.conf /etc/nginx/conf.d/app-upstream.conf
sudo nginx -t
sudo systemctl reload nginx

回滚后不要马上删除绿色目录。先记录错误日志、版本号、发布时间和触发条件,再决定是修复后重发,还是回退代码分支重新构建。对于访问量较大的站点,还可以结合Nginx 性能调优清单检查 keepalive、缓冲区和 worker 参数,避免发布过程被性能瓶颈放大。

常见风险与检查清单

单机蓝绿部署最容易出问题的地方,往往不是 Nginx 语法,而是共享资源。两个版本如果同时写同一个上传目录、同一张临时表或同一份缓存文件,就可能出现旧版本和新版本互相覆盖的情况。因此,发布前要把状态类资源单独列出来。

  • 数据库变更:向后兼容优先,例如先新增字段,再上线读取逻辑,最后清理旧字段。
  • 上传目录:统一放在 /data/uploads 这类共享路径,不放在版本目录内。
  • 缓存键名:涉及结构变化时增加版本前缀,例如 product:v2:
  • 定时任务:同一时间只允许一个环境执行,避免订单、邮件或报表重复触发。

蓝绿部署中数据库、上传目录和缓存的共享边界

如果你的业务已经涉及多台服务器、跨区域访问或 CDN(内容分发网络)缓存,单台 VPS(虚拟专用服务器)的蓝绿切换就只是发布流程的一部分,还需要处理缓存刷新、数据库迁移和跨节点一致性。本文的方案更适合先把单机发布标准化,再逐步升级到负载均衡或容器编排。

总结:先把切换做小,再把流程做稳

总结来看,Nginx 蓝绿部署并不要求一开始就购买复杂平台。你需要的是清晰的目录隔离、固定的 upstream 文件、可重复执行的健康检查,以及一条能够在 1 分钟内完成的回滚命令。这样做的意义,是把上线风险从“全站试错”缩小到“一次可验证的转发切换”。

如果你需要在 Hostease 的 VPS(虚拟专用服务器)环境中落地类似流程,建议先从非核心站点演练 2-3 次:记录每次部署耗时、健康检查结果和回滚步骤,再迁移到正式业务。等单台机器的发布动作稳定后,再考虑监控告警、自动化流水线和多节点架构,会比一开始堆工具更可靠。

发表评论