因为composer config -g repo.packagist仅替换元数据源(packages.json),不修改已锁定的dist.url,ZIP包仍从原始GitHub等地址下载;且中文镜像不托管ZIP,需手动清理lock文件、删vendor并重装,才能使新dist路径生效。

为什么直接改 composer config -g repo.packagist 不行
因为这条命令只替换元数据入口(packages.json),但 ZIP 包仍从原始 dist.url 下载——比如 https://github.com/monolog/monolog/releases/download/2.10.0/monolog-2.10.0.zip。局域网打不开 GitHub,国内公开镜像(阿里云、USTC)也不托管 ZIP 文件,只缓存 packages.json 和 provider-*.json。
验证真实 ZIP 地址:运行 composer show monolog/monolog --verbose,看 dist.url 字段;别信“换源就完事”,必须让所有依赖的 ZIP 都能通过局域网 HTTP 直接 GET 到。
-
composer config -g repo.packagist仅影响当前用户,CI 环境(如 GitHub Actions runner 用户)、宝塔(www 用户)、Docker 容器默认读不到 - 全局配置无法覆盖依赖包自身声明的源(比如某私有包内部写了
"repositories": [{"type":"composer","url":"https://repo.packagist.org"}]) - 内网常禁 HTTPS 重定向、拦截
file_get_contents、丢弃 443 外部请求,这些不是配置错误,而是信任链断裂
Satis 构建后 composer install 仍 404 的真实原因
Satis 不是服务,只是静态文件生成器:它不监听端口、不启动进程,只把 packages.json 和 ZIP 写进输出目录。404 不是网络不通,是 Web 服务没暴露对路。
- Nginx
root必须精确指向satis.json中output-dir的路径,例如root /var/www/satis/web; - 必须显式声明 JSON MIME 类型:
types { application/json json; },否则返回text/plain,Composer 拒收 - 镜像 URL 必须以
/结尾:"url": "https://pkgs.internal/",少一个斜杠会拼成https://pkgs.internalpackages.json - 检查
dist/下 ZIP 路径是否可直连 GET,例如https://pkgs.internal/dist/monolog/monolog/2.10.0/xxx.zip,SELinux 或文件权限常锁死该路径
项目级 composer.json 怎么写才真正生效
私有源必须写在你要装包的那个项目的根级 composer.json 里,不是 Satis 自己的配置文件,也不是包自己的 composer.json。
- 类型必须是
"type": "composer",URL 是托管packages.json的根地址(含末尾/) - 务必加上
"packagist.org": false,且放在repositories数组里,不是嵌套在某个仓库对象内部 - 私有源必须放在
repositories数组第一位,Composer 按顺序查找,不会合并同名包 - 如果原
composer.json中"repositories"是数组([]),composer config repo.packagist ...命令会报错或覆盖整个数组;需先手动改成对象({})再执行
require-all: true 是个坑,慎用
它会让 Satis 把 Packagist 所有公开包全量同步,首构建可能超 40GB,加载时内存溢出或超时;更糟的是,它会把 dev- 分支也当版本暴露,导致 composer update 拉取到不稳定分支。
实际部署中,应严格按需同步:在 satis.json 中用 packages 字段白名单指定组织或包名,例如:
"packages": {
"acme/*": {},
"monolog/monolog": {"version": "2.10.0"}
}
复杂点在于:Satis 不自动处理 ZIP 重命名和路径映射,dist/ 目录结构必须与 packages.json 中声明的 dist.url 完全一致;少一个目录层级或大小写不匹配,就会 404 —— 这类问题往往要靠 curl 直连验证,而不是等 composer install 报错才去查。











