2026-08-17 · 建站运维
1dao.cc 家族的所有站点——主站、博客、禅道、导航、文件柜、商城——现在都跑在同一套部署模式上:walle 发布目录 + 符号链接切换 + 数据独立目录。这篇把符号链接的细节彻底讲清楚:它怎么做到秒级发布/回滚、数据为什么永远不怕被覆盖。
一、为什么需要符号链接
传统部署是直接覆盖线上目录,有两个痛点:
- 回滚难:新版本出问题,旧文件已被覆盖,只能从备份里翻
- 数据易失:代码目录里混着用户上传文件,一次误操作(覆盖/清空)就全没了
符号链接方案把「代码版本」和「线上入口」解耦:入口是一个链接,指向某个版本目录。换版本 = 换链接指向,数据则单独放数据目录,再靠一层链接接回来。
二、全站符号链接一览
站点链接(walle 管理,指向版本目录):
| 站点 | 链接 | 当前指向 |
|---|---|---|
| 主站 | /var/www/1dao.cc | releases/1dao.cc/20260816-215530 |
| 博客 | /var/www/blog | releases/blog/20260814-030230 |
| 禅道 | /var/www/zentao | releases/zentao/20260816-205041 |
| 导航 | /var/www/nav | releases/nav/20260817-003548 |
| 文件柜 | /var/www/files-page | releases/files/20260817-000729 |
| 商城 | /var/www/crmeb/crmeb | releases/crmeb/20260817-005243 |
数据链接(数据隔离,非 walle 管):
- 博客:
content/uploadfile → /var/www/blog-data/uploadfile(文章图片) - 商城:
public/uploads → /var/www/crmeb-data/uploads(商品图/主题图) - 文件柜:
/var/www/vault/index.html → /var/www/vault-src/index.html(单文件链接)
版本目录命名规则:YYYYMMDD-HHMMSS(部署时间),每个项目保留最近 5 个版本。
三、切换机制:三步原子换链
walle 的 getLinkCommand 核心就三条命令:
ln -sfn <新版本目录> <release库>/current-<项目>.tmp # ① 建临时链接
chown -h www-data <临时链接> # ② 修正链接属主(只改链接本身)
mv -fT <临时链接> <线上入口> # ③ 原子替换
关键在第三步:mv 在同一文件系统内是 rename 原子操作。也就是说:
- 任何时刻访问
/var/www/blog,指向的都是一个完整存在的版本 - 切换瞬间完成,没有「删旧建新」的空窗期,不会出现 404 或读到一半的状态
chown -h的-h很重要:不加的话会把目标目录的属主改掉
四、数据链接的继承:cp -arf
walle 部署用的是增量传输模式,解压新版本前先执行:
cp -arf <线上目录>/. <新版本目录>
-a(archive)会把符号链接原样复制为链接,而不是解引用复制内容。所以:
uploads → crmeb-data/uploads这种链接会自动「继承」到每个新版本- 用户数据永远只存一份在数据目录,不随代码重复打包、不会被覆盖
- 商城 release 里的
.env(数据库/Redis 配置)虽然不在 git 仓库里,也靠这步从线上复制过来,内容始终与数据目录一致
五、回滚与保留策略
- 回滚:重新部署旧版本,链接指向旧版本目录,秒级切回。walle 的 rollback 就是这个原理
- 保留:每个项目 releases 下保留 5 个版本,超出的旧目录自动清理
- 链接本身:都是绝对路径,权限恒为 777(链接权限无意义,实际看目标目录),属主 www-data
六、细节与坑
- 链接属主:早期博客的链接属主是 root(部署机制修正前的遗留),不影响运行,但新部署都会
chown -h成 www-data - nginx 层面:
root /var/www/crmeb/crmeb/public默认跟随符号链接(disable_symlinks off),PHP-FPM 的SCRIPT_FILENAME走$document_root同样跟随,无需额外配置 - 单文件链接:文件柜的 index.html 是单文件链接(非 walle 管),因为它的源目录
vault-src独立维护
总结
这套架构的本质一句话:代码在 releases/ 时间戳目录里,入口靠符号链接原子指向当前版本,用户数据再靠第二层链接隔离在数据目录。发布、回滚都是秒级换链,数据永不被覆盖——这也是备份体系「只备份不可重建数据」原则的落地基础。
文章导出
生成预览中...