私有仓库SSH URL必须为git@host:user/repo.git格式(冒号分隔),不能用ssh://协议;Composer依赖本地git执行克隆,需确保SSH密钥已加载、known_hosts已预置且repositories中type设为vcs、url完整。

私有仓库的 SSH URL 格式必须正确
Composer 不会自动把 git@github.com:user/repo.git 这类 SSH URL 转成可访问的 Git 协议地址,它依赖底层 git 命令执行克隆,因此 URL 必须是标准的 SSH 形式,且能被本地 git 直接识别。
常见错误是写成 ssh://git@host:port/user/repo.git —— 这在某些 Git 配置下会失败;更稳妥的是用 git@host:user/repo.git(冒号分隔,无端口时默认 22)。
- GitHub 私仓:用
git@github.com:org/private-package.git - GitLab 自托管:确认
core.sshCommand已设为支持自定义端口,例如ssh -p 2222,否则默认 22 可能不通 - 若仓库路径含特殊字符或空格,务必 URL 编码——但更建议直接避免这类路径
composer.json 中 type 和 source 需显式声明
Composer 默认只信任 Packagist 上的包,要拉取私有仓库,必须在 composer.json 的 repositories 段手动注册,并指定 type 为 vcs,同时提供完整 url。
不写 type 或错写成 package 会导致 Composer 完全忽略该仓库;漏掉 url 则报 "URL required" 错误。
{
"repositories": [
{
"type": "vcs",
"url": "git@github.com:myorg/internal-sdk.git"
}
],
"require": {
"myorg/internal-sdk": "^1.2"
}
}
SSH 密钥未加载或权限不足是最高频失败原因
运行 composer install 时如果卡住或报 Permission denied (publickey),基本不是 Composer 问题,而是当前用户环境下的 SSH 认证没过。
- 先手动测试:
git ls-remote git@github.com:myorg/internal-sdk.git HEAD—— 这步不通,Composer 一定失败 - 确保密钥已添加到
ssh-agent:ssh-add -l查看,ssh-add ~/.ssh/id_rsa加载 - 检查
~/.ssh/config是否覆盖了 Host 别名但漏配IdentityFile,比如写了Host github.com却没跟IdentityFile ~/.ssh/github_key - CI 环境中注意:Docker 容器、GitHub Actions runner 默认不继承宿主机 SSH agent,需显式挂载或启动 agent
Git 配置影响 clone 行为,尤其 submodule 和 shallow clone
Composer 内部调用 git clone 时,会受全局或系统级 git config 干扰,典型如 clone.defaultRemote 或 submodule.recurse 设置不当,导致私仓子模块拉取失败或超时。
最稳妥做法是在项目根目录下运行:git config --local core.sshCommand "ssh -o StrictHostKeyChecking=no"(仅限可信内网),或更安全地预置 known_hosts:
ssh-keyscan -t rsa github.com >> ~/.ssh/known_hosts
另外,Composer 7+ 默认启用 shallow clone,对带大量历史 tag 的私仓可能引发版本解析异常;可临时禁用:COMPOSER_DISCARD_CHANGES=1 composer install,或在 config 段加 "preferred-install": {"*": "source"} 强制源码安装。
私有仓库的 tag 推送后,Composer 缓存可能滞留旧信息,composer clear-cache 后再 composer update vendor/package 才能生效——这点容易被忽略,尤其是多人协作时 tag 覆盖更新后。


















