composer镜像对ssh认证完全无效,因其仅加速公开包元数据和zip归档,不代理git协议克隆;私有仓库仍需git clone走ssh/https,故必须确保git clone git@xxx:org/repo.git静默成功,否则所有镜像、缓存清理均无效。

Composer 本身不参与 SSH 密钥分发,所谓“镜像下发密钥”是常见误解——实际生效的是 Git 的 SSH 配置机制。只要 git clone git@xxx:org/repo.git 能静默成功,Composer 就能拉下私有包;否则所有镜像、配置、缓存清理都无效。
为什么 Composer 镜像对 SSH 认证完全无效
Composer 镜像(如阿里云、腾讯云、Packagist.org)只加速 已公开索引的包元数据和 ZIP 归档,不代理 Git 协议克隆。私有仓库不会被镜像收录,Composer 在安装时仍会直接调用 git clone 命令走 SSH 或 HTTPS 协议拉取源码。
常见错误现象:
- 在
composer.json中配置了国内镜像,但私有包仍卡在Cloning into '/tmp/xxx' - 镜像设置后
composer update显示 “Package not found”,实则是 SSH 连接失败被静默忽略
根本原因:镜像只影响 packagist.org 类型的 HTTP 元数据请求,不触达 vcs 类型仓库的 Git 操作链路。
SSH Key 必须由 Git 层统一管理,不是 Composer 层
Composer 不读取、不加载、不转发任何密钥文件。它唯一依赖的是当前用户执行 git 命令时的环境行为。因此自动化下发必须落在 Git 可识别的位置:
-
~/.ssh/id_ed25519(或id_rsa)权限必须为600,否则ssh拒绝使用 -
~/.ssh/config中的Host名必须与 URL 中域名**逐字符一致**,例如url是git@gitlab.example.com:group/pkg.git,则Host必须写gitlab.example.com,不能写gitlab或gl - CI 环境中需显式启动
ssh-agent并ssh-add私钥,PHP 进程(如 Web 服务器)若以不同用户运行,需为其单独配置密钥目录和 agent socket
Git 全局 insteadOf 是最稳妥的自动化策略
硬编码 SSH 地址到 composer.json 容易被 IDE 自动转成 HTTPS、被 CI 工具误解析、或在团队协作中引发冲突。用 Git 自身重写机制更可靠:
运行以下命令一次,即可让所有 HTTPS 请求自动转为 SSH:
git config --global url."git@github.com:".insteadOf "https://github.com/"
对应 GitLab / 自建服务也同理:
git config --global url."git@gitlab.com:".insteadOf "https://gitlab.com/"git config --global url."git@git.example.com:".insteadOf "https://git.example.com/"
这样你在 composer.json 中可放心写 "url": "https://github.com/org/private-repo.git",Git 会在底层自动替换成 git@github.com:org/private-repo.git 并走 SSH 认证。该配置对所有 Git 操作生效,无需 Composer 特殊适配。
CI/CD 中最容易漏掉的三个点
本地能跑 ≠ CI 能跑。以下三项在 GitHub Actions、GitLab CI、Jenkins 中高频出错:
-
ssh-keyscan git.example.com >> ~/.ssh/known_hosts缺失 → 首次连接卡住,报Host key verification failed - 部署密钥未在**每个私有依赖仓库**中启用 → 主项目有密钥,但
org/private-lib仓库没勾选该密钥,导致克隆 404 或权限拒绝 - 私钥注入后未
chmod 600 ~/.ssh/id_rsa→ssh直接跳过该密钥,报Bad owner or permissions
复杂点在于:Git 的 SSH 行为受三重叠加影响——系统级 /etc/ssh/ssh_config、用户级 ~/.ssh/config、以及环境变量(如 SSH_AUTH_SOCK)。任一环节断开,git clone 就失败,Composer 无从补救。











