离线包分发必须绕过packagist,用path仓库或本地http服务替代远程源:path适用于少量私有包,http服务(如nginx)需提供合法packages.json和zip;禁用packagist.org、清理lock中source字段、验证repos.packagist为false且install日志无远程下载。

离线包分发必须绕过 Packagist,用本地文件协议或 HTTP 服务替代远程仓库
Composer 默认依赖 Packagist,在无网络或内网隔离环境下会直接失败。关键不是“怎么配”,而是“怎么让 Composer 完全不碰外网”。所有远程仓库地址(https://repo.packagist.org)必须被显式替换为本地可访问的源,且该源必须能响应 packages.json 和 ZIP 包请求。
- 最简方案:用
path类型仓库指向本地已解压的包目录,适用于少量、稳定、不常更新的私有包 - 生产级方案:搭一个轻量 HTTP 服务(如 Nginx + static files),把
packages.json和 ZIP 存进去,再用composer config -g repositories.official.type composer指向它 - 绝对禁止:在
repositories中写packagist.org或留空——这会让 Composer 自动 fallback 到官方源,导致超时或静默失败
如何生成可用的 packages.json 并保证结构合法
离线源的核心是 packages.json 文件,它不是手写的 JSON,而是由 Composer 自己导出的元数据快照。手动拼写极易出错,比如 missing packages key、version 键名大小写错误、dist.type 缺失等,都会导致 composer install 报 Could not parse version constraint 或直接跳过该包。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 先在有网环境执行:
composer archive --format=zip --dir=./dist vendor/package-name,得到 ZIP 包 - 再用
composer show -s vendor/package-name查看其 dist URL 和 version,用于构造packages.json中的dist字段 - 最终
packages.json必须包含packages数组,每个包项含name、version、dist(含url和type)、autoload等字段;推荐用satis或Private Packagist自动生成,避免手写
为什么 vendor 目录不能直接拷贝到离线环境
拷过去确实能跑,但不是“离线分发”,只是临时逃逸。问题在于:composer.lock 里记录的是远程源地址和哈希值,下次 composer update 或 install 仍会尝试连接原仓库;且新依赖无法加入,版本冲突无法解析,require 新包会失败。
- 正确做法:在离线环境首次运行前,先用
composer install --no-interaction --prefer-dist,确保所有依赖都从本地源拉取并写入 lock - 必须删掉
composer.lock里的packages字段下所有source块(只保留dist),否则 Composer 仍会尝试 clone - 验证方式:
composer config -g repos.packagist应返回false,且composer install -vvv日志中不应出现Downloading https://
离线镜像的缓存与存储路径必须独立
多个项目共用 COMPOSER_CACHE_DIR 会导致 ZIP 包校验失败或重复下载——因为缓存键基于 URL,而离线环境 URL 是 file:/// 或内网地址,不同项目若共享缓存,会互相污染。
- 每个离线分发单元(如一个交付给客户的 ZIP 包)应带独立缓存路径:
export COMPOSER_CACHE_DIR=/tmp/composer-cache-offline-$(date +%s) - Docker 场景下,必须用
VOLUME显式挂载缓存目录,不能复用宿主机全局缓存 - 如果用
path仓库,注意symlink在容器内可能失效,建议设"options": {"symlink": false}避免报错
真正难的不是生成 ZIP 或写 JSON,而是让 Composer 完全“忘记”互联网的存在——任何残留的远程配置、未清理的 lock 字段、或默认启用的 packagist.org fallback,都会在某个深夜部署时突然触发超时,让你翻遍日志也找不到源头。










