Satis仅生成静态文件,不自动更新,必须手动或定时执行build命令;备份需包含整个输出目录(含packages.json、provider文件及dist/ ZIP),并保留历史快照与校验机制。

为什么不能只靠 Satis build 一次就完事
Satis 生成的是静态文件,packages.json 和 dist/ ZIP 包一旦生成就不再自动更新——哪怕你 Git 仓库里已经 merge 了新 tag,Satis 也不会感知。没人手动或定时触发 php bin/satis build,私有源就等于“停更”。下游项目执行 composer update 时仍会拉到旧版本,甚至因 provider 数据缺失报 Could not find package。
备份 ≠ 生成,得把元数据和归档一起存下来
真正要备份的不是 Satis 的配置文件,而是它 build 出来的整个输出目录(比如 web/):里面包含 packages.json、所有 p/xxx/ 下的 provider 文件、以及 dist/ 里的 ZIP 归档。漏掉 dist/,composer install 会 fallback 到 source clone,失去离线/加速价值。
- 用
rsync -a --delete web/ /backup/satis-$(date +%Y%m%d)/比 tar 更安全(保留软链、权限、增量同步) - 备份前加校验:
find web/ -name "*.json" -exec jsonlint {} \; 2>/dev/null | grep -q "ERROR" && exit 1,防元数据写坏静默失败 - 不要只备份
packages.json—— 它只是索引,真正安装时 Composer 会按需请求p/monolog/monolog.json这类 provider 文件
定时任务必须带环境隔离与失败告警
在 CI 或独立服务器上跑定时 build,容易踩两个坑:一是没加载正确的 PHP 扩展(比如 missing ext-zip 导致 dist 包生成失败),二是没设 COMPOSER_AUTH 导致私有 Git 仓库无法 clone。
- 用完整环境启动:写成 shell 脚本封装
php -d extension=zip.so bin/satis build satis.json web/ - 失败必须中断并通知:加上
|| (echo "Satis build failed at $(date)" | mail -s "Satis Backup Alert" team@example.com) - 别用
@daily简单调度 —— 改成0 3 * * * cd /path/to/satis && ./build-and-backup.sh,确保路径和用户上下文一致
历史快照要可追溯,不能只留 latest
每次 build 都覆盖 web/ 目录,等于丢掉所有历史 provider 数据。某天发现 v2.1.0 有严重 bug,想回退到 v2.0.5 的元数据?没存就只能重跑 Git 历史 + 手动指定 commit hash 构建,耗时且易错。
建议按日期+Git commit 做快照目录:/backup/satis/20261103-abc123/,并在根目录放一个 manifest.json 记录本次 build 覆盖的包名、版本范围、Git HEAD。这样查问题时,curl https://satis.internal/20261103-abc123/packages.json 就能确认当时元数据是否完整——而不是对着线上 latest 干瞪眼。











