composer install 报 Permission denied (publickey) 主因是 ssh 密钥未配置或 git 协议被全局重写为 https;需验证 ssh -T git@github.com、检查 git config –get-all url.”https://”.insteadOf、或改用 GitHub Token + HTTPS,并确保 minimum-stability 适配 dev 分支。

Composer install 时提示 Cloning into 'xxx'... Permission denied (publickey)
这是最常见现象:Composer 尝试用 SSH 协议拉取私有仓库,但本地 SSH 密钥未配置或未被 GitHub 认可。Composer 默认对 git@github.com:user/repo 这类 URL 使用 SSH,而非 HTTPS。
验证方式:运行 ssh -T git@github.com。若返回 Hi username! You've successfully authenticated...,说明 SSH 已通;否则需补全密钥配置。
- 确保已生成 SSH 密钥(如未生成:
ssh-keygen -t ed25519 -C "your_email@example.com") - 将公钥(
~/.ssh/id_ed25519.pub)完整复制,粘贴进 GitHub → Settings → SSH and GPG keys - 确认
~/.ssh/config中有对应 Host 配置(尤其多账号场景):Host github.com IdentityFile ~/.ssh/id_ed25519
composer.json 中写死 git@github.com:user/repo.git 仍失败?检查 Git 全局协议重写
即使 Composer 的 repositories 指定了 SSH 地址,Git 自身可能因全局配置强制转为 HTTPS,绕过你的 SSH 设置。
执行 git config --global url."https://".insteadOf git:// 是常见操作,但它也会把 git@github.com: 转成 HTTPS —— 导致权限失效。
- 检查是否误启用了协议替换:
git config --get-all url."https://".insteadOf - 若输出含
git@github.com或ssh://git@github.com,运行:git config --global --unset-all url."https://".insteadOf - 也可精准禁用 SSH 转换:
git config --global --add url."git@github.com:".insteadOf "https://github.com/"(反向兜底)
不想配 SSH?改用 GitHub Personal access Token + HTTPS
SSH 不是唯一解。GitHub 已弃用密码认证,但支持用 Token 替代密码走 HTTPS。这对 CI/CD 或容器环境更可控。
步骤精简:composer config -g github-oauth.github.com your_personal_access_token,然后在 composer.json 中使用 HTTPS 地址:"https://github.com/user/private-repo.git"。
- Token 需勾选
repo权限(私有库必需),read:packages非必需 - Token 存储在
~/.composer/auth.json,注意文件权限:chmod 600 ~/.composer/auth.json - HTTPS 方式下,Composer 会自动注入 Authorization Header,无需修改仓库 URL 格式
私有包作为依赖时,require 版本写 "dev-main" 却拉不到最新提交?
Composer 默认只加载带 Git tag 的版本(如 v1.0.0),dev-main 属于“开发分支”,需显式启用 minimum-stability 和 prefer-stable 控制逻辑。
关键点不在 SSH 或 Token,而在稳定性策略:
- 项目根目录
composer.json必须包含:"minimum-stability": "dev", "prefer-stable": false - 若仅想对某私有包放宽限制,可用
repositories的type: vcs显式声明:"repositories": [ { "type": "vcs", "url": "git@github.com:user/private-repo.git" } ] - 执行
composer update vendor/package-name而非全量 update,避免意外升级其他包
SSH 配置只是入口,真正卡住的常是 Git 协议重写、Token 权限粒度、或 Composer 的稳定性解析规则 —— 这三处不匹配,换再多次密钥也没用。