composer_auth必须为单行合法json,否则静默失效:要求严格单行、全小写键名、闭合引号、无尾随逗号、无空格或制表符;它完全替代auth.json,多源需合并配置,且须显式注入ci/docker环境。

COMPOSER_AUTH环境变量必须是单行合法JSON
CI/CD中用COMPOSER_AUTH传凭证,最常因格式非法静默失败——Composer不报错,只 fallback 到未认证请求,最终卡在401或“Could not find package”。
它要求:严格单行、无换行、键名全小写、引号闭合、逗号不漏、不能有尾随逗号。任何空格或制表符都可能破坏解析。
-
COMPOSER_AUTH='{"http-basic":{"gitlab.example.com":{"username":"oauth2","password":"glpat-xxx"}}}'✅ 正确 -
COMPOSER_AUTH='{ "http-basic": { "gitlab.example.com": { "username": "oauth2", "password": "glpat-xxx" } } }'❌ 含空格,失败 -
COMPOSER_AUTH='{"http-basic":{"gitlab.example.com":{"username":"oauth2","password":"glpat-xxx"}},}'❌ 尾随逗号,失败
建议用jq生成:echo '{"http-basic": {"'"$GITLAB_HOST"'": {"username": "oauth2", "password": "'"$GITLAB_TOKEN"'"}}}' | jq -c
COMPOSER_AUTH优先级最高,但会覆盖全局auth.json
设置COMPOSER_AUTH后,Composer完全忽略~/.composer/auth.json和项目级auth.json——不是叠加,是彻底替代。
这在多仓库场景下很关键:比如同时拉 GitLab 和私有 Packagist,你得把两个域名都写进同一个COMPOSER_AUTH值里,不能指望它“补全”全局配置。
- 双源示例:
COMPOSER_AUTH='{"http-basic":{"gitlab.example.com":{"username":"oauth2","password":"glpat-a"},"packages.internal":{"username":"ci","password":"token-b"}}}' - 若只写了一个域名,另一个仓库的请求将无认证,直接 401
- CI脚本开头应加校验:
composer config --global --list | grep -q "http-basic" || (echo "MISSING AUTH CONFIG" >&2; exit 1)
GitLab等HTTP Basic认证必须用http-basic字段,不能混用gitlab-token
gitlab-token字段只对 GitLab API 调用生效(如获取 tag 列表),而composer install拉取代码时走的是 Git 协议或 HTTPS 下的静态文件下载,必须靠http-basic提供凭证。
尤其当 GitLab 启用了require_two_factor或限制了 API 访问范围时,仅配gitlab-token会导致“Could not fetch”或“Repository not found”。
- GitLab 私有仓库 URL 是
https://gitlab.example.com/group/pkg.git→ 必须用http-basic字段,key 为gitlab.example.com - 若 URL 含端口(如
:8080),key 必须完整写成gitlab.example.com:8080,少一个字符都不匹配 -
gitlab-token字段此时无效,删掉反而更干净
COMPOSER_AUTH在Docker或GitHub Actions中必须显式注入
容器内或CI运行时,COMPOSER_AUTH不会自动继承宿主机环境变量;不显式声明,就等于没配。
GitHub Actions 示例(注意env层级和 secrets 引用):
env:
COMPOSER_AUTH: '{"http-basic":{"gitlab.example.com":{"username":"oauth2","password":"${{ secrets.GITLAB_TOKEN }}"}}}'
Docker CLI 示例:
docker run -e COMPOSER_AUTH='{"http-basic":{"gitlab.example.com":{"username":"oauth2","password":"glpat-xxx"}}}' -v $(pwd):/app php:8.3-cli sh -c "cd /app && composer install"
容易被忽略的一点:某些 CI 平台(如 GitLab CI)默认屏蔽敏感变量传递到子 shell,需确认COMPOSER_AUTH是否真正进入composer进程环境——最稳的方式是用printenv | grep COMPOSER_AUTH先验证。











