satis元数据体积大源于全量导出无用分支和provider文件,而非包本身;应关闭skip-dev、require-dependencies和providers配置项,并显式指定版本范围、启用gzip压缩与cdn缓存。

自建Packagist元数据体积为什么大
不是包本身大,是元数据文件(packages.json、provider-*.json)越积越多——每个包版本都生成独立 provider 文件,Satis 默认全量导出所有分支、标签、dev 版本,甚至包括已被废弃的 dev-master 或 dev-feature/*。一个含 50 个私有包的仓库,元数据目录轻松突破 200MB,跨境同步时卡在 HTTP chunk 或 TLS 握手阶段很常见。
Satis 配置里必须关掉的三个开关
默认配置会把所有 Git 引用都塞进元数据,但生产环境根本不需要 dev 分支和历史 tag。实测删掉这三项,元数据体积直降 60%~80%:
-
"archive": {"skip-dev": true}—— 禁止为 dev 分支生成 provider -
"require-dependencies": false—— 不递归拉取依赖包的元数据(除非你真要托管整个依赖树) -
"output-dir": "web"下加"providers": ["stable"]—— 只导出带稳定语义版本(如^1.2.0)的 provider,跳过dev-、alpha、beta
注意:"require-dependencies": true 是陷阱项,它会让 Satis 尝试解析并拉取每个包的 composer.json 中所有 require 包,哪怕那些包根本不在你的 satis.json repositories 列表里——结果就是元数据里混入大量外部 Packagist 包引用,体积暴增且无法访问。
provider 文件按需生成,别全量 dump
运行 satis build 时,默认行为是扫描全部 Git 仓库并生成所有匹配版本的 provider。但多数项目只用 ~1.0.0 或 ^2.3 这类约束,根本不会装 dev-develop 或 v0.9.1。
安全做法是显式指定版本范围:
- 用
--skip-errors避免单个仓库失败中断整批构建 - 加
--no-interaction防止交互式 prompt 卡住 CI 流水线 - 关键:通过
"version": "1.0.*"或"version": "^2.3"在satis.json的每个 package 块中硬编码允许版本,Satis 就只生成对应 provider,不碰其他分支
例如:"name": "myorg/utils", "version": "^3.2", "source": { ... } → 最终只产出 provider-myorg~utils~3.2.json,而不是几十个 provider-myorg~utils~dev-*.json。
元数据压缩与 CDN 缓存头必须配齐
光删 provider 不够,packages.json 本身是纯文本,gzip 后仍有 5–10MB。不压缩直接走跨境链路,首字节延迟高、TCP 重传多。
Nginx 配置里必须加这两行:
gzip on; gzip_types application/json;
同时确保响应头带 Cache-Control: public, max-age=3600(1小时足够),避免 Composer 每次都发 HEAD 请求校验。Satis 生成的静态文件无动态逻辑,完全可缓存。
容易被忽略的一点:packages.json 里包含的 notify-batch 字段如果指向内网地址(比如 http://satis.internal/notify),跨境节点无法解析该域名,会导致整个元数据加载失败——要么删掉该字段,要么统一替换为公网可访问的 endpoint。











