必须用 SSH 协议 + 正确密钥加载 + Git URL 重写,三者缺一不可;HTTPS + PAT 仅为备选且 CI 中更易出问题,因 Composer 本身无认证逻辑,完全依赖 git clone 的底层认证,SSH 失败表现为 Permission denied 或 Host key verification failed,HTTPS 失败则静默卡住或报 401。

直接结论:必须用 SSH 协议 + 正确的密钥加载 + Git URL 重写,三者缺一不可;HTTPS + PAT 只是备选,且在 CI/CD 中更易出问题。
为什么 composer install 总卡在 Cloning into '/tmp/...' 或报 401?
根本原因不是 Composer 本身的问题,而是它调用 git clone 时底层认证失败。GitHub 已彻底禁用密码登录,HTTPS 方式若没配好 auth.json 或全局 github-oauth,就会静默卡住或返回 Could not fetch https://github.com/xxx/yyy;而 SSH 方式若密钥没加载、ssh-agent 没启用、或 ~/.ssh/config 缺失对应 IdentityFile,则表现为 Permission denied (publickey) 或 Host key verification failed。
常见错误现象:
- 本地运行
composer install成功,但 CI(如 GitHub Actions)失败 -
ssh -T git@github.com成功,但composer update仍拉不到私有库 - 报错提示
Failed to extract vendor/package: unable to create directory—— 实际是克隆阶段已静默失败
如何验证 SSH 密钥和 Git 配置是否真正生效?
别跳过这一步。Composer 不会告诉你“密钥没加”,只会让整个流程失败。
- 运行
ssh-add -l,确认输出里有你的私钥(如/Users/you/.ssh/id_ed25519);没有就执行ssh-add ~/.ssh/id_ed25519 - 检查
~/.ssh/config是否为 GitHub 显式指定了用户和密钥:Host github.com User git IdentityFile ~/.ssh/id_ed25519
- 手动测试 Git 克隆:
git clone git@github.com:your-org/private-package.git /tmp/test-clone—— 必须成功,Composer 才可能成功 - 如果用的是 ed25519 密钥但 Git 版本低于 2.32,可能不支持;可临时改用
ssh-keygen -t rsa -b 4096生成兼容密钥
composer.json 里该写 HTTPS 还是 SSH URL?
推荐写 HTTPS 地址,再靠 Git 的 insteadOf 规则自动转成 SSH —— 更健壮,也避免某些 IDE 或工具对 SSH URL 解析异常。
- 在
composer.json的repositories段写:"repositories": [ { "type": "vcs", "url": "https://github.com/your-org/private-package" } ] - 然后全局配置 Git 重写:
git config --global url."git@github.com:".insteadOf "https://github.com/" - 这样即使团队成员误写 HTTPS,也能走 SSH;而直接写
git@...在部分 CI 环境(如未预装 ssh-agent)下反而容易失败 - 切记:不要在
url里写https://token@github.com/...—— GitHub 已弃用该方式,且 token 泄露风险高
CI/CD 环境下最容易漏掉的三件事
本地能跑 ≠ CI 能跑。GitHub Actions、GitLab CI 默认不加载 SSH agent,也不信任未知 host key。
- 必须提前运行
ssh-keyscan github.com >> ~/.ssh/known_hosts,否则首次连接会卡死(报Host key verification failed) - CI 中不能依赖
ssh-add交互式加载;要用ssh-agent bash -c 'ssh-add 这类方式注入密钥 - PHP 进程用户(如
www-data)和当前 shell 用户不同 —— 若 Web 服务要触发composer install,需单独为该用户配置~www-data/.ssh/和ssh-agent
最常被忽略的点:Composer 缓存了之前失败的 HTTPS 请求记录。一旦试过 HTTPS + 错误 token,后续即使改用 SSH,也要先运行 composer clear-cache,否则它可能继续尝试旧路径。


















