COMPOSER_DISABLE_NETWORK=1是硬性开关,不设则composer install必卡在远程元数据校验;需配合--no-plugins --no-scripts --no-autoloader及dump-autoload -o,且必须禁用全局镜像、清理含source的lock文件、避免create-project。

COMPOSER_DISABLE_NETWORK=1 是硬性开关,不设它必卡住
Composer 默认行为是强制校验远程元数据,哪怕 vendor/ 已存在、composer.lock 也完整,只要没设 COMPOSER_DISABLE_NETWORK=1,composer install 就会卡在 Loading composer repositories 阶段,或直接报 Could not fetch https://repo.packagist.org/packages.json。这不是网络不稳定,是设计如此。
常见错误操作包括:
- 只加
--no-plugins --no-scripts,却漏掉环境变量 - 误用不存在的
--no-network参数(Composer 官方从未实现) - 在 Windows CMD 中用
set设置后没用&&连接命令,导致变量未生效
离线安装必须配合三 no 参数 + dump-autoload -o
仅设环境变量还不够。默认行为仍会触发插件初始化、脚本执行、autoload 重建——这些环节可能隐式联网(比如 phpstan/extension-installer 初始化时查版本),或因路径残留导致失败。
安全命令组合如下(Linux/macOS):
COMPOSER_DISABLE_NETWORK=1 composer install --no-plugins --no-scripts --no-autoloader && composer dump-autoload -o
关键点说明:
-
--no-plugins:跳过所有插件加载,防止hirak/prestissimo等尝试远程加速 -
--no-scripts:屏蔽post-install-cmd,避免脚本调用curl或npm -
--no-autoloader:绕过 autoload 重建阶段,某些自定义 autoloader 实现会尝试远程类查找 -
dump-autoload -o:必须立即执行,否则运行时大概率报Class not found;-o强制生成优化版映射,比默认散列更稳定
离线添加新包只能走 path 仓库,不能用 require
composer require 在离线时必然失败,因为它默认要联网查包名、版本、依赖树。唯一可行路径是把本地目录当仓库用,靠 path 类型跳过所有元数据请求。
操作步骤:
- 目标包根目录下必须有合法
composer.json,含完整name(如"acme/utils")和明确version或分支标识(如"dev-main") - 项目
composer.json的repositories段显式声明:{"type":"path","url":"./packages/my-utils"} - 执行
composer require acme/utils:@dev(注意必须带@dev,否则不识别) - 必须同步禁用全局 Packagist:
composer config --global repo.packagist false - 安装后立即运行
composer dump-autoload -o
离线前最容易被忽略的三件事
很多团队拷了 vendor/ 过去就以为完事,结果在目标机上直接报错。问题往往出在这三点:
- 没清掉全局镜像配置:
composer config --global repo.packagist false必须执行,否则 Composer 会在离线时 fallback 尝试连接镜像源 -
composer.lock里含"source": {"type": "git"}条目(如"url": "git@github.com:user/repo.git"),这种锁文件天生不支持离线 - 用了
create-project初始化项目——它强制联网解析模板元数据,COMPOSER_DISABLE_NETWORK=1对它完全无效
真离线场景下,composer diagnose 的 Checking HTTP connectivity 行必须显示 FAIL,且 PHP 版本、mbstring/openssl/zlib 扩展、OS 架构、composer.lock 生成上下文,全部需严格对齐。











