🏭 Satis 私有仓库构建器
18 分钟,用 Composer SDK 的 Satis 方法初始化配置、加仓库、加 require、构建出可托管的静态私有 Packagist。需要本机有 PHP + Composer。
为什么需要 Satis
公司内部有不能上 Packagist 的私有包,但又想用 Composer 统一管理。Satis 把你指定的私有 Git 仓库打包成一个静态网站(含 packages.json),团队 composer install 时直接从这里拉取。
第 1 步:初始化配置
comp.InitSatis(name, homepage, dir) 在 dir 下生成 satis.json 骨架。也可以用 CreateSatisConfig(configPath, name, homepage) 显式指定配置文件路径。
第 2 步:加仓库与 require
AddSatisRepository(configPath, type, url)— 往配置里追加一个仓库(type通常是git/vcs)。AddSatisRequire(configPath, packageName, version)— 限定只打包某些包;不限定则用require-all: true。
第 3 步:构建
comp.BuildSatis(configPath, outputDir) 执行 satis build,把所有版本下载、打包进 outputDir,返回构建输出文本。
完整可运行示例
package main
import (
"fmt"
"log"
"github.com/scagogogo/composer-skills/pkg/composer"
)
func main() {
comp, err := composer.New(composer.DefaultOptions())
if err != nil {
log.Fatal(err)
}
const (
cfgPath = "/tmp/satis/satis.json"
outDir = "/tmp/satis/public"
home = "https://composer.internal.mycompany.com"
)
// 1️⃣ 初始化配置
if err := comp.InitSatis("mycompany/satis", home, "/tmp/satis"); err != nil {
log.Fatalf("init: %v", err)
}
fmt.Println("📄 satis.json 已生成")
// 2️⃣ 添加私有 VCS 仓库
repos := []struct{ typ, url string }{
{"git", "https://git.internal.mycompany.com/team/auth.git"},
{"git", "https://git.internal.mycompany.com/team/billing.git"},
}
for _, r := range repos {
if err := comp.AddSatisRepository(cfgPath, r.typ, r.url); err != nil {
log.Fatalf("add repo %s: %v", r.url, err)
}
fmt.Printf("🔗 已加仓库: %s\n", r.url)
}
// 3️⃣ 限定打包范围(可选,不限定则 require-all)
if err := comp.AddSatisRequire(cfgPath, "mycompany/auth", "*"); err != nil {
log.Fatalf("add require: %v", err)
}
if err := comp.AddSatisRequire(cfgPath, "mycompany/billing", "*"); err != nil {
log.Fatalf("add require: %v", err)
}
// 4️⃣ 构建
output, err := comp.BuildSatis(cfgPath, outDir)
if err != nil {
log.Fatalf("build: %v", err)
}
fmt.Println("🏗️ 构建输出:")
fmt.Println(output)
fmt.Printf("✅ 静态仓库已生成于 %s,包含 packages.json\n", outDir)
}预期输出
📄 satis.json 已生成
🔗 已加仓库: https://git.internal.mycompany.com/team/auth.git
🔗 已加仓库: https://git.internal.mycompany.com/team/billing.git
🏗️ 构建输出:
Building dev-main
Collecting packages...
✅ 静态仓库已生成于 /tmp/satis/public,包含 packages.json第 4 步:让项目消费这个仓库
构建出的 outDir 用任意静态服务器托管(nginx / Caddy / 对象存储)。在消费端 PHP 项目里加上仓库并安装:
composer config repositories.mycompany composer https://composer.internal.mycompany.com
composer require mycompany/auth:"*"进阶:定制配置结构
pkg/composer.SatisConfig 是公开结构体,可直接读写后用标准 json.MarshalIndent 落盘,灵活控制 minimum-stability、archive(打包离线 zip)、providers(V2 分片)等:
cfg := composer.SatisConfig{
Name: "mycompany/satis",
Homepage: home,
OutputDir: "public",
RequireAll: false,
MinimumStability: "stable",
Archive: map[string]interface{}{
"directory": "dist",
"format": "tar",
},
}
b, _ := json.MarshalIndent(cfg, "", " ")
os.WriteFile(cfgPath, b, 0644)require-all vs require
私有包少时用 AddSatisRequire 精确打包,构建快、产物小;包多且都想暴露时用 require-all: true(InitSatis 默认即如此)。
Satis 需要单独安装
Satis 不是 Composer 自带的命令,需先在全局装一次:composer global require composer/satis。本机若未装,BuildSatis 会报命令不存在。
下一步
- 给私有仓库加安全审计:🔒 构建安全审计流水线。
- 把 Satis 的包索引统计做成看板:🪞 包镜像。