composer 本身不是服务端,不提供镜像站功能;所谓私有镜像实为可被其识别的 http 服务,需具备元数据生成、包托管与 repositories 配置能力。

Composer 本身不提供镜像站功能,也不参与镜像同步或存储管理——这是常见误解的根源。你真正需要的是 composer install 或 composer update 背后依赖的镜像源(如 Packagist)的替代方案,比如私有 Packagist 服务(如 Private Packagist、Satis、Toran Proxy),或更现代的替代品(如 packagist.com 自托管版、Artifactory 的 PHP Repository)。所谓“Composer 构建私有镜像站”,实际是指搭建一个能被 composer 命令识别并拉取包的 HTTP 服务,其核心是元数据生成 + 包文件托管 + repositories 配置。
为什么不能直接用 Composer 当镜像服务
composer 是一个客户端工具,不是服务端。它没有内置 HTTP 服务器、认证系统、包索引机制或存储后端。运行 composer create-project 或 composer require 时,它只是读取 composer.json 中的 repositories 列表,向指定 URL 发起 GET 请求获取 packages.json 和 .zip 包文件。因此,“同步”和“容量规划”必须落在服务端组件上,而非 composer 本身。
同步策略:Satis vs Private Packagist vs Artifactory
三者定位不同,影响同步方式和运维成本:
-
Satis:静态生成器,适合小团队。每次运行satis build会扫描 Git 仓库或 Packagist,下载所有匹配包的 ZIP 并生成静态packages.json。不支持实时同步,需定时crontab触发;无法按需拉取,所有包全量下载,容易撑爆磁盘。 -
Private Packagist:商业 SaaS 或自托管版。支持 webhook 触发同步(如 GitHub push 后自动更新)、按需缓存(只拉取项目实际require的包)、版本过滤(如仅同步^2.0范围)、私有包上传与权限控制。同步粒度细,存储可控。 -
Artifactory:通用二进制仓库,PHP Repository 是其插件能力之一。同步基于远程仓库代理(proxy repo),支持缓存策略(如 TTL 过期后才回源)、带宽限速、拒绝特定包名模式。适合已有 Artifactory 基础设施的团队,但 PHP 生态支持不如专用方案成熟。
存储容量怎么算:别只看 ZIP 文件大小
真实占用远超包压缩包本身,需叠加以下几层:
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
-
packages.json元数据:每个包平均约 1–5 KB,万级包约 10–50 MB,可忽略。 - ZIP 包解压后体积:
composer install --no-dev下载的 ZIP 通常比源码小 30–50%,但解压后可能膨胀 2–4 倍(尤其含测试、文档、前端资源的包)。 - 多版本冗余:Satis 默认保留所有 tagged 版本;Private Packagist 可配置保留最近 N 个版本或按语义化版本规则清理(如只留
1.x,2.x最新 patch)。 - 缓存副本:Artifactory 或 Toran Proxy 会在本地缓存每次
composer install实际拉取的 ZIP,同一包不同版本可能重复缓存,且无自动 GC。
经验公式:预期包数量 × 平均解压后大小 × 2.5(冗余系数)。例如 2000 个包,平均解压后 5 MB → 约 25 GB。若启用 dev 包或历史版本全量保留,翻倍起步。
容易被忽略的坑:HTTP 缓存头与 CDN 兼容性
私有镜像站返回的 packages.json 和 ZIP 必须带正确 Cache-Control 头,否则 composer 会频繁 304 请求或跳过缓存:
-
packages.json应设Cache-Control: public, max-age=3600(1 小时),避免每次update都重请求元数据。 - ZIP 文件应设
Cache-Control: public, immutable, max-age=31536000(1 年),因包哈希不变,内容不可变。 - 若套 CDN(如 Cloudflare、阿里云 CDN),需确保 CDN 不缓存 404 响应,否则包不存在时会返回陈旧错误页;同时关闭对
/packages.json的强制缓存,允许动态更新。
没配好这些,你会看到 composer update 变慢、偶尔拉不到新版本、CI 构建随机失败——问题不在 Composer,而在镜像站的 HTTP 层。










