COMPOSER_DISABLE_NETWORK=1是唯一可靠的隔离开关,不设则composer install必请求packagist元数据;它硬性阻断所有远程URL解析,不重试不fallback,且必须在运行前导出,比禁用packagist源更底层。

COMPOSER_DISABLE_NETWORK=1 是唯一可靠的隔离开关
不设这个环境变量,composer install 就算加了 --no-plugins 也会在解析 composer.json 阶段尝试请求 https://repo.packagist.org/packages.json。这不是配置疏漏,是 Composer 默认行为——它要校验包元数据合法性。一旦机器意外连通外网(比如容器桥接错配、运维临时开代理),这个请求就会发出,暴露内网结构或触发安全审计。
这个变量是硬性阻断:所有远程 URL 解析直接报错退出,不重试、不 fallback。比 composer config --global repo.packagist false 更底层,后者只禁用 packagist 源,但若 composer.json 里写了 "url": "https://api.github.com" 这类自定义仓库,照样会外连。
- 必须在运行命令前导出:
export COMPOSER_DISABLE_NETWORK=1 - Dockerfile 中要用
ENV COMPOSER_DISABLE_NETWORK=1,不能靠 shell 启动时临时set - CI/CD 流水线中需确保所有
composer步骤都继承该环境变量
备份 vendor 前必须清空缓存目录
很多人在联网机上跑完 composer install 就直接打包 vendor/ 拷进内网,结果镜像里残留了 ~/.composer/cache/repo.packagist.org/ 下的元数据缓存。这些文件可能被离线环境复用,导致后续 composer update 或插件加载时悄悄回源——尤其当 composer.lock 里有 "source": {"type": "git", "url": "https://github.com/..."} 时,Composer 仍会尝试解析该 URL(哪怕失败)。
- 打包前必须执行:
composer clear-cache - 检查缓存是否清空:
ls -la ~/.composer/cache/应为空或只剩无关子目录 - 如果用 Docker 构建,
clear-cache要放在COPY composer.* .之后、composer install之前
composer.lock 里的 source 字段是离线隐患点
composer.lock 不只是版本快照,它还记录了每个包的 source 信息。如果项目依赖用了 dev 分支、private Git 仓库或 GitHub gist,lock 文件里就会写死 "url": "https://github.com/xxx"。这种写法在离线环境下会导致 composer install 直接失败,但失败前已触发 URL 解析逻辑——而 COMPOSER_DISABLE_NETWORK=1 正是为此兜底:让它报错退出,而不是卡住或 fallback。
- 生成 lock 文件前,确认
composer.json中没写公网repositories,且没设"minimum-stability": "dev" - 若必须用 Git 源,改用本地路径:
"url": "/path/to/local/repo",并确保该路径在目标环境存在 - 检查 lock 文件是否干净:
grep -A5 '"source":' composer.lock | grep url,确认无意外公网地址
备份文件本身不带风险,但恢复时容易误用
备份 composer.json、composer.lock 和 vendor/ 是常规操作,但问题常出在恢复环节。比如把联网机上生成的 vendor/ 直接解压到内网服务器,却忘了同步清理 ~/.composer/ 下的全局配置或插件缓存;又或者用旧版 composer.phar 恢复,而新版已修复某些离线解析 bug。
- 恢复前先验证 Composer 版本:
composer --version,建议统一用 2.7+(对离线场景更严格) - 恢复后不要立刻跑
composer update,先确认COMPOSER_DISABLE_NETWORK=1已生效 - 如果备份含
~/.composer/config.json,恢复时注意删掉其中的repositories字段,避免覆盖全局设置
离线环境最麻烦的不是“装不上”,而是“看似装上了,其实偷偷连了”。关键不在备份动作本身,而在每一步是否切断了所有潜在的网络出口——从环境变量、缓存、lock 文件结构,到恢复时的工具链一致性。











