离线环境必须备份 composer.lock,它是离线部署的唯一元数据权威来源,记录每个包的精确版本、dist URL、shasum 和完整依赖树;vendor 可重装,但 lock 缺失或被修改会导致 composer install 报错“Could not find package”或“Your requirements could not be resolved”。

离线环境必须备份 composer.lock,不是 vendor 目录
composer.lock 是离线部署的唯一元数据权威来源,它记录了每个包的精确版本、dist URL、shasum 和依赖树。vendor/ 只是产物,可丢可重装;但 lock 文件一旦缺失或被手动修改,composer install 在离线时会直接报 Could not find package 或校验失败。
常见错误现象:把 vendor/ 打包带走,却漏掉 composer.lock,结果离线机执行 composer install 时提示 “Your requirements could not be resolved”,实际是因为没 lock 就等于没“采购清单”。
- 必须确认
composer.lock文件存在且未被 gitignore 排除(检查git status是否显示它) - lock 文件中不能含
"source": {"type": "git", "url": "..."}类条目——这类包在离线时无法还原,应改用"dist"方式发布或提前打成 artifact - 建议用
composer validate检查 lock 文件语法合法性,避免因格式错误导致离线解析失败
打包 vendor 目录前要跑 --optimize-autoloader
直接复制 vendor/ 虽快,但若源机未启用优化,autoload.php 里可能含大量 symlink 或相对路径引用,在目标机(尤其是不同 OS 或 UID)下会失效,运行时报 Class not found。
正确做法是在与目标环境一致的 PHP 版本和扩展下执行完整安装,而非只拷文件:
- 在联网机执行:
composer install --no-dev --prefer-dist --optimize-autoloader --no-scripts --no-plugins - 验证 autoload:
php -r "require 'vendor/autoload.php'; echo class_exists('Psr\Http\Message\RequestInterface') ? 'OK' : 'FAIL';" - 打包整个项目目录(含
vendor/、composer.json、composer.lock),不要只打包 vendor/ 子目录
离线包要用 artifact 仓库,别碰 path 或 vcs
想让多个项目复用同一套离线包(比如新项目也要装 monolog/monolog),不能靠 path 仓库——它只对单个项目有效,且要求包目录结构严格匹配;更不能用 vcs(如 git)类型,离线时根本拉不了代码。
真正可迁移的离线包方案是 artifact 仓库:把每个包打成 ZIP,并在 repositories 中声明为本地 ZIP 目录。
- 打包命令(在已安装好依赖的项目中运行):
composer archive --format=zip --dir=./artifacts/ monolog/monolog - 项目
composer.json中添加:{"type":"artifact","url":"./artifacts/"} - 必须确保 ZIP 包内含合法
composer.json,且其中version字段与composer.lock中一致 - artifact 仅支持顶层包,子依赖仍需出现在 lock 文件中并被打包,否则 install 时会卡住
COMPOSER_DISABLE_NETWORK=1 是所有离线操作的前提
这个环境变量不是“建议开启”,而是硬开关。不设它,composer install 会无视所有 --no-xxx 参数,坚持请求 https://repo.packagist.org/packages.json,报错后直接退出。
很多人以为只要 vendor/ 和 lock 都在,就能跳过网络,结果还是失败——问题就出在这一步没配。
- Dockerfile 中写:
ENV COMPOSER_DISABLE_NETWORK=1 - Shell 命令前加前缀:
COMPOSER_DISABLE_NETWORK=1 composer install --no-plugins --no-scripts --no-autoloader - Windows CMD:
set COMPOSER_DISABLE_NETWORK=1 && composer install ... - 别用
--offline:该参数不存在,是常见误传
最易被忽略的是:即使你用了 artifact 或 path 仓库,不设这个变量,Composer 仍会 fallback 到 Packagist 校验元数据,最终失败。











