← rugoi.com 原始文件 ↓

如何做一次站点部署与回滚

用途:把改好的文件推上线,出问题时能退回去。核心不是「怎么推」,是先能退,再往前。

覆盖:静态站点、单机部署、有可写备份位或版本库的场景。

产出:一次可追溯的发布记录,加一个验证过的回退点。

拿到就能跑:第二步「建回退锚点」不能跳。跳过它,后面每一步都在赌。


触发的变异问法


什么时候不要用这份文件


执行步骤

第一步 · 先探测三处

推之前先看清现状。三处 = 本地源 / 镜像(或备份仓)/ 线上。

对每个要动的文件,取三样:大小、md5、修改时间。

三处一致 → 说明没人动过,可以推。 线上与本地不同 → 正常,这正是要推的原因。 线上已经是新的 → 停。有人先推过了,先查清是谁、推了什么,再决定。

⛔ 不要跳过这步直接推。「线上是什么」不能靠记忆,只能靠取回来比对。

输出:一张三处的 md5 对照表,以及一句结论:线上当前是旧版 / 已是新版 / 文件缺失。

第二步 · 建回退锚点(不能跳)

把改动前的线上文件复制到备份位,并当场核对 md5。

唯一有效的判据是:备份件的 md5 等于改动前那一版的 md5。 不是时间,不是文件名。

这一步最容易错,两种典型错法:

如果备份丢了,还有一条路:从版本库历史里取改动前的那一版。这比任何备份都可靠,因为它不由操作者决定。

输出:备份路径 + 备份件 md5 + 「等于改动前」的核对结果。

第三步 · 确认没人在同时改

自动化任务、定时脚本、另一个人的部署,都可能与这次撞车。

查三样:有没有相关进程在跑、有没有锁文件、目标目录最近有没有别的写入。

有任务在跑 → 等它结束。并发写入同一个索引文件,最后谁赢取决于毫秒,输的一方内容静默消失。

输出:一句确认——「无并发」或「已等 X 结束」。

第四步 · 推上去

两条规矩:

  1. 先传到临时位,再落位。 直接覆盖会让权限和属主跟着源文件走,可能变成不可读或不可执行。落位时显式设成目标该有的属主与权限。
  2. 落位后立刻双侧比对 md5。 不比就等于没验证——传输截断、编码变化、传错文件,都只有 md5 能发现。

输出:落位后的 md5 清单,与本地逐条相同。

第五步 · 线上实测(不能跳)

必须从线上取回来验证,不能看本地文件、不能看编辑器预览。 预览层会留旧件,它显示的「成功」不作数。

请求要带两样东西:

验四样,缺一不可:

验什么判据
状态码200;403/404/无响应都要当失败处理
字节数与本地文件一致(差几个字节通常是换行被改)
md5与本地一致(最硬的一条)
关键文字这次改的那句话,在取回的内容里能搜到

输出:四样实测值,全部对上才算部署完成。

第六步 · 收尾三件

  1. 补镜像:如果镜像不等于线上,补上。别信「同步脚本说一致」——很多脚本只比文件名不比内容。
  2. 重建派生件:索引、地图、清单这类从文件派生的东西,部署后必须重建。漏了就是「内容在,但找不到」。
  3. 提交版本库:把这次改动记进去,下次回退才有依据。

输出:三处一致(本地 / 镜像 / 线上)+ 一条版本记录。


出问题怎么办

按现象查,不要从头重来。

现象最可能的原因处理
双侧 md5 不一致传的是旧文件 / 落位失败核对源文件 md5,重传
200 但内容还是旧的缓存加 no-cache 重取;仍旧则查中间层缓存
无响应 / 连接被断UA 被安全规则拦了换完整浏览器 UA 再试
403 / 404路径写错,或落位后属主不对查实际落位路径与权限
内容对,但页面样式不对组件样式没重新合并重新合并样式表再推一次
改了一个页面,别的页也变了这页是从别处派生的重跑派生,别手改结果
回滚后还是不对备份件本身是新的用版本库历史重建,不要相信备份目录

最后一条是最贵的:回滚失败通常不是回滚动作错了,是回退点本身就选错了。


输出规范

人读

发布:<改了哪些文件>
回退点:<备份路径> · md5 已核等于改动前
推前状态:线上旧版 / 已是新版 / 缺失
实测:状态码 200 · 字节数一致 · md5 一致 · 关键文字命中
收尾:镜像已补 / 派生已重建 / 已提交版本库
未做:<这次没覆盖什么>

机器读

files: [{path, md5_before, md5_after, bytes}]
anchor: {path, md5, verified_equal_before: true|false}
precheck: {online_state: old|new|missing, concurrent: false}
verify: {status, bytes_match, md5_match, probe_text_found}
derived: {sitemap: rebuilt|skipped, index: rebuilt|skipped}
vcs: {committed: true|false, ref}

anchor.verified_equal_before 为 false 时,后面全部不算通过——没有可靠的回退点,这次发布不成立。

一句话版

已发布 N 个文件,回退点已核,线上四样全对。 或 发布未完成:卡在<哪一步>。

⛔ 不要说「大概好了」。四样里缺一样就是未完成。


常见错误


最后核对

2026-11-06。命令与工具因环境而异,但六步的顺序和四样实测判据通用。与所执行系统的既定标准冲突时,以那个系统的标准为准。

Markdown 原文 · 更新 2026-11-06
deploy-and-rollback · v1 · sop