私有包发布前必须预编译产物,否则composer install仅获取源码导致线上报错;需手动构建、提交产物、配置archive zip、避免post-install-cmd、设置platform与stability、同步完整vendor目录。

私有包发布前必须预编译产物
Composer 不执行构建命令,所以 composer install 拿到的只是源码——如果私有包含 dist/、bin/ 或扩展 .so 文件,而这些没被提交进 Git 或打包进 dist zip,线上就会直接报错(比如 JS 404、Class not found、extension not loaded)。
实操建议:
- 在打 tag 前,手动运行构建脚本(如
npm run build、make、php artisan package:build),把产出物提交进仓库 - 若用 Satis 或 Private Packagist,确保配置了
"archive": {"format": "zip"}并启用了--skip-dev归档逻辑 - 不要依赖
post-install-cmd自动构建:CI 环境可能缺 Node.js/GCC,且该钩子在生产机上运行风险极高
composer.json 里 platform 和 stability 配置决定能否装上
私有包若声明了 "php": "^8.2",但你的生产环境是 PHP 8.1,composer install 就会跳过它或报版本冲突——哪怕你实际代码完全兼容。同理,"stability": "dev" 或未设 "minimum-stability",可能导致私有包被当成不稳定版本拒绝安装。
实操建议:
- 在根项目的
composer.json中显式设置"platform": {"php": "8.1"},强制 Composer 模拟目标环境解析依赖 - 私有包的
composer.json必须有明确"type": "library"和合理"autoload"(PSR-4 路径不能指向tests/或examples/) - 避免在私有包中写
"require-dev"引用构建工具;那些应放在 CI 脚本里,而非依赖树中
部署时 vendor 目录必须整体同步,不能只跑 install
生产机上运行 composer install 是高危操作:它会尝试写缓存、生成 autoload、执行脚本,而 web 用户(如 www-data)通常无权写 vendor/composer/,导致 500 或静默失败。更糟的是,如果私有包源是 path 类型或需要 HTTP 认证,线上根本连不上。
实操建议:
- 所有
composer install --no-dev --optimize-autoloader --classmap-authoritative必须在干净 CI 环境或本地完成,然后把整个vendor/打包上传 - 若用
path仓库,发布前先composer archive打 zip,再推到私有 repo;别让生产机现场git clone - 验证方式:上线后运行
php -r "require 'vendor/autoload.php'; echo class_exists('My\Private\Class') ? 'OK' : 'FAIL';"
私有源认证和镜像配置容易漏掉 HTTPS 和 CA
用 composer config repositories.mypriv http://repo.internal/packages.json 后,composer update 可能卡住或报 cURL error 60: SSL certificate problem——不是密码错,而是私有源用了自签名证书,或 Nginx 没配全中间 CA。
实操建议:
- 生产部署脚本里加
export COMPOSER_CAFILE=/etc/ssl/certs/my-company-bundle.crt,并确保该路径被 PHP 的 openssl 扩展识别 - 私有源 JSON 接口必须返回标准格式,尤其
packages字段不能为空数组;可用curl -H "Accept: application/json" http://repo.internal/packages.json直接测 - 避免在
composer.json里硬编码 token:"http://token:x-oauth-basic@repo.internal";改用composer config http-basic.repo.internal user pass存凭据
path 仓库一切正常,一上生产就崩——因为 dist/ 没提交、zip 没包含 build 结果、或者 autoload 映射路径写错了却没在优化模式下暴露。


















