智核技术笔记

返回文章列表

静态网站的页面是构建时生成好的文件。更新一篇文章,不是在服务器上改那一页 HTML,而是改源文件、重新构建,再用新的文件替换网站目录。替换如果直接覆盖,构建出错或页面有问题时,就没有完整的上一版可以立刻换回。

把「源文件、构建结果、正在对外的目录、备份」分成四个位置,更新和回滚都只做复制,不在对外目录里临时改页面。

四个目录各放什么

以本站为例,可以按下面这样放:

位置内容能不能当网站根目录
源码目录文章、配置、主题不能,这里是工程
dist/本次构建出的 HTML、样式、脚本可以,但是候选版本
/srv/aicore/current现在对外的文件这是网站根目录
/srv/aicore/releases/时间戳一份完整的历史版本回滚时整份换上

源码目录里有依赖和中间文件,不能指给 Web 服务器。每次只发布 dist/ 里的结果。

发布前先留一份完整备份

在替换之前,把当前对外目录整份复制出来。目录名用时间,避免第二次发布把上一次备份盖掉:

stamp=$(date +%Y%m%dT%H%M%SZ)
mkdir -p /srv/aicore/releases
cp -a /srv/aicore/current "/srv/aicore/releases/${stamp}"
bash

cp -a 保留权限和时间。备份完成后看一下文件数量,不要只看命令没有报错。空目录复制成功,也仍然是空的。

服务器上如果同时跑着别的网站,备份和替换都只发生在这个站点自己的目录里,不要打包整个 /srv 或 Web 服务器的配置,除非这次确实改了配置。

用新目录替换,而不是在旧目录里覆盖

构建在源码目录完成,确认 dist/ 里有首页和文章后再上传。上传到一个新目录,例如 /srv/aicore/releases/20261026T090000Z,不要直接传进 current。

传完后在服务器上检查三件事:首页文件存在,一篇文章的路径存在,样式和字库也在这个目录里。然后把对外目录切过去。目录本身如果是一个符号链接,切换就是一次改链接:

ln -sfn /srv/aicore/releases/20261026T090000Z /srv/aicore/current
bash

Web 服务器的根目录指着 current,改链接后新请求就会读到新文件。已经打开的页面需要刷新。

如果系统不允许用符号链接,就保持两个真实目录,在 Web 服务器配置里把根目录从旧版本改成新版本,再重载配置。重载前保留旧配置的副本,这样切回去时有据可依。

出错时整份回滚

新版本出现页面打不开、样式丢失或文章内容不对,不要在对外目录里手改 HTML。那些改动会在下一次发布时被盖掉,也和源文件对不上。

回滚就是把 current 指回上一份备份:

ln -sfn /srv/aicore/releases/上一次的时间戳 /srv/aicore/current
bash

切回去以后,用浏览器打开首页、文章列表和刚才出错的那一篇,确认是旧内容。然后再回到源码里修,重新构建,作为再下一次发布。不要把服务器上改过的 HTML 反抄回源码,两条线会越差越远。

备份保留最近几份即可。确认新版本可用之后,再删更早的副本,给磁盘留空间。正在被 current 指着的那一份不能删。

常见错误

  • 只备份了新改的那篇文章。样式、脚本和搜索索引是一起生成的,缺任何一件,旧文章页也可能显示不完整。回滚要整份目录。
  • 构建失败了仍把半成品传上去。应先在本地打开构建结果,至少看首页和一篇文章。
  • 新版本覆盖了旧版本的同一目录,没有时间戳。发现问题时已经没有完整旧文件。
  • 改了文章却忘了重新构建,服务器上还是上一次的 HTML。源文件新、网页旧,核对的是网页而不是编辑器。
  • 回滚只换了页面,没换同时改过的服务器配置。配置和文件要各自有上一份可用的副本。

每次发布把四件事记下来:源码位置、使用的版本、对外目录、这次备份的路径。下次接手的人不需要从历史记录里猜哪一份是能用的。

小结

静态网站的更新单位是一整份构建结果,不是单个 HTML 文件。先把正在对外的目录完整备份,再把新结果放到带时间的目录里,检查后再切换。出问题就把对外目录指回备份,然后回到源码里修。这样每一次发布都可以前进,也可以退回上一个已知可用的版本。

静态网站的文章更新、备份与回滚实践
https://www.aicore.icu/blog/static-site-release
作者 智核技术笔记
发布于 2026年10月26日