composer install 报错 curl error 60 的根本原因是系统或 php 缺失可信 ca 根证书,需通过 openssl_get_cert_locations() 确认默认证书路径,优先使用 php 自带或系统证书,并用 composer config -g cafile 正确配置,避免项目级配置覆盖、路径格式错误及权限问题。

composer install 报错 cURL error 60:SSL certificate problem
这是最常见现象,本质是 Composer 请求 packagist.org 时,系统找不到可信的 CA 根证书,或证书过期。不是网络问题,也不是 Composer 本身坏了,而是它默认依赖系统的 CA 证书路径(比如 Linux 的 /etc/ssl/certs/ca-certificates.crt),而某些环境(Docker、Windows WSL、自定义 OpenSSL)里这个路径不对或文件缺失。
- 检查当前生效的 CA 路径:运行
php -r "print_r(openssl_get_cert_locations());",重点关注default_cert_file和cafile字段 - 确认该路径下文件真实存在且可读:
ls -l /path/to/cacert.pem,权限不足也会静默失败 - 别直接改系统证书目录——容易影响其他 PHP 扩展(如 cURL、stream),优先走 Composer 自身配置
用 config 命令设置 cafile 不生效?
很多人执行 composer config -g cafile /path/to/cacert.pem 后仍报错,原因通常是:Composer 会优先读取项目级 composer.json 中的 config.cafile,如果项目里已定义且为空或错误路径,全局配置会被忽略。
- 先检查项目根目录是否有
composer.json,打开看有没有"cafile"字段,有就删掉或修正 - 全局配置写入的是
~/.composer/config.json,手动打开确认cafile值是否被正确写入、路径是否带多余空格或引号 - Windows 用户注意路径分隔符:必须用正斜杠或双反斜杠,
C:cacert.pem会失败,要写成C:/cacert.pem或C:\cacert.pem
怎么拿到可靠的 cacert.pem 文件?
别从网上随便下载 PEM 文件,也别用浏览器导出的证书——它们不包含完整信任链。最稳妥的方式是复用 PHP 或系统已验证过的证书源。
- Linux/macOS:直接用系统证书包,路径通常是
/etc/ssl/certs/ca-certificates.crt(Debian/Ubuntu)或/etc/pki/tls/certs/ca-bundle.crt(RHEL/CentOS) - PHP 自带证书(推荐):在
openssl_get_cert_locations()输出里找default_cert_file对应的路径,那个文件就是 PHP 编译时绑定的可信证书集 - 临时调试可用 curl 官方 PEM:
curl -o cacert.pem https://curl.se/ca/cacert.pem,但生产环境建议用系统或 PHP 自带版本
CA 配置对私有仓库的影响
如果你还用了私有 Packagist(如 Satis、Private Packagist)或 GitLab/GitHub Packages,CA 配置同样起作用——但仅限 HTTPS 协议。HTTP 仓库不会校验证书,也不受 cafile 影响;而自签名证书的私有 HTTPS 仓库,光配 cafile 不够,还得关掉证书校验(不推荐)或把私有 CA 加进 cacert.pem 文件末尾。
- 私有仓库用自签名证书?把它的根证书内容追加到
cacert.pem文件末尾,保持 PEM 格式(以-----BEGIN CERTIFICATE-----开头) - 绝对不要设
secure-http: false或verify-peer: false来绕过错误——这会让所有 HTTPS 请求裸奔,包括密码、token 传输 - Docker 环境尤其要注意:基础镜像(如
php:alpine)默认没装 CA 包,得在Dockerfile里加apk add --no-cache ca-certificates并确保update-ca-certificates运行成功
CA 路径配置看着简单,实际牵扯 PHP、OpenSSL、操作系统、容器环境四层证书信任链。最容易被忽略的是:修改后必须确认 PHP 进程重新加载了配置(比如重启 CLI 或 FPM),而不是只改了文件就以为完事了。










