必须在composer.json的repositories对应仓库options.ssl.cafile中配置绝对路径pem证书文件,含完整证书链且顺序正确,权限为644,否则ci/docker等环境会静默失效。

composer.json里怎么配sslcafile才生效
必须用绝对路径,相对路径在CI或Docker里基本失效。Composer不解析./或../,它直接传给PHP的stream_context,而PHP对相对路径处理不一致。
-
cafile值必须是完整路径,比如/var/www/project/certs/internal-ca.pem,不能写certs/internal-ca.pem - 文件得包含完整证书链:服务端证书 + 中间CA + 根CA,顺序必须是叶证书在前、根CA在末尾
- 权限设为
644,若属主不是运行PHP的用户(如www-data),读取会静默失败 - 配置位置在
repositories数组内对应仓库的options.ssl.cafile,不是顶层字段
全局cafile和openssl.cafile哪个优先级高
环境级(即openssl.cafile) > 用户级(composer config --global cafile) > 项目级(composer.json里的cafile)。但注意:全局cafile只影响Composer自身HTTP请求,不影响Git clone等子进程调用的cURL。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 改
php.ini里的openssl.cafile后,必须重启PHP CLI进程(如sudo systemctl restart php8.1-fpm);CLI模式下通常不用重启,但需确保下次执行时加载新配置 -
composer config --global cafile写入的是~/.composer/config.json,对所有项目生效,但无法控制Git操作的证书验证 - 若同时设了
openssl.cafile和composer config --global cafile,前者会覆盖后者——Composer底层优先读PHP配置
为什么用了cafile还是报unable to get local issuer certificate
这不是配置没生效,而是证书链本身不完整。cURL要求能从叶证书向上逐级追溯到可信根,缺中间证书或顺序反了都会触发这个错误。
- 别只导出服务端证书——用
openssl s_client -connect gitlab.example.com:443 -showcerts抓全链,再按顺序拼成PEM - 检查PEM文件是否含非ASCII字符、多余空行或注释;开头必须是
-----BEGIN CERTIFICATE-----,结尾必须是-----END CERTIFICATE----- - 用
curl -v --cacert /path/to/chain.pem https://your-repo.example.com单独测试,确认返回HTTP 200且无SSL certificate problem - 如果源是中文域名(如
https://pkg.公司名.内部),必须先转Punycode(xn--55qx5d.内部),否则证书域名匹配失败
镜像源和自签名源能共存吗
可以,但必须明确区分作用域。镜像源(repo.packagist)只代理Packagist.org元数据,不影响私有仓库;自签名源靠repositories单独声明,两者互不干扰。
- 全局镜像命令
composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/不会影响repositories里的私有源 - 若私有源也想走镜像加速,得自己搭Satis或Private Packagist,原生Composer不支持“镜像+自签名”嵌套
- 多个私有源混用时,每个都得配自己的
cafile,不能复用同一路径——除非它们共用同一CA签发 - CI环境中最容易漏的是:镜像配置写了
sudo composer config -g,但构建用的是runner用户,实际读的是/home/runner/.composer/config.json,不是root的
cafile路径,最后发现只是把根CA放最前面,或者源地址用了中文域名却没转Punycode。










