CI/CD中COMPOSER_AUTH注入失败主因是JSON格式非法,必须为单行、键名全小写、无换行空格,推荐用jq生成;私有Git源与中文镜像可共存,但需在composer.json中将镜像置repositories首位并设"packagist.org": true。

CI/CD里用COMPOSER_AUTH注入凭证,为什么总失败?
失败主因不是权限不对,而是JSON格式非法——换行、多余空格、键名大小写错误、逗号遗漏,都会让Composer静默忽略整个COMPOSER_AUTH值,且不报错。
- 必须是单行纯JSON:
COMPOSER_AUTH='{"http-basic":{"packages.your-company.com":{"username":"ci","password":"xxx"}}}' - 键名严格小写:
http-basic不能写成Http-Basic或HTTP_BASIC - 禁止在CI脚本里拼接字符串生成JSON,改用
jq:echo '{"http-basic": {"'"$REPO_HOST"'": {"username": "'"$CI_USER"'", "password": "'"$CI_TOKEN"'"}}}' | jq -c - CI第一步加校验:
composer config --global --list | grep -q "http-basic" || (echo "MISSING AUTH CONFIG" >&2; exit 1)
私有Git仓库(vcs)和中文镜像(packagist)能共存吗?
能,但顺序和结构错了就会丢包——composer config repo.packagist会清空整个repositories数组,导致vcs源失效。
- 手动编辑
composer.json,把镜像源放在repositories数组最前面: {"type":"composer","url":"https://mirrors.aliyun.com/composer/"}- 私有Git源跟在后面:
{"type":"vcs","url":"git@git.internal/pkg.git"} - 显式保留兜底项:
"packagist.org": false不行,必须写"packagist.org": true,否则私有源挂了就彻底找不到包
为什么CI里composer install卡住或装错版本?
因为默认行为依赖交互、缓存和本地配置,而CI环境既没用户也没auth.json文件,还常禁用脚本执行。
- 强制关闭所有干扰项:
composer install --no-interaction --no-progress --optimize-autoloader --no-scripts -
--no-scripts尤其关键:很多post-install-cmd会调用php artisan或写配置,CI里缺环境变量直接崩 - 绝不运行
composer update:CI只认composer.lock,没提交lock文件?构建必须失败 - Docker中启用分层缓存时,加
--prefer-dist;同时用config.platform.php锁定PHP版本,避免因CI容器PHP小版本差异触发重编译
auth.json放哪最安全?
项目根目录下的auth.json本身不危险,危险的是它被提交进Git——哪怕只是“临时注释掉”,历史记录里密码永远存在。
- 开发机上可用项目级
auth.json,但必须加进.gitignore - 全局
auth.json(~/.composer/auth.json)适合多项目共享,但CI容器里不该存在 - CI/CD唯一推荐方式就是
COMPOSER_AUTH环境变量,且仅限当前构建生命周期 - 绝对禁止在
composer.json里硬编码凭证,包括注释行——Git历史不可删,泄露即永久
packagist.org兜底项的布尔值写法和COMPOSER_AUTH的JSON生成方式。这两处出错不会抛异常,只会让私有包“神秘消失”或“始终走公网下载”,排查起来极耗时间。


















