必须同时禁用 packagist.org fallback,仅配私有源无效;repositories 末尾须加 {"packagist": false};artifact 用于分发、path 用于本地开发,不可混用;需全局+项目双重配置并启用 COMPOSER_DISABLE_NETWORK=1。

团队协作中配置统一离线源,不是加个 repositories 就完事——必须同时关掉 packagist.org 的 fallback 行为,否则哪怕私有源配对了,composer install 仍会偷偷连外网。
项目级必须显式禁用 packagist.org
只在 composer.json 的 repositories 里写私有源,不加 "packagist": false,等于没关。Composer 会把你的私有源当“补充”,默认仍 fallback 到 https://repo.packagist.org。
-
"repositories"数组末尾必须包含{"packagist": false},不能放在中间或开头 - 如果已有
"type": "composer", "url": "https://packagist.org"这类条目,直接删掉,别想着“覆盖” - 运行
composer config repositories检查输出,确认没有 packagist.org 相关 URL - 加
-v参数跑一次composer install,看到Downloading https://repo.packagist.org/packages.json就说明某处漏了
私有源类型选 artifact 还是 path?看用途
artifact 适合部署分发,path 适合本地开发联调,两者不能混用,也不能靠它替代初始化。
-
artifact:包必须是vendor-name/package-name-version.tar.gz格式,放在扁平目录(如/opt/artifacts/),配置为{"type":"artifact","url":"/opt/artifacts/"} -
path:仅限你手头已有完整源码的包,路径必须相对项目(如./packages/my-utils),且composer.json中需含"options": {"symlink": false} - 用
path时,require 必须带@dev,例如composer require my-utils/my-utils:@dev,否则不生效 - 不要在
repositories里混写多个类型——artifact 和 path 各自独立生效,但冲突配置会导致行为不可预测
全局和项目级配置要双重保险
光改项目 composer.json 不够,CI/CD 或开发者本地环境可能继承全局配置,导致离线失效。
- 执行
composer config --global repo.packagist false,彻底关闭全局源 - 检查
composer config --global repos输出,确保没残留packagist.org条目 - CI 脚本开头加
COMPOSER_DISABLE_NETWORK=1,防止插件或脚本绕过配置发起请求 - 离线机首次运行前,建议清空缓存:
composer config --global cache-dir /dev/null,避免缓存里残留远程元数据
最常被忽略的一点:Satis 镜像生成的 packages.json 必须被 Web 服务正确托管,且 archive.prefix-url 必须与实际访问地址完全一致——少一个斜杠、协议不匹配、路径重定向,都会让 dist.url 解析失败,最终退回到联网请求。











