企业级私有Composer仓库应选Satis(轻量自建、完全可控)或Private Packagist(合规高效、支持私有部署),二者可单独使用或混合部署,HTTPS为强制要求;Satis适合中小团队自主可控场景,Private Packagist更适合中大型组织对权限、审计与自动化的需求。

私有 Packagist 服务选型:Satis 还是 Private Packagist?
企业内部用 Composer 管理私有包,核心不是“能不能装”,而是“谁控制索引、谁审计依赖、谁保障可用”。Satis 是轻量静态生成方案,适合 CI/CD 流水线自动构建;Private Packagist(PP)是商业托管方案,自带 Web UI、权限分级、安全扫描和 webhook 集成。中小团队用 Satis 更可控,大中型企业建议直接上 PP——它原生兼容 composer.json 的 repositories 配置,且能复用 GitHub/GitLab OAuth 登录,省去自建鉴权的麻烦。
- Satis 生成的是纯静态
packages.json,必须走 HTTP 服务(如 Nginx)对外暴露,不支持按用户动态过滤包 - PP 支持细粒度权限:比如
dev-team组只能看到internal/logging,而infra组能看到全部 - 若已有 GitLab 私有仓库,PP 可直连其 API 拉取 tag/branch,无需在每个包里手动 push 到 Satis 源
配置 composer.json 指向私有源:顺序和 type 关键字不能错
本地项目要装私有包,composer.json 的 repositories 必须显式声明私有源,并注意优先级。Composer 默认只查 packagist.org,加了私有源后,它会按数组顺序从左到右匹配——所以私有源要放在最前面,否则可能命中公共同名包导致安装失败。
{
"repositories": [
{
"type": "composer",
"url": "https://packagist.internal.company.com"
},
{
"type": "packagist",
"url": "https://packagist.org"
}
],
"require": {
"company/internal-sdk": "^2.1"
}
}
-
type必须是composer(不是vcs或package),否则无法解析packages.json - 如果私有源启用了 Basic Auth,URL 要写成
https://user:pass@packagist.internal.company.com,但更推荐用auth.json管理凭证 - 不要在
repositories里混用type: vcs和type: composer——前者是单包直连 Git,后者是完整 Packagist 协议源,行为完全不同
认证与凭证管理:别把 token 塞进 composer.json
私有源基本都需要认证,但 composer.json 是公开文件,绝不能放密码或 token。正确做法是用全局 auth.json,它默认位于 ~/.composer/auth.json(Linux/macOS)或 %APPDATA%\Composer\auth.json(Windows)。
{
"http-basic": {
"packagist.internal.company.com": {
"username": "ci-bot",
"password": "ghp_abc123..."
}
}
}
- 执行
composer config -g http-basic.packagist.internal.company.com ci-bot ghp_abc123...会自动写入auth.json,比手写更安全 - CI 环境(如 GitHub Actions)应通过
COMPOSER_AUTH环境变量注入,值为 JSON 字符串:{"http-basic":{"packagist.internal.company.com":{"username":"ci-bot","password":"${{ secrets.PACKAGIST_TOKEN }}"}}} - 如果私有源用 OAuth2(如 PP),
auth.json里要填oauth字段,不是http-basic
私有包版本约束:避免 dev-main 锁死开发流
内部包常处于活跃开发中,但直接 require "dev-main" 会导致 composer install 总拉最新 commit,破坏可重现性。正确做法是用 dev- + 分支名 + #commit-hash 锁定具体提交,或统一走语义化标签。
- 开发阶段可用
"company/internal-sdk": "dev-develop#abc1234",确保所有环境拉同一份代码 - 上线前必须打 Git tag(如
v1.2.0),并在私有源里同步——Satis 需运行php bin/satis build ...,PP 会自动监听 tag 事件 - 禁止在
require中写"dev-master":Master 分支随时变,CI 构建可能今天成功、明天失败 - 如果内部包依赖另一个内部包,两个包都必须在私有源中注册,且版本约束要兼容——Composer 不会跨源解析
最难绷的是权限链:Git 仓库权限 → 私有 Packagist 同步权限 → Composer 客户端认证权限,三者缺一不可。漏掉任意一环,composer update 就会报 Could not fetch 或 401 Unauthorized,而不是明确提示哪一层挂了。


















