答案是Composer install报“Permission denied (publickey)”的根本原因是SSH未按预期路由到正确密钥,而非密钥本身失效;需确保composer.json中URL使用~/.ssh/config定义的Host别名(如git@github-personal:user/repo.git),且对应Host配置含HostName、User、IdentityFile和IdentitiesOnly yes,并通过ssh -T验证连通性。

Composer install报错“Permission denied (publickey)”不是密钥坏了,是没走对路
根本问题不在密钥本身是否有效,而在于 Composer 调用 git clone 时,SSH 客户端根本没用到你期望的那个私钥——它连的是 github.com,但你的 ~/.ssh/config 里只给 github-personal 或 gitlab-internal 配了 IdentityFile,没覆盖默认域名。
- 运行
ssh -T git@github.com:如果失败,说明默认 Host 没配密钥;成功但composer install仍失败,说明composer.json里写的仍是git@github.com:user/repo.git,没改用你定义的别名 -
~/.ssh/config中必须为每个目标显式声明Host条目,例如:Host github-personal HostName github.com User git IdentityFile ~/.ssh/id_rsa_personal IdentitiesOnly yes
- 对应地,
composer.json的repositories里 URL 必须写成git@github-personal:user/repo.git,不能留github.com - 别依赖
ssh-add加了多个密钥就万事大吉——SSH 不会自动挑,全靠Host别名路由
重关联密钥时最容易漏掉的三件事
重新生成或迁移密钥后,光把公钥贴到 GitHub/GitLab 页面远远不够。以下任一缺失都会导致 composer install 卡在 SSH 认证环节。
-
chmod 600 ~/.ssh/id_rsa_*:私钥权限大于 600(比如 644)会被 SSH 忽略,直接跳过加载 - 没执行
ssh-add -K ~/.ssh/id_rsa_personal(macOS)或ssh-add ~/.ssh/id_rsa_personal(Linux):密钥没进ssh-agent,git clone就拿不到它 -
~/.ssh/config里漏了IdentitiesOnly yes:这个开关不加,SSH 可能尝试用其他已加载的密钥“碰运气”,结果先用错密钥连一次就失败退出
为什么 ssh -T git@xxx 成功,但 composer install 还是挂?
因为 Composer 不直接跑 ssh 命令,它调的是 git clone,而 Git 是否读取 ~/.ssh/config 取决于 URL 格式和 Git 自身配置。常见误判点:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- URL 写成
https://github.com/user/repo.git:Git 完全绕过 SSH 配置,也不走~/.ssh/config,更不会提示你缺密钥——它可能降级走 HTTPS,然后卡在 401 或凭据弹窗 - 全局 Git 配置干扰:
git config --global core.sshCommand如果被设成硬编码路径(如"ssh -i ~/.ssh/old_key"),会覆盖~/.ssh/config的路由逻辑 - Composer 缓存残留:上次失败的 clone 状态可能被缓存,导致后续即使改对了 URL 也继续走旧路径。清掉
~/.composer/cache/vcs/和项目内vendor/composer/installed.json
CI/CD 环境下密钥加载失败的典型表现
本地 OK、CI 上失败,大概率是 ssh-agent 没启动或密钥没加载——CI 默认不启动交互式 shell,ssh-agent 不会自动运行。
- GitHub Actions 中必须显式启动:
run: | eval "$(ssh-agent -s)" ssh-add - <<< "${{ secrets.PERSONAL_SSH_KEY }}" - GitLab CI 要确认
before_script里有ssh-agent -s和ssh-add,且secrets注入的密钥内容不含多余换行或空格(Base64 编码后解码再验证) - Docker 构建中若用
FROM php:8.3,镜像默认没装openssh-client,得加RUN apt-get update && apt-get install -y openssh-client
实际生效的关键永远不是“密钥有没有”,而是“SSH 客户端知不知道该用哪个密钥连哪个地址”。配错一行 HostName 或漏一个 IdentitiesOnly yes,整个链路就断在第一步。

















