局域网用 composer 镜像源只需确保 packages.json 和 dist/*.zip 可通过 http 直接访问,路径、响应头、配置三者严丝合缝;satis 构建需设 "require-all": true、完整 "archive" 块、正确 "repositories" 数组;客户端 composer.json 必须以 / 结尾、"packagist.org": false 置根节点、私有源排首位,并清除 vendor/ 和 lock 文件。

局域网内用 Composer 镜像源,根本不需要同步 packagist.org —— 你真正要做的,是让所有机器都能通过 HTTP 直接 GET 到 packages.json 和 dist/*.zip,且路径、响应头、配置三者严丝合缝。其他所谓“同步”方案,90% 是踩坑起点。
为什么 composer config -g repo.packagist 在局域网里静默失效
这条命令只改元数据入口(packages.json),但不碰任何包的 dist.url。Satis/Nexus 生成的 ZIP 默认放在 dist/xxx.zip,而 Composer 仍会按 lock 文件里原始 GitHub 地址去下载——局域网根本打不开。
- 它只影响元数据请求,不影响 ZIP 下载路径;
dist.url来自packages.json里的每个包定义,Satis 必须自己生成正确的 URL - 全局配置写入的是当前用户(如
root)的~/.composer/config.json,但宝塔用www、Docker 用runner、CI 用非交互用户,压根读不到 - 键名写成
repos.packagist(多一个 s)、漏掉中间composer类型值、URL 少末尾/—— 三者任一出错,Composer 都静默 fallback 到官方源,不报错也不提示 - 验证是否生效:运行
composer config -g repo.packagist,输出必须是完整 JSON,形如{"type": "composer", "url": "http://192.168.1.100/"}
Satis 构建私有源时必填的三个字段
Satis 不是代理,不是缓存,它只是静态文件生成器。构建失败或生成后拉不到 ZIP,问题基本锁死在这三项:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
-
"require-all": true—— 否则只同步项目composer.json里显式require的包,其他 tag、dev 分支、历史版本全丢 -
"archive"块必须完整:{"directory": "dist", "format": "zip", "skip-dev": true}—— 缺这个,CI 构建时只能走git clone,而内网往往禁用 git 协议 -
"repositories"必须是对象数组,每个私有 Git 仓库单独声明:{"type": "vcs", "url": "https://git.internal/project-a.git"}—— 写成字符串 URL 或漏type,Satis 构建时直接跳过
客户端 composer.json 怎么写才真正走内网
项目级配置优先级高于全局,且可随代码交付,是唯一靠谱的方式。但手写极易漏关键项:
- 私有源 URL 必须以
/结尾,否则 Composer 拼成http://192.168.1.100packages.json,404 -
"packagist.org": false必须写在composer.json根节点(和require同级),不能嵌套在某个repositories对象里 - 私有源必须放在
repositories数组第一位,Composer 按顺序查找,不会合并同名包 - 已有其他仓库(比如 VCS 定义)时,别手动覆盖整个
repositories数组,用composer config repo.packagist composer http://192.168.1.100/追加更安全 - 改完立刻删掉
vendor/和composer.lock,否则旧 lock 里的哈希仍指向原始源,校验失败
Nginx 暴露 Satis 输出目录时最容易被忽略的细节
镜像服务本身不“主动分发”,只是静态文件托管。路径或响应头稍有偏差,composer install 就卡在 404 或返回 text/plain 被拒绝:
- Nginx 的
root必须精确指向 Satis 的output-dir(如root /var/www/satis/web;),不能多一层或少一层 - 必须显式声明 JSON MIME 类型:
types { application/json json; },否则packages.json返回text/plain,Composer 直接跳过 - 验证 ZIP 是否可直连:用
curl -I http://192.168.1.100/dist/vendor-package-1.0.0.zip,必须返回200且Content-Type: application/zip - Web 服务必须允许跨域(如果前端调用),但 Composer 本身不依赖 CORS,这点常被误判
最常被忽略的一点:Satis 生成的 packages.json 里每个包的 dist.url 是拼出来的,它依赖你在 satis.json 里写的 homepage 和 archive.directory。这两个字段一旦配错,ZIP 路径就断,而错误不会在构建日志里报出来——你得手动打开生成的 packages.json 查看 dist.url 字段是否可访问。










