Composer 依赖 Git 的 SSH 配置访问私有仓库,需确保 SSH 密钥正确配置、Git 未被 insteadOf 规则干扰、仓库 URL 使用 git@ 格式且权限合规。

Composer 默认用 HTTPS 克隆私有仓库,但 GitLab/Bitbucket 的私有项目若启用了 2FA 或禁用了密码认证(如 Bitbucket 已全面停用账户密码),就必须改用 SSH。关键不是“配 Composer”,而是让 git 命令本身能走 SSH 访问你的私有仓库,Composer 只是调用它。
确认 SSH 密钥已生成并添加到 Git 托管平台
Composer 不处理密钥管理,它完全依赖系统级的 git 行为。先确保:
- 本地已有可用的 SSH 密钥(如
~/.ssh/id_rsa或~/.ssh/id_ed25519),且未设置密码(或已用ssh-agent加载) - 公钥(
id_rsa.pub或id_ed25519.pub)已完整复制并粘贴到 GitLab 的 Settings → SSH Keys 或 Bitbucket 的 Personal settings → SSH keys - 在终端执行
ssh -T git@gitlab.com(或git@bitbucket.org)返回欢迎信息,而非权限拒绝
强制 Composer 使用 SSH URL 而非 HTTPS
即使你 composer.json 里写的是 HTTPS 地址(如 "vendor/package": "dev-main"),Composer 仍可能尝试用 HTTPS 克隆——除非你明确告诉它该包的源必须走 SSH。做法是配置 repositories 并指定 url 为 SSH 格式:
{
"repositories": [
{
"type": "vcs",
"url": "git@gitlab.com:your-group/your-private-package.git"
}
],
"require": {
"your-group/your-private-package": "dev-main"
}
}
注意:url 必须是完整 SSH URL(git@host:path.git),不能是 https://,也不能漏掉 .git 后缀;包名(your-group/your-private-package)必须与仓库的 name 字段或自动推断名一致,否则 Composer 找不到匹配源。
避免因 Git 配置导致 SSH 失效
常见坑:全局 Git 配置中设置了 insteadOf 规则,把所有 git@ 强制转成 HTTPS:
[url "https://"]
insteadOf = git@
这会让 git clone git@gitlab.com:xxx 实际走 HTTPS,直接失败。检查并删除这类规则:
- 运行
git config --global --get-regexp insteadOf查看是否有干扰项 - 若有,用
git config --global --unset url."https://".insteadOf清除 - 仅对特定域名做重写才安全,例如只让 GitHub 的 SSH 自动转 HTTPS(极少需要)
私有子模块或嵌套依赖也走 SSH?
如果私有包自身含有 .gitmodules 或依赖其他私有仓库,那些子依赖不会自动继承父项目的 SSH 配置。你必须确保:
- 子模块的 URL 在其
.gitmodules文件里也是git@开头(而非https://) - 或在项目根目录运行
git submodule sync --recursive同步后,手动修正子模块的远程地址:git -C vendor/your-package submodule set-url --all git@gitlab.com:subgroup/subpackage.git - Composer 不解析或改写子模块 URL,这是纯 Git 层行为
最易忽略的一点:SSH 密钥权限必须是 600(chmod 600 ~/.ssh/id_*),且 ~/.ssh 目录不能被组或他人写入(chmod 700 ~/.ssh),OpenSSH 在严格模式下会直接拒用密钥,错误常表现为 Permission denied (publickey) 却不提示具体原因。










