真正可离线部署的 vendor 目录须用 composer install --no-dev --optimize-autoloader --no-scripts --no-plugins 生成,确保干净、精简、可移植,并严格校验 composer.json、composer.lock、vendor/autoload.php 及 PHP 环境一致性。

生产环境离线打包发布,核心不是“让 Composer 在断网时还能联网”,而是彻底切断所有网络路径,把依赖安装变成纯文件搬运 + 静态校验动作。只要漏掉一个配置或跳过一次验证,上线后就可能报 Class not found 或卡在 Could not fetch https://repo.packagist.org/packages.json。
怎么生成真正可离线部署的 vendor 目录
不能靠本地开发机随便 composer install 一下就打包。必须确保 vendor 是“干净、精简、可移植”的:
-
composer install --no-dev --optimize-autoloader --no-scripts --no-plugins是唯一安全组合;加--no-dev不只是省空间,更是防止 dev-only 包(如phpunit)带入不兼容的 bin 脚本或扩展依赖 -
--optimize-autoloader会生成vendor/composer/autoload_classmap.php,避免运行时扫描目录——这对没 opcache 的容器或低配机器尤其关键 - 执行前确认
composer.lock存在且未被修改;若用git clone拉项目,注意.gitattributes可能 exclude 掉某些包里的资源文件 - 别用
zip -r vendor.zip vendor/直接压——先tar -czf release.tgz .打整个项目(含composer.json、composer.lock、vendor/),否则 autoload 路径错位
为什么 COMPOSER_DISABLE_NETWORK=1 必须写在命令前,不能只设 ENV
这个环境变量是硬开关,但它的生效时机很刁钻:只有在 Composer 启动初期读取,且会被项目级配置覆盖。常见失效场景:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- Dockerfile 里写了
ENV COMPOSER_DISABLE_NETWORK=1,但后续RUN composer install是在新 shell 中执行,变量未继承(尤其用了sh -c包裹时) - 项目
composer.json里有"repositories"字段指向https://packagist.org,它会优先于全局 config 生效 - 没同时运行
composer config --global repo.packagist false,导致即使禁网,Composer 仍尝试 DNS 解析 packagist 域名 - 验证方法:进容器后执行
COMPOSER_DISABLE_NETWORK=1 composer install --no-plugins -v 2>&1 | grep -i 'fetch\|http',不应出现任何 URL 输出
离线发布包里必须包含哪些文件才不会踩坑
只拷 vendor/ 和 composer.lock 是最低要求,但容易翻车。真正稳妥的发布包至少含:
-
composer.json(必须,autoload 配置、scripts 定义全靠它) -
composer.lock(必须,版本锁定和 dist shasum 校验全靠它) -
vendor/(必须,但得是上一步用标准参数生成的) -
vendor/autoload.php(必须,不能删,它是 PSR-4 自动加载入口) - 如果项目含自定义 bin 脚本(如
bin/console),要确认其 shebang 是#!/usr/bin/env php,且目标机php在$PATH中 - 不要包含
node_modules/、.git/、tests/——这些在tar时用--exclude过滤更可靠
怎么验证打包结果真能离线运行
别只测 composer --version 或 php -m | grep mbstring。真实验证必须模拟断网 + 运行时加载:
- 启动容器后立刻执行
ip link set eth0 down(或用docker run --network none) - 运行
COMPOSER_DISABLE_NETWORK=1 composer install --no-plugins --no-scripts --no-autoloader --no-dev,看是否秒过(不报错、不卡住) - 再跑
composer dump-autoload -o,确认没触发任何网络请求(加-v可观察) - 最后用目标 PHP SAPI(如
php-fpm或php -S)启动一个最小 index.php:require 'vendor/autoload.php'; echo class_exists('Monolog\Logger') ? 'OK' : 'FAIL'; - 最容易被忽略的一点:PHP 版本和扩展必须一致。比如源机是 PHP 8.3 +
ext-pcntl,目标机缺pcntl,composer install不报错,但运行时直接Fatal error

















