如何使用Satis或Packagist搭建私有Composer仓库? (内网部署)

14次阅读

Satis 更适合内网私有 composer 仓库,因其是轻量静态元数据生成器,无需数据库和运行时服务,仅通过配置即可支持私有 git 仓库、分支/标签精准控制及全版本兼容。

如何使用Satis或Packagist搭建私有Composer仓库? (内网部署)

私有 Composer 仓库在内网环境下,Satis 是更轻量、可控且无需数据库和 Web 框架的首选;Packagist 官方版(packagist/packagist)不适合直接内网部署——它依赖 postgresqlelasticsearchredis 和大量后台服务,运维成本远超实际需求。

为什么 Satis 更适合内网私有仓库

Satis 本质是一个静态包元数据生成器:它读取 composer.json 配置,拉取 Git 仓库(支持 ssh/http),执行 git clonecomposer install(可选),最后输出 packages.json 和压缩包(.zip.tar)。整个过程无运行时服务,生成结果可直接托管在 nginx/apache 或甚至 file:// 协议下被 composer 客户端消费。

  • 不依赖数据库或队列,配置即生效
  • 支持私有 Git 仓库(如 giteagitlab Self-Hosted),通过 auth.json 注入凭据
  • 可精确控制哪些分支/标签被发布(用 "minimum-stability""stability-flags"
  • 生成的 packages.json 兼容所有 Composer 版本(包括 2.x)

Satis 部署三步走:配置 → 构建 → 托管

ubuntu 22.04 + php 8.1 环境为例,目标是将公司内部 git@git.internal:php/my-sdk.gitv1.2.0dev-main 发布为私有包。

第一步:安装 Satis(推荐全局 Phar)

curl -sS https://getcomposer.org/installer | php php composer.phar global require composer/satis --no-plugins

第二步:编写 satis.json

{   "name": "internal/packagist",   "homepage": "https://packages.internal",   "repositories": [     {       "type": "vcs",       "url": "git@git.internal:php/my-sdk.git"     }   ],   "require-all": true,   "archive": {     "directory": "dist",     "format": "zip",     "skip-dev": false,     "prefix-url": "https://packages.internal/dist"   } }

第三步:构建并发

  • 确保 ~/.composer/auth.json 已配置 SSH key 或 HTTP Token(用于访问私有 Git)
  • 运行:php ~/.composer/vendor/bin/satis build satis.json web/
  • web/ 目录部署到 Nginx 根路径(如 /var/www/packages),确保 packages.json 可被公开 GET 访问

客户端如何使用该私有仓库

项目根目录下创建或修改 composer.json,添加 repositories 条目:

{   "repositories": [     {       "type": "composer",       "url": "https://packages.internal"     }   ],   "require": {     "internal/my-sdk": "^1.2"   } }

关键注意事项:

  • url 必须指向包含 packages.json 的目录(不是文件本身),且该 URL 必须能被开发机/CI 环境直连(内网 DNS 或 hosts 要配好)
  • 若使用自签名 HTTPS 证书,需在客户端机器设置:export COMPOSER_DISABLE_TLS=1(仅限测试)或向系统 CA 信任库导入证书
  • 每次更新包版本后,必须重新运行 satis build,否则客户端查不到新版本(Satis 无自动监听机制)

常见失败现象与定位点

典型报错:[ComposerDownloaderTransportException] The 'https://packages.internal/packs/internal/my-sdk/1.2.0.0-zip' URL could not be accessed

原因往往不在 Satis 配置,而在路径映射断层:

  • archive.prefix-url 值是否与 Nginx 实际服务路径一致?比如 Nginx root 是 /var/www/packages,但 prefix-url 写成 https://packages.internal/assets,就会 404
  • 生成的 dist/ 目录是否被 Nginx 正确暴露?检查 Nginx 配置中是否有 location /dist { alias /var/www/packages/dist; } 这类映射
  • Git 仓库的 tag 名是否符合 Composer 版本规范?v1.2.0 合法,1.2.0-release 默认不识别(需加 "version": "1.2.0.0"composer.json 中)

最易被忽略的是权限链:Satis 构建时用的用户(如 www-data)能否 git clone 私有仓库?能否写入 web/dist/?这些错误不会中断构建,但会导致 packages.json 中的 dist.url 指向一个根本不存在的 ZIP 文件。

text=ZqhQzanResources