私有源无效是因为 composer config -g repo.packagist 仅修改元数据入口,不代理私有包的 ZIP/Git 下载;私有源须单独声明在 repositories 数组首位,类型明确,URL 以/结尾,且需确保 dist 文件可直连、权限和 MIME 类型正确。

composer config -g repo.packagist 为什么对私有源无效
因为这个命令只改元数据入口(packages.json),但私有包(比如 internal/auth-sdk)的 ZIP 包、Git 地址、dist URL 全部绕过镜像直连——阿里云、腾讯云等公开镜像根本不托管私有包,也不做代理转发。你配了 repo.packagist,Composer 看到私有包声明后,直接跳过镜像,去请求你 composer.json 里写的 https://repo.internal/ 或 git@corp.com:auth-sdk.git,根本不会查镜像。
私有源必须单独声明,且不能和 packagist 混写
私有源要独立定义在 repositories 数组里,类型明确为 "type": "composer" 或 "type": "vcs",URL 指向你自己的服务地址(如 Satis 或 Private Packagist)。关键点:
-
"packagist.org": false是错的写法——它只禁用默认源,但不阻止 Composer 尝试其他composer类型源;正确开关是顶层"packagist": false - 私有源必须放在
repositories数组第一位,Composer 按顺序查找,同名包不会合并,后写的会被忽略 - 如果用了 Satis,确保其
satis.json中require-all: true没开——它会拉全量 Packagist 包,首构建可能超 40GB,还暴露 dev 分支导致依赖解析混乱 - URL 必须以
/结尾:"url": "https://pkgs.internal/"✅,少斜杠会拼成https://pkgs.internalpackages.json→ 404
局域网镜像必须让 dist.zip 可直连,不是只换 packages.json
公开镜像只缓存 packages.json 和 provider-*.json,不托管 ZIP 文件。企业私有镜像必须让所有 dist.url 能被局域网 HTTP 直接 GET 到,否则 composer install 会卡在下载环节。验证方式:
- 运行
composer show monolog/monolog --verbose,看输出里的dist.url字段是否指向你内网地址(如https://pkgs.internal/dist/monolog/monolog/2.10.0/xxx.zip) - Nginx 的
root必须精确指向 Satis 的output-dir,例如root /var/www/satis/web; - 必须显式配置 MIME 类型:
types { application/json json; },否则返回text/plain,Composer 拒收 - SELinux 或文件权限常锁死
dist/目录,检查ls -Z和httpd_can_network_connect是否开启
认证和安全不能靠镜像 URL 解决
镜像本身不处理认证。私有源提速靠的是提前注入凭据、减少握手次数:
- 用
composer config http-basic.repo.internal username password把凭证存进auth.json,而非硬编码在composer.json里 -
auth.json必须加进.gitignore,否则密码泄露 - 私有源 URL 必须带域名(如
https://repo.internal),不能用 IP;否则http-basic映射失效 - Git 类私有包优先用
"type": "vcs",走 SSH key 或 HTTPS token,比composer类型更轻量、更可控
最常被忽略的是:Satis 生成的静态文件没被 Web 服务正确暴露,或者 composer.lock 里仍存着旧的外部 dist.url,删 vendor 和 lock 后重装才能真正切过去。


















