Composer 能拉取私有 Git 仓库的前提是 SSH 配置正确:运行用户、~/.ssh/ 路径、密钥权限三者必须一致;密钥需为 600 权限且 IdentityFile 写绝对路径;composer.json 中必须用 git@ 开头的 SSH URL 并声明 "type": "vcs"。

Composer 能拉取私有 Git 仓库,但前提是它能以你的身份通过 SSH 访问该仓库。不是配对 SSH 密钥就完事,关键在于 composer install 运行时的用户、SSH 配置路径、密钥权限,三者必须对齐。
确认当前运行 Composer 的用户是谁
很多人在 CI 环境或 root 下执行 composer install,却把密钥配在了普通用户家目录,结果一直提示 Permission denied (publickey)。先搞清谁在执行:
whoami
如果是 CI(如 GitHub Actions、GitLab CI),默认是 root 或专用服务用户(如 www-data);本地开发则通常是当前登录用户。密钥必须放在该用户的 ~/.ssh/ 下,且 ~ 必须可展开为真实路径(不能是符号链接或空值)。
确保 SSH 密钥可用且权限正确
以下三点缺一不可:
-
~/.ssh/id_rsa(或自定义密钥名)存在,且私钥文件权限为600(chmod 600 ~/.ssh/id_rsa) -
~/.ssh/config中已声明主机别名与密钥路径,例如:
Host gitlab.example.com IdentityFile ~/.ssh/id_rsa_gitlab User git
注意:IdentityFile 必须写绝对路径;若用相对路径(如 ./id_rsa),SSH 会从当前工作目录找,而 Composer 执行时工作目录可能是项目根,不一定是 ~/.ssh/。
- 用该用户执行
ssh -T git@gitlab.example.com能成功返回欢迎信息(不是密码提示,也不是 Permission denied)
在 composer.json 中正确声明私有仓库
不要依赖 GitHub/GitLab 的 HTTPS URL(那走的是 token 或密码认证),必须用 SSH URL,并确保协议头是 git@ 开头:
{
"repositories": [
{
"type": "vcs",
"url": "git@gitlab.example.com:mygroup/my-private-package.git"
}
],
"require": {
"mygroup/my-private-package": "^1.0"
}
}
常见错误:
- 写成
https://gitlab.example.com/mygroup/my-private-package.git—— 即使配了 SSH 密钥也无效 - 写成
ssh://git@gitlab.example.com/mygroup/my-private-package.git—— Composer 不识别这种格式,会 fallback 到 HTTPS - 没加
"type": "vcs"—— Composer 默认只认 Packagist,私有仓库必须显式声明类型
CI 环境下避免硬编码密钥,改用 SSH agent forwarding 或 deploy key
在 GitHub Actions、GitLab CI 中,直接把私钥写进 ~/.ssh/id_rsa 是高危操作。更安全的做法是:
- GitHub Actions:用
webfactory/ssh-agentaction 注入密钥,再确保ssh-agent已启动并添加了 key - GitLab CI:用
before_script启动ssh-agent,用ssh-add 加载变量中的密钥 - 所有场景:优先使用「Deploy Key」而非个人 SSH 密钥,限制权限到单个仓库
如果 composer install 报错 Failed to clone git@gitlab.example.com:mygroup/my-private-package.git,先别急着改 composer.json,用 ssh -vT git@gitlab.example.com 看详细握手日志——90% 的问题出在 SSH 层,跟 Composer 本身无关。










