Composer 不提供 vendor 快照备份功能,直接 tar/zip vendor 目录不可靠,因二进制扩展、平台差异、符号链接及 install 参数(如 --no-dev)会导致还原失败;可靠方式是备份 composer.lock + 固定 PHP 版本 + 一致安装参数。

Composer 本身不提供 vendor 快照备份功能,直接 tar 或 zip vendor/ 目录在多数生产场景下不可靠——因为二进制扩展、平台特定的编译产物、符号链接和 composer install --no-dev 等行为会导致还原失败。
为什么不能直接打包 vendor 目录
很多团队第一次尝试用 tar -czf vendor-backup.tgz vendor/ 备份,结果在另一台机器或 CI 环境解压后跑不起来。常见原因包括:
-
vendor/bin/下的可执行文件可能依赖绝对路径或硬编码的../vendor/autoload.php,迁移后路径失效 - 像
ext-redis、grpc这类扩展包,在不同 PHP 版本或架构(x86_64 vs aarch64)下编译的.so文件无法通用 -
composer install会根据composer.lock中的content-hash校验依赖一致性;手动替换vendor/后,下次composer update可能误判为“未安装”,触发重装 - 某些包(如
laravel/sail)会在post-install-cmd中生成本地配置,这些不会被包含在纯 vendor 打包中
真正可靠的备份方式:锁文件 + 完整安装上下文
关键不是备份 vendor,而是确保能在任意环境 100% 复现相同 vendor。这需要三样东西:
-
composer.lock(必须提交到 Git,且不能忽略) - 明确的 PHP 版本(写在
.php-version或 CI 配置里,比如 GitHub Actions 的php-version: '8.2') - 一致的安装参数(尤其是
--no-dev、--optimize-autoloader、--apcu-autoloader—— 这些会影响vendor/composer/autoload_*.php的生成结果)
示例:CI 中稳定还原的命令应固定为
composer install --no-dev --optimize-autoloader --apcu-autoloader --no-interaction
注意:--apcu-autoloader 仅在启用 APCu 时生效,否则会被忽略;但一旦用了,就必须在目标环境启用 APCu,否则启动报错 Class "Composer\Autoload\ApcuClassLoader" not found。
需要离线恢复?用 composer archive + 自建私仓镜像
当网络受限(如内网部署、航空管制区服务器),不能依赖 packagist.org 时,有两个轻量级方案:
- 用
composer archive打包单个包(如composer archive vendor/my/package 1.2.3 --format=zip),再集中上传到内网 HTTP 服务,然后在composer.json中加自定义仓库:
{
"repositories": [
{
"type": "package",
"package": {
"name": "my/package",
"version": "1.2.3",
"dist": {
"url": "https://intranet.example.com/pkg/my-package-1.2.3.zip",
"type": "zip"
}
}
}
]
}- 更推荐:用
satis或toran-proxy(已停更)搭建最小化镜像站,只同步composer.lock中出现的包及其依赖,生成静态 JSON 元数据。这样composer install仍走标准流程,只是源换成了内网地址
别碰 composer dump-autoload --classmap-authoritative 的产物做备份——它生成的 classmap 是基于当前文件系统路径的,移动后 class_exists() 会返回 false。
紧急回滚时最安全的操作顺序
线上出问题要秒级回退,别删 vendor 再重装(太慢)。优先走以下路径:
- 确认上一个可用的
composer.lock提交哈希(比如 git log -p composer.lock | grep "^-" | head -n1) - 执行
git checkout <old-lock-hash> -- composer.lock</old-lock-hash>(只切 lock 文件) - 立刻运行
composer install --no-dev --no-interaction(不加--optimize-autoloader,避免因 APCu 缺失导致失败) - 验证通过后,再补上优化参数重建 autoloader
记住:lock 文件是唯一真相源,vendor 目录只是它的瞬时投影。任何绕过 lock 的“快速备份”都会在某个周五下午三点让你重新理解什么叫“确定性构建”。


















