composer config -g repo.packagist 对私有镜像无效,因其仅替换元数据入口(packages.json),不修改包的 dist.url 字段,而 zip 文件仍从原始源(如 github)下载,局域网无法访问;私有镜像需确保所有 dist.url 指向内部 http 服务且 web 服务器正确暴露静态文件。

composer config -g repo.packagist 为什么对私有镜像无效
这条命令只改元数据入口,不触碰 ZIP 包下载路径——satis 生成的 dist/ 下 ZIP 文件必须能被 HTTP 直接 GET 到,而 composer config -g repo.packagist 完全不控制 dist.url 字段。它只替换 packages.json 的获取地址,所有包的 dist.url 仍来自原始源(比如 GitHub),局域网根本打不开。
验证方式很简单:composer show monolog/monolog --verbose,看输出里的 dist.url 字段是不是还指向 https://github.com/...。如果是,说明镜像没真正接管下载链路。
- 私有镜像不是“换源”就能用,而是要让每个包的
dist.url指向你自己的 HTTP 服务(如https://pkgs.internal/dist/monolog/monolog/2.10.0/xxx.zip) -
composer config -g repo.packagist只影响packages.json元数据拉取,和 ZIP 下载无关 - CI 或多用户环境(如宝塔 www 用户)默认读不到你的全局配置,更没法覆盖
dist.url
satis build 后 composer install 报 404 的真实原因
satis 不是 Web 服务,只是静态文件生成器。它不会监听端口、不启动进程,只把 packages.json 和 ZIP 写进 output-dir。404 不是网络不通,是 Web 服务器没正确暴露这些文件。
关键配置点必须全部对齐:
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
- Nginx 的
root必须精确指向satis.json中output-dir的子目录web,例如:root /var/www/satis/web; - 必须显式声明 JSON MIME 类型:
types { application/json json; },否则返回text/plain,Composer 拒收 - 镜像 URL 必须以
/结尾:"url": "https://pkgs.internal/",少一个斜杠会拼成https://pkgs.internalpackages.json - 检查 SELinux 状态或文件权限:
ls -l /var/www/satis/web/dist/是否可被 Web 用户读取
项目级 composer.json 怎么写才真正走私有镜像
私有源必须写在你要装包的那个项目的根级 composer.json 里,不是 satis 自己的配置文件,也不是包自己的 composer.json。漏掉任意一项,composer require acme/utils 就会报 Could not find package。
- 类型必须是
"type": "composer",URL 是托管packages.json的根地址(含末尾/) - 务必加上
"packagist.org": false,且放在repositories数组顶层,不是嵌套在某个仓库对象内部 - 私有源必须放在
repositories数组第一位,Composer 按顺序查找,不会合并同名包 - 别用
"require-all": true——首构建可能超 40GB,内存溢出或超时;还会把dev-分支当正式版本暴露
dist.url 路径不可达时最该查什么
即使 packages.json 能正常加载,dist.url 404 仍是高频故障点。这不是 Composer 配置问题,而是服务层暴露缺陷。
直接浏览器访问那个 ZIP 地址(比如 https://pkgs.internal/dist/monolog/monolog/2.10.0/monolog-2.10.0.zip),看是否返回文件。如果 404,重点排查:
- Web 服务 root 路径是否真指向
satis输出的web/目录,而非上层satis/ - Nginx/Apache 是否开了
autoindex off?ZIP 文件需显式存在,不能靠目录索引生成 - SELinux 是否拦截:
getenforce查状态,临时关掉测试:setenforce 0 - 文件权限是否允许 Web 用户读取:
chown -R www-data:www-data /var/www/satis/web/dist
真正麻烦的不是配置本身,而是 dist.url 路径映射和 Web 服务暴露之间那几行 Nginx 配置的精度——差一个字符、少一个斜杠、缺一个 MIME 声明,就卡在 ZIP 下载环节,日志还不报错。










