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

私有 Composer 仓库在内网环境下,Satis 是更轻量、可控且无需数据库和 Web 框架的首选;Packagist 官方版(packagist/packagist)不适合直接内网部署——它依赖 PostgreSQL、Elasticsearch、Redis 和大量后台服务,运维成本远超实际需求。
为什么 Satis 更适合内网私有仓库
Satis 本质是一个静态包元数据生成器:它读取 composer.json 配置,拉取 Git 仓库(支持 SSH/HTTP),执行 git clone 和 composer install(可选),最后输出 packages.json 和压缩包(.zip 或 .tar)。整个过程无运行时服务,生成结果可直接托管在 Nginx/Apache 或甚至 file:// 协议下被 composer 客户端消费。
- 不依赖数据库或队列,配置即生效
- 支持私有 Git 仓库(如 Gitea、GitLab 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.git 的 v1.2.0 和 dev-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 无自动监听机制)
常见失败现象与定位点
典型报错:[Composer\Downloader\TransportException] 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 文件。










