必须备份 composer.json 和 composer.lock,因前者声明依赖意图,后者记录精确版本、commit hash、dist shasum及完整依赖树,缺一不可保证发布状态可重现。

只备份 composer.json 和 composer.lock
,其他都是干扰项。这两份文件是唯一能保证“重装即还原”的元数据,缺一不可。
为什么不能只 cp vendor/ 或 tar 整个项目?
vendor/ 是构建产物,不是源事实:它可能被本地修改、忽略 git、权限异常或缓存污染;而 composer.json 声明“要什么”,composer.lock 记录“实际装了什么”——包括每个包的 exact commit hash、dist shasum、完整依赖树和私有仓库地址。没有 composer.lock,composer install 会按当前时间点拉取最新兼容版本,比如 "laravel/framework": "^10.0" 可能在不同时间装出 v10.42.0 或 v10.48.0,行为不一致。
- 私有包路径(如
repositories中的path或内网 Git URL)只存在于composer.json,不备份就丢失上下文 - 某些已下线的 tag、删库的 package,在 packagist 上已不可获取,仅靠
composer.json无法重装 - 直接压缩 vendor/ 体积大、易损坏、且无法校验完整性(
composer.lock里有 dist shasum 可验证)
备份命令必须带环境+时间戳,禁止模糊命名
命名格式决定你能不能在故障时精准回滚。模糊名如 latest.lock、prod-backup.json 在 CI 日志或运维记录里根本无法追溯。
- 推荐路径:
releases/prod-20261104-2320-composer.lock(格式:环境-YYYYMMDD-HHMM-文件名) - 必须同时备份两个文件,命名严格对应:
prod-20261104-2320-composer.json - 一行命令搞定:
cp composer.{json,lock} releases/prod-$(date +%Y%m%d-%H%M)-composer.{json,lock} - 把这行加进你的
deploy.sh或 CI 脚本,别靠人工执行——人总会漏、会手抖、会忘记改名
CI/CD 流程中必须校验 lock 文件是否被意外修改
很多团队在 CI 里跑 composer install 却不检查 composer.lock 是否被开发者误提交或脚本覆盖,结果本地能过、CI 报错、上线后行为突变。
- CI 启动第一件事:
composer validate --no-check-all(检查composer.json格式与字段合法性) - 紧接着:
git diff --quiet composer.lock || (echo "composer.lock changed unexpectedly" && exit 1) - 如果 CI 环境 PHP 版本和生产不一致,
composer install会静默跳过不兼容包——加--ignore-platform-reqs是临时绕过,不是解决方案 - 私有包源变更后,
composer.lock里仍存旧 URL,install 会卡在 “Resolving dependencies”,要用composer show xxx/yyy手动确认可访问性
最常被忽略的一点:备份动作必须和数据库备份时间对齐。代码已升级、数据还是旧结构,一启动就报错。不要分开备份,要在 MySQL 备份脚本末尾追加 composer archive 或同步拷贝 composer.{json,lock},并在日志里并列记录两者的精确时间戳。











