搭建私有 Satis 仓库的步骤与认证方案

解读

在国内 PHP 面试中,这道题考察的是候选人对 Composer 生态的深度掌握,而不仅仅是“会用 composer install”。
Satis 是 Composer 官方提供的静态仓库生成器,能把公司内部的私有包(如基础组件、SDK、业务模块)集中管理,解决“Git 仓库直接依赖”带来的版本混乱、权限失控、Git 服务器压力等问题。
面试官想听到的是:

  1. 你能从零搭建一套可落地的 Satis 方案;
  2. 你清楚国内网络、合规、安全(源码不外泄)的痛点,并给出对应认证与加速策略;
  3. 你能说明后续 CI/CD、版本约束、灰度发布的配合方式。
    回答时先给主线步骤,再针对“认证”展开两种以上企业级方案,最后补充高可用与审计细节,体现“可维护、可审计、可扩展”的工程思维。

知识点

  • Composer 仓库类型:Composer、VCS、Path、Artifact、Satis(静态)
  • Satis 工作原理:扫描指定源码仓库 → 生成 packages.json 及 zip 归档 → 静态文件落地 → Nginx 纯静态服务
  • 认证层:HTTP Basic(Nginx auth_basic)、Bearer Token(PHP 转发)、LDAP 统一登录、IP 白名单、HTTPS 双向证书
  • 国内加速:Nginx 开启 gzip/br、阿里云 OSS 反向代理、CDN 回源私有 Bucket、rsync 多机房同步
  • 安全合规:源码包加密归档、审计日志(谁、何时、拉取哪个版本)、与内部工单系统对接
  • 版本策略:semver 三段位 + 公司第四段位(如 2.3.4.20250619)、branch-alias、composer.lock 统一
  • CI 集成:GitLab CI 推送 tag → 触发 Satis 重新 build → 生成新静态文件 → 刷新 CDN 缓存 → 企业微信群通知

答案

步骤一:准备 Satis 环境

  1. 选用一台内网 CentOS 7/8 或 Ubuntu 20.04 最小化机器,2C4G 即可,挂载 100G SSD 单独盘 /data/satis;
  2. 安装 PHP ≥7.4 与 Composer 2,国内镜像源使用阿里云:composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/
  3. 全局安装 Satis:composer global require composer/satis --dev,并把 ~/.config/composer/vendor/bin 加入 PATH。

步骤二:编写 satis.json
示例:

{
  "name": "company/satis",
  "homepage": "https://satis.company.local",
  "repositories": [
    { "type": "git", "url": "ssh://git@gitlab.company.local:2222/php/common.git" },
    { "type": "git", "url": "ssh://git@gitlab.company.local:2222/php/order-sdk.git" }
  ],
  "require-all": true,
  "archive": {
    "directory": "dist",
    "format": "zip",
    "skip-dev": true
  },
  "config": {
    "secure-http": false
  }
}

说明:

  • require-all:true 一次性扫描所有 tag/branch,省去手动写版本;
  • archive 会把 zip 包落到本地,避免后续用户直接去 Git 服务器拉源码,降低 Git 压力;
  • secure-http:false 方便内网自签证书调试,生产建议改为 true 并配置可信 CA。

步骤三:生成静态仓库

cd /data/satis
satis build satis.json public

首次构建后目录结构:

public/
├── index.html
├── packages.json
├── dist/
│   ├── common-1.0.0.zip
│   └── order-sdk-2.3.4.zip

把 public 目录设为 Nginx 根目录,配置:

server {
    listen 443 ssl http2;
    server_name satis.company.local;
    ssl_certificate     /etc/nginx/ssl/satis.pem;
    ssl_certificate_key /etc/nginx/ssl/satis.key;
    root /data/satis/public;
    location / {
        try_files $uri $uri/ =404;
        auth_basic "Company Satis";
        auth_basic_user_file /etc/nginx/htpasswd.satis;
    }
    access_log /var/log/nginx/satis.access.log main;
}

htpasswd 文件用 htpasswd -c /etc/nginx/htpasswd.satis alice 生成,定期通过 LDAP 脚本同步,实现“离职即失效”。

步骤四:客户端使用
在项目 composer.json 里新增:

"repositories": [
  {
    "type": "composer",
    "url": "https://satis.company.local",
    "options": {
      "http": {
        "header": [
          "Authorization: Basic " + base64_encode("alice:password")
        ]
      }
    }
  }
]

为了把账号密码从代码中剥离,可借助 composer auth.json:

composer config --global http-basic.satis.company.local alice password

文件权限 600,放在 Jenkins 或 GitLab Runner 的 ~/.composer 目录,配合 CI 变量 COMPOSER_AUTH 注入。

步骤五:认证方案对比与选型

  1. HTTP Basic + LDAP 同步:最轻量,适合 200 人以内研发团队;
  2. Bearer Token + PHP 网关:写一段 30 行的 index.php,验证 Redis 中的 JWT,再把请求转发到静态文件,可细粒度到“项目级”授权;
  3. IP 白名单 + VPN:仅允许办公网、跳板机、K8s Pod 网段访问,最简单粗暴,适合金融类隔离环境;
  4. 双向 TLS:客户端证书内置在 Runner 镜像,无需账号密码,适合无人值守的自动部署。
    落地建议:
  • 开发阶段用方案 1,CI 阶段用方案 4,外部供应商联调用方案 2 的临时 Token(24h 过期)。

步骤六:高可用与灰度

  • 在 Nginx 层做健康检查,rsync 把 /data/satis/public 实时推到备份节点;
  • 每次 build 完成后记录 git commit 与 build id,回滚时直接切换软链;
  • 对核心包使用“双轨制”:稳定版放 release 目录,开发版放 dev 目录,业务线通过 "preferred-install": "dist""minimum-stability": "stable" 隔离。

拓展思考

  1. 如果公司包数量超过 3000、体积过 200G,Satis 全量扫描变慢,可改用 Private Packagist 或 Repman,或自研“增量更新”脚本:只扫描 git tag 变更,diff 后更新 packages.json 片段。
  2. 国内多云场景下,可把 dist 目录同步到阿里云 OSS,再开私有 Bucket + CDN,回源 Host 绑定内网域名,既加速又省流量费。
  3. 审计与合规:在 Nginx 日志里解析 user、package、version,接入 ELK,每天出报表“谁拉取了哪些包”,防止源码外泄;对敏感包(支付 SDK)可再叠加“二次审批”流程,Runner 需要临时 Token 才能安装。
  4. 与 GitLab Package Registry 对比:GitLab 原生支持 Composer,但版本检索性能差、权限模型固定;Satis 方案更灵活,适合“多 Git 平台混合”的中大型企业。
  5. 未来如果转向微服务 + 多语言,可评估 Nexus3、Harbor 的 Composer 插件,统一治理 PHP、Java、Docker 镜像,降低运维碎片度。