Composer拉取私有包报Permission denied (publickey)是SSH认证失败:需检查ssh -T连通性、私钥权限600、~/.ssh/config配置、Deploy Key是否添加,CI中推荐HTTPS+token替代SSH。

Composer 拉取私有包时提示 Permission denied (publickey)
这是最典型的 SSH 配置问题:Composer 通过 git@github.com:user/repo 这类 SSH URL 访问私有仓库,但本地 SSH agent 没有加载对应密钥,或密钥权限不正确。
检查步骤和修复建议:
- 运行
ssh -T git@github.com(或你用的 Git 托管平台,如git@gitlab.com),确认是否能成功认证;失败则说明 SSH 层不通,Composer 必然失败 - 确保私钥文件权限为
600:chmod 600 ~/.ssh/id_rsa(或你的私钥路径) - 确认
~/.ssh/config中为该主机配置了正确的IdentityFile和User(例如User git) - 如果使用 GitHub App 或 Deploy Key,需确认该密钥已添加到对应仓库的
Deploy keys设置中,并勾选Allow write access(仅限需要推送时)
composer.json 中写死 SSH URL 却在 CI 环境下失败
CI 环境(如 GitHub Actions、GitLab CI)通常没有交互式 SSH agent,也默认不加载用户级 ~/.ssh/config,直接写 "repo": "git@github.com:org/private-package.git" 会因无密钥而卡住。
推荐做法是改用 HTTPS + token 认证,更可控:
- 生成一个只读 Personal Access Token(GitHub)或 Project Access Token(GitLab),赋予
read_package_registry或read_repository权限 - 在
composer.json中改用 HTTPS URL:"repo": "https://token:x-oauth-basic@github.com/org/private-package.git" - 更安全的做法是配合
auth.json(支持环境变量注入):{ "github-oauth": { "github.com": "${GITHUB_TOKEN}" } }然后在 CI 中用COMPOSER_AUTH环境变量传入 JSON 字符串,避免硬编码
私有 Packagist(如 Satis、Private Packagist)启用后仍拉不到包
即使配置了私有仓库,Composer 默认仍会尝试从 packagist.org 回退查找——如果包名与公开包冲突,或 repositories 顺序/类型配置错误,就会跳过私有源。
关键检查点:
-
repositories数组中,私有源必须放在packagist.org条目之前,或显式禁用默认源:{ "repositories": [ { "type": "composer", "url": "https://your-private-packagist.com" }, { "packagist.org": false } ] } - 确保私有源返回的
packages响应中,包名、版本、distURL(尤其是url字段)全部可访问;常见错误是dist.url写成内网地址,CI 无法解析 - 运行
composer clear-cache后再composer update --verbose,观察日志里是否真正请求了私有源的packages.json
使用 composer config --global github-protocols https 的真实效果
这个命令不会“修复” SSH 问题,它只是让 Composer 在遇到 GitHub 包时,自动把 git@github.com:... 转成 https://github.com/... —— 本质是绕过 SSH,转走 HTTPS 流程。
但它有局限:
- 只对 GitHub 生效(硬编码逻辑),对 GitLab、自建 Gitea 等无效
- 若包
composer.json显式声明了"source": {"url": "git@..."},此设置会被忽略 - HTTPS 方式仍需 token 或
auth.json支持,否则会遇到401 Unauthorized - 建议仅作为临时调试手段,生产环境应明确控制协议与凭证方式
私有包拉取失败,根源几乎总在「凭证没到」或「路径不可达」。与其反复调 SSH,不如先确认目标仓库 URL 是否能在 shell 里用相同凭证 git clone 成功——Composer 只是复用了这套底层能力。










