需配置auth.json认证、声明ghcr.io仓库、严格匹配包名与版本。auth.json须含ghcr.io的PAT令牌,composer.json需声明type为composer的ghcr.io仓库URL,安装时用完整命名空间名及对应tag版本。

配置 GitHub Packages 认证凭据
Composer 无法直接读取 GitHub 的 Personal Access Token(PAT)环境变量,必须显式写入 auth.json。不配置或配错会导致 401 Unauthorized 或 403 Forbidden 错误,尤其在 CI/CD 中容易忽略本地与远程环境差异。
- 在项目根目录创建
auth.json(确保未被.gitignore排除,或仅存于 CI 环境中) - 内容必须包含
ghcr.io域名,且token是带read:packages权限的 PAT(推荐使用 fine-grained token,勾选packages:read) - 不要用
username+password,GitHub Packages 已弃用密码认证
{
"github.com": {
"oauth-token": "ghp_..."
},
"ghcr.io": {
"bearer": "ghp_..."
}
}
声明私有仓库为 Composer 存储库
GitHub Packages 不是默认注册表,Composer 需要明确知道去哪里找包。仅靠 auth.json 不够,必须在 composer.json 的 repositories 中声明类型为 composer 的源,并指向正确的 ghcr.io API 地址。
- 仓库 URL 格式固定为
https://ghcr.io/v2/+OWNER/REPO,末尾不加/ - 类型必须是
composer,不能是vcs或package,否则无法解析composer.json元数据 - 如果包发布在组织下(非个人),
OWNER是组织名,不是你的用户名
{
"repositories": [
{
"type": "composer",
"url": "https://ghcr.io/v2/your-org/your-private-package"
}
]
}
安装时指定完整包名与版本约束
GitHub Packages 中的包名必须严格匹配 composer.json 里定义的 name 字段,且该名称需含命名空间(如 your-org/your-private-package)。Composer 不会自动从 URL 推导包名。
- 运行
composer require时,必须写全名:your-org/your-private-package,不能只写your-private-package - 版本号需与 GitHub Packages 中发布的 tag 一致(如
v1.0.0),且 tag 必须对应一个有效的composer.json - 若使用
dev-main,确保仓库已启用allow-plugins并允许composer-plugin-api(某些安全策略会拦截)
执行命令示例:
composer require your-org/your-private-package:^1.0
常见失败原因与验证方式
最常卡在「能登录但拉不到包」——本质是认证、仓库声明、包名三者没对齐。调试时优先检查这三项是否完全一致。
-
composer config --global github-oauth.github.com和auth.json冲突?删掉全局配置,只留项目级auth.json - 运行
composer diagnose,确认输出中包含ghcr.io在 authenticated domains 列表里 - 手动用
curl -H "Authorization: Bearer ghp_..." https://ghcr.io/v2/your-org/your-private-package/versions测试 API 是否返回可用版本列表 - GitHub Packages 页面上包的
Installation区域显示的composer require命令,复制后要核对name是否与你本地composer.json一致
GitHub Packages 对 Composer 的支持依赖于正确的元数据暴露,不是所有私有仓库都默认开启 composer registry 模式;如果 composer install 报 Could not parse version constraint,大概率是目标仓库没发布含有效 composer.json 的 tag。










