packages.json能扛住高并发安装,因其是纯静态文件,由Nginx/Apache直接返回,无PHP解析、无数据库查询、无缓存穿透;Composer仅需一次GET请求获取全部元数据并本地解析,下载地址已内嵌,瓶颈仅在于Web服务器带宽和磁盘I/O。

静态 JSON 模式是 Satis 的唯一工作模式,它不提供 API 服务,只生成 packages.json 和 ZIP/TAR 归档——性能高、部署轻、无运行时开销,但所有“动态行为”都必须靠配置和客户端配合来模拟。
为什么 packages.json 能扛住高并发安装
Satis 输出的 packages.json 是纯静态文件,Nginx/Apache 直接返回,无 PHP 解析、无数据库查询、无缓存穿透风险。Composer 安装时只做一次 GET 请求,拿到全部包元数据后本地解析,后续下载地址(dist/source)也已内嵌其中。
- 对比 Packagist 或 Artifactory:它们需实时聚合、校验、签名、路由,QPS 上限受服务端 CPU/IO 限制;Satis 的瓶颈只在 Web 服务器带宽和磁盘 I/O
- 文件体积可控:用
"require-all": false+ 显式"require"白名单,避免把整个 GitHub 镜像下来 - CDN 友好:整个
web/目录可直接推送到 CDN,packages.json和dist/下所有 ZIP 都支持强缓存(ETag/Last-Modified)
composer.json 中仓库声明必须带结尾斜杠
Composer 构建请求 URL 的逻辑是:url + "packages.json"。如果写成 "https://satis.example.com",它会拼出 https://satis.example.compackages.json(少了个 /),导致 404;而写成 "https://satis.example.com/" 才能正确命中 https://satis.example.com/packages.json。
- 常见错误现象:
composer update不报错但始终 fallback 到 packagist.org,curl -I https://satis.example.com/packages.json返回 404 或 403 - 检查方法:直接浏览器访问该 URL,确认能返回 JSON 内容且 HTTP 状态码为 200
- 注意 Nginx 配置:若用
alias,末尾不能多加/;若用root,确保路径指向的是web/目录本身,不是其父目录
构建时内存溢出和空 packages.json 的真实原因
Satis 构建失败常被误判为环境问题,实际多是配置或网络策略冲突:
-
Allowed memory size exhausted:不是 PHP 版本低,而是"require-all": true+ 大量 VCS 仓库触发 Composer 元数据递归加载;解决方法是改用"require"明确包名,或调大memory_limit至 512M+ -
packages.json文件存在但为空或只有{}:大概率是"repositories"里写了无效 URL(如权限拒绝的私有 GitLab 地址)、或 GitHub API 被限流(没配GITHUB_TOKEN环境变量);Satis 默认静默跳过失败源,不报错 - 构建命令未加
-v参数时,根本看不到哪些包被跳过——建议首次构建必加php bin/satis build -v satis.json web/
离线环境部署最关键的三个动作
静态模式下,“离线可用”不是默认结果,而是精确控制链路每一步的结果:
- 构建机必须联网完成全量抓取:Satis 不支持断点续传,
"require-dependencies": true必须开启,否则依赖树中未显式声明的包不会进packages.json -
dist/目录必须和packages.json同级且可公开访问:ZIP 文件路径由"prefix-url"+"archive.directory"拼接,例如"prefix-url": "https://satis.example.com"+"directory": "dist"→ 下载地址为https://satis.example.com/dist/vendor-package-1.2.3.zip - 客户端项目必须禁用 packagist.org:
"packagist.org": false这行不能漏,也不能写成"packagist": false——键名必须完全匹配
最易忽略的点:Satis 不生成任何“包存在性校验机制”。一旦 packages.json 里写了某个包,但对应 ZIP 实际没生成(比如因网络中断或权限失败),composer install 就会在下载阶段卡住或报 404,而这个错误不会在构建时暴露。



















