离线共享源必须用artifact类型,不能配packagist镜像;它只读本地.tar.gz并校验dist.shasum,不发任何网络请求,且需全局禁用packagist、url为无斜杠绝对路径、包命名与内部composer.json严格一致。

离线共享源必须用 artifact 类型,不能配 packagist 镜像
artifact 是唯一能绕过所有网络请求的仓库类型,它只读本地 .tar.gz 文件并校验 dist.shasum,不查元数据、不连 DNS、不 fallback。配成 "type": "composer" 或改 repo.packagist URL 本质仍是联网行为,哪怕指向内网 Nginx,Composer 仍会发 HEAD 请求校验 packages.json 和 provider-*.json,离线时直接失败。
常见错误现象:Could not fetch https://internal-mirror.example.com/packages.json,即使你把整个 Satis 输出目录拷过去也一样——因为 Composer 默认仍要解析 provider 列表。
- 必须全局禁用默认源:
composer config --global repo.packagist false - 项目级配置中
repositories只保留一条:{"type":"artifact","url":"/path/to/artifacts/"} -
url必须是绝对路径,且结尾不带斜杠(/path/to/artifacts✅,/path/to/artifacts/❌) - 执行
composer install -v时,输出里不能出现任何Downloading或GET字样
包文件命名和结构必须严格匹配 Composer 解析逻辑
artifact 仓库不解析目录树,只靠文件名匹配 vendor/name-version.tar.gz,再读包内 composer.json 的 name 和 version 字段做二次校验。任意一环不一致,就报 Could not find package xxx in a version installable using your PHP version。
典型错例:monolog/monolog-2.13.0.tar.gz 里 composer.json 写的是 "name": "monolog/monolog" ✅,但若写成 "name": "monolog/monolog-dev" 或 "version": "2.13"(缺补零),就会静默跳过该包。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
- 包文件必须放在
url指向目录的**根层**,不能嵌套子目录(/artifacts/monolog/monolog-2.13.0.tar.gz✅,/artifacts/monolog/2.13.0/monolog-2.13.0.tar.gz❌) - 版本号必须带完整补零,如
2.13.0,不能简写为2.13;预发布版本需含-beta1等后缀 - 所有包必须提前在联网机生成,推荐用
composer archive --format=tar.gz命令导出,避免手打压缩包漏掉composer.json或权限异常
团队协作时缓存目录不能共用,但 artifact 路径必须统一
多个开发者共用一个 ~/.composer/cache/ 目录会导致冲突:A 下了 monolog-2.13.0,B 同时 require monolog-2.13.1,可能覆盖或混杂 ZIP 文件。但 artifact 仓库不同——它是只读的静态文件集,所有人指向同一 /shared/artifacts 即可,无需同步缓存。
关键点在于路径一致性:开发机、CI 构建机、测试机、部署机,只要 composer config repositories.offline.url 指向的路径相同(比如都设为 /opt/composer-artifacts),且该路径挂载方式一致(NFS / bind mount / rsync 同步),就能保证行为完全一致。
- 别用
cache-dir做共享源——它只是缓存父目录,files/下的 ZIP 才是实际载体,但cache-dir不控制 ZIP 存放位置 - 如果用 Docker,确保
/opt/composer-artifacts以ro方式挂载,且容器内 PHP 进程用户(如www-data)对该路径有read+execute权限 - 新增包时,不要运行
composer update——它会尝试联网。应由专人维护 artifact 目录,加新包后通知团队rsync -av /src/artifacts/ user@target:/opt/composer-artifacts/
离线环境下 composer install 失败的三个静默原因
很多团队看到 composer install 报错就以为是包缺失,其实更常踩的是配置残留、锁文件陷阱和 autoload 断链。这些错误不会明确提示“网络问题”,而是表现为包找不到、类加载失败或命令卡住。
-
composer.lock中存在"source"类型条目(如"type": "git"或"url": "https://github.com/xxx"),离线时无法校验 commit hash,install 直接退出 - 全局配置残留
repo.packagist:即使设了 artifact,Composer 仍会在 fallback 阶段尝试访问https://repo.packagist.org,导致 DNS 超时卡住 - 没清空旧
vendor/就跑composer install:Composer 会尝试 diff 已有文件并触发部分 autoload 重建逻辑,某些自定义 autoloader(如 Laravel 的ClassLoader)会隐式 require 远程类
真正稳的流程是:先删 vendor/ 和 composer.lock(用已验证的离线版 lock),再设好 artifact,最后跑 COMPOSER_DISABLE_NETWORK=1 composer install --no-plugins --no-scripts --no-autoloader && composer dump-autoload -o。中间任何一步跳过,都可能让问题藏到运行时才暴露。










