最小可用satis.json必须含name和homepage两个顶层必填字段,homepage为无尾斜杠的完整URL(如"http://192.168.1.100"),repositories为含VCS对象的顶层数组,且需配"require-all":true;缺一将导致composer install回退公网。

直接配 satis.json + php bin/satis build + Web 托管 + 客户端显式声明,四步缺一不可;漏掉任何一步,composer install 都会 fallback 到 packagist.org 并卡住。
如何写一个最小但能用的 satis.json
它不是模板填充题,字段位置、类型、值约束都必须严格对齐 Composer 解析逻辑:
-
name和homepage是顶层必填字段,homepage必须是完整 URL(如"http://192.168.1.100"),结尾不能带/,否则 dist 下载地址会多拼一层 -
repositories必须是顶层数组,每个元素是对象,不能是字符串 URL;例如{"type": "vcs", "url": "https://git.internal/auth-sdk.git"}合法,"https://git.internal/auth-sdk.git"会静默跳过 - 只用
"require-all": true或只用"require": {"vendor/package": "*"},二者共存会导致构建时跳过所有包,且不报错 -
output-dir强烈建议写绝对路径(如"/var/www/satis"),相对路径在 CI 或不同工作目录下极易生成 ZIP 到错误位置,导致distURL 404
为什么 packages.json 能访问,但 composer install 还是走外网?
根本原因:客户端没关默认源。Satis 不拦截、不代理、不重定向,它只提供一个可选源——你必须主动告诉 Composer “别查 packagist.org”:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 项目
composer.json中必须有"packagist.org": false,放在顶层,和repositories同级 -
repositories里声明私有源时,url值末尾必须带/(如"https://packages.internal/"),否则 Composer 拼出的请求是https://packages.internal/packages.json/packages.json - 执行
composer clear-cache,否则旧缓存可能仍指向公网源 - 验证是否生效:运行
composer config --list | grep repositories,确认输出中只含你的私有源,且packagist.org明确为false
Web 服务返回 packages.json 但解析失败?
常见于 Nginx/Apache 没配 MIME 类型,Composer 收到 text/plain 就直接拒收:
- 浏览器或
curl -I https://packages.internal/packages.json必须返回HTTP/2 200且Content-Type: application/json - Nginx 需加配置:
types { application/json json; },放在http或server块内 - Apache 用户需确保
mod_mime已启用,并添加AddType application/json .json - dist ZIP 文件路径由 Satis 自动生成(如
dist/vendor-package/1.2.0-zip-hash.zip),Web 服务器必须允许该路径被公开 GET,不能设deny all或 require 认证
最易被忽略的是 homepage 和 url 的斜杠规则:前者结尾不能有 /,后者必须有;差这一个字符,dist 下载地址就全错,但错误日志里只显示 “Could not download” —— 不提示具体 URL,得自己 curl -v 抓包看。

















