文档/ 部署/ 蓝绿部署与回滚

蓝绿部署与回滚

sh0 的每次部署都使用蓝绿策略实现零停机发布。如果出现问题,可以即时回滚到任何之前的版本。

蓝绿部署

蓝绿部署是一种通过并行运行两个相同环境来消除停机时间的发布策略。在任何给定时间,一个环境(蓝色)提供实时流量,另一个(绿色)处于空闲状态或正在更新新版本。

当你部署新版本时,sh0 会在当前容器旁边启动新容器。一旦新容器通过健康检查,流量会立即从旧容器切换到新容器。旧容器会短暂保持运行作为备用,然后被关闭。

Blue-green deployment diagram showing two containers with traffic routing
Tip
蓝绿部署在 sh0 中默认为所有应用启用。无需配置——每次部署都会自动使用此策略。

sh0 的实现方式

以下是 sh0 每次部署时遵循的逐步流程:

  1. 构建:从源代码构建新的 Docker 镜像或从镜像仓库拉取
  2. 启动绿色容器:使用更新后的镜像启动新容器,连接到与当前容器相同的网络和卷
  3. 健康检查:sh0 对新容器运行健康检查(HTTP 端点、TCP 端口或自定义命令)
  4. 运行部署前钩子:如果已配置,部署前钩子会在新容器上执行(例如数据库迁移)
  5. 流量切换:更新 Caddy 的反向代理配置,将所有流量路由到新容器
  6. 运行部署后钩子:执行部署后钩子(例如清除缓存、发送通知)
  7. 排空旧容器:旧容器有一个宽限期(默认 30 秒)来完成处理中的请求
  8. 停止旧容器:旧容器被停止并移除
Deployment timeline showing each step of the blue-green process

流量切换在反向代理层(Caddy)进行,这意味着它是即时的。停止旧容器和启动新容器之间没有间隔——两者在过渡期间同时运行。

零停机部署

由于旧容器会继续提供流量直到新容器被验证为健康,因此用户在部署期间不会经历任何停机。切换是无缝的:

  • 部署期间无 502 错误
  • 无连接中断或请求丢失
  • 无需维护窗口
  • 旧容器上的 WebSocket 连接允许自然完成

健康检查

健康检查对于零停机部署至关重要。sh0 支持三种类型的健康检查:

类型工作原理最适用于
HTTP向指定路径发送 GET 请求并期望返回 2xx 响应具有健康检查端点的 Web 应用
TCP尝试与容器端口建立 TCP 连接数据库、缓存、非 HTTP 服务
命令在容器内运行命令并检查退出码自定义健康逻辑
Health check configuration
{
  "healthcheck": {
    "type": "http",
    "path": "/health",
    "interval": 10,
    "timeout": 5,
    "retries": 3,
    "start_period": 30
  }
}
Warning
如果新容器未通过健康检查,sh0 会自动取消部署。旧容器继续提供流量,失败的部署会记录在历史中并附带错误信息。

部署历史

sh0 为每个应用维护完整的部署历史记录。部署历史包括:

  • 部署状态(成功、失败、已回滚)
  • Git commit SHA 和提交信息
  • Docker 镜像标签和摘要
  • 构建时长和部署时长
  • 部署触发者(用户、webhook 或 API)
  • 完整构建日志
Deployment history table showing recent deployments with status, commit, and duration

点击任意部署可查看其完整构建日志、钩子执行结果和健康检查输出。当前上线的部署在列表中高亮显示。

一键回滚

如果部署引入了 bug 或性能问题,你可以从部署历史中回滚到任何之前的版本。点击任意成功的历史部署旁边的 回滚 按钮即可立即重新部署该版本。

Deployment history with rollback button highlighted on a previous successful deployment

回滚遵循与常规部署相同的蓝绿流程:使用旧版本的 Docker 镜像启动新容器、运行健康检查、切换流量。这意味着回滚也是零停机的。

Tip
sh0 保留近期部署的 Docker 镜像,以便回滚可以即时完成——无需重新构建镜像。保留镜像数量可在 应用设置 → 部署 → 保留版本数 中配置(默认:10)。

通过 API 回滚

你也可以通过 sh0 API 以编程方式触发回滚。这对于由监控系统触发的自动回滚非常有用。

Rollback to a specific deployment
# Rollback to a specific deployment ID
curl -X POST https://your-sh0-server.com:9000/api/apps/{app_id}/rollback \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"deploy_id": "deploy_abc123"}'
Rollback to the previous deployment
# Rollback to the immediately previous version
curl -X POST https://your-sh0-server.com:9000/api/apps/{app_id}/rollback \
  -H "Authorization: Bearer YOUR_TOKEN"

如果未指定 deploy_id,sh0 会回滚到当前部署之前最近一次成功的部署。

回滚行为

关于回滚工作方式的重要细节:

  • 仅代码:回滚会恢复应用代码(Docker 镜像),但不会恢复数据库更改。如果你的部署包含数据库迁移,可能需要手动编写反向迁移。
  • 环境变量:回滚使用当前的环境变量,而不是原始部署时的变量。这确保更新后的密钥和配置保持生效。
  • 钩子执行:回滚期间会执行部署前和部署后钩子,与常规部署一样。
  • 历史记录:回滚会在部署历史中创建一个带有「回滚」标签的新条目,显示恢复了哪个部署。
Warning
回滚不会恢复数据库架构更改。如果你的部署包含破坏性迁移(删除列、重命名表),请相应规划回滚策略。建议使用可逆迁移,并先在预览环境中测试回滚场景。