composer私有仓库配置必须显式声明"packagist.org": false,否则即使url正确、包存在,仍报could not find package;正确写法是将其置于repositories同级顶层,且url末尾斜杠不可省。

私有仓库 URL 配置必须显式禁用 packagist.org
不加 "packagist.org": false,Composer 就永远优先查官方源,哪怕你的私有包 100% 存在、URL 完全正确,也会报 Could not find package vendor/name。这不是网络或认证问题,是匹配逻辑被默认源劫持了。
常见错误写法:
{ "repositories": [{ "type": "composer", "url": "https://repo.example.com/" }] }
正确写法(注意末尾斜杠不能省,"packagist.org": false 必须顶层):
{ "repositories": [{ "type": "composer", "url": "https://repo.example.com/" }], "packagist.org": false }
- Artifactory/Satis/Nexus 等所有 composer 类型私有源都适用该规则
- 如果用了虚拟仓库聚合多个源,确保后端至少有一个
type: composer的本地或远程仓库,Generic 类型不识别 - URL 中
/api/composer/路径不可替换成/api/npm/或其他协议路径
auth.json 是唯一安全的凭证落点
把账号密码、Token、App Password 写进 composer.json 是高危操作——它会随代码提交,暴露在 Git 历史里。Bitbucket 已停用账号密码登录 API,必须用 App Password,且权限需包含 account:read 和 repository:read。
正确做法只有一条路:用 auth.json,并确保它在 .gitignore 里。
- 全局配置(推荐):
composer config --global http-basic.repo.example.com username password - Bitbucket App Password 示例:
composer config --global http-basic.bitbucket.org username app_password_here - GitLab OAuth Token:
composer config --global gitlab-oauth.gitlab.example.org your_token - 环境变量方式(CI/CD):
COMPOSER_AUTH='{"http-basic":{"repo.example.com":{"username":"u","password":"p"}}}'
vendor 目录只读 ≠ chmod -R 555
chmod -R 555 vendor/ 是典型误操作:PHP 进程连 opendir() 都失败,报错如 failed to open stream,因为目录缺执行位(x),无法遍历子目录。
真正可行的只读方案是分层控制:
-
chown -R deploy:deploy vendor/—— 归属部署用户,避免 root 残留 -
chmod 755 vendor/—— 目录必须有 x 权限才能进入 -
find vendor/ -type f -exec chmod 644 {} \;—— 所有文件去写位 -
chmod +x vendor/bin/* 2>/dev/null || true—— 只放行明确要执行的二进制(如phinx) - 若框架依赖动态类映射(如某些插件机制),单独保留
vendor/composer/autoload_classmap.php可写;否则应预生成并设为644
自定义 CA 证书必须全局配置且格式严格
内网私有仓库用自签名或企业 CA 时,composer config ssl.cafile 很容易配了却没生效——Composer ≥2.5 不报错,而是静默 fallback 到系统 CA,继续抛 cURL error 60。
关键点只有三个:
- 证书文件必须是 PEM 格式完整链:中间 CA 在前、根 CA 在后,用
cat intermediate.pem root.pem > combined.pem拼接,别手动编辑 - 必须用
--global配置:composer config --global ssl.cafile /etc/ssl/certs/company-ca.pem - 确认 PHP 进程能读:Nginx + PHP-FPM 下,
www-data用户可能无权读家目录下的文件,建议放系统路径并设宽松组读
验证是否生效:composer config --global --list | grep ssl.cafile,输出应为实际绝对路径;再试 composer install,不再报 SSL 错误才算到位。











