Composer install 报“Too many open files”是因并发解压触发系统文件描述符限制(默认1024),需通过ulimit -n临时提升或修改/etc/security/limits.conf永久配置,且须确保CI、systemd、Docker等环境同步生效。

Composer install 时提示 “Too many open files” 错误
这是典型的系统级资源限制问题,不是 Composer 本身 bug。当 Composer 并发解压大量包(尤其含 vendor/bin 下多个 PHAR 或嵌套 tar.gz)时,会同时打开数百个文件句柄,超出 PHP 或系统默认的 ulimit -n 限制(常见为 1024),直接触发 Too many open files 错误,中断安装。
关键点在于:这个限制作用在 PHP 进程启动的整个生命周期,包括 proc_open 调用的解压子进程 —— 所以仅调大 PHP 的 open_basedir 或 memory_limit 完全无效。
- 先运行
ulimit -n确认当前限制值;低于 4096 基本就会出问题 - 临时提升可用:
ulimit -n 8192 && composer install - 但更稳妥的是改系统级配置,避免每次手动设
Linux 系统级 ulimit 配置要改 /etc/security/limits.conf
很多人只改了 shell 的 ulimit 或 ~/.bashrc,但 Composer 常被 CI 工具(如 GitHub Actions runner、Jenkins agent)或 systemd 服务调用,这些环境不读用户 shell 配置,必须写入全局 limits。
编辑 /etc/security/limits.conf,追加两行(注意用户名或组名要匹配实际运行 Composer 的账户):
立即学习“PHP免费学习笔记(深入)”;
www-data soft nofile 8192 www-data hard nofile 8192
如果用 root 或当前用户执行,换成 * soft nofile 8192;hard 是上限,soft 是运行时生效值,两者需同时设。
- 改完需重新登录或重启对应服务(systemd 服务需
sudo systemctl daemon-reload) - 验证是否生效:在目标用户下执行
ulimit -n,且确保composer install进程继承该值(可ps -eo pid,comm,rlimit | grep composer查看) - 某些容器环境(如 Docker)需在
docker run时加--ulimit nofile=8192:8192,limits.conf不生效
Composer 自身并发数控制能缓解但不能根治
composer install 默认启用多进程解压(由 composer/composer 内部的 ParallelDownloader 控制),并发数取决于 CPU 核心数,通常 4–8 个进程同时解压,每个解压操作又会打开数十个文件句柄 —— 这才是压垮 ulimit 的直接原因。
临时绕过可强制降并发:
composer install --no-plugins --no-scripts -n --prefer-dist
其中 -n(--no-interaction)会禁用部分交互式解压逻辑,但最有效的是设置环境变量:
-
COMPOSER_PARALLEL_JOBS=1 composer install:强制单进程,彻底避开并发文件打开 -
COMPOSER_DISABLE_NETWORK=1对离线安装有用,但不解决解压阶段的句柄问题 - 注意:降并发会显著拖慢安装速度,尤其在 HDD 或低配 VM 上,只是权宜之计
PHP-FPM 或 CLI 的 max_files 配置无关
有人尝试改 php.ini 里的 max_files 或 max_execution_time,完全没用 —— 这些是 PHP 脚本层限制,而 “Too many open files” 是操作系统内核返回的 EMFILE 错误,发生在 fopen()、tar -xzf 等系统调用层面,PHP 解释器根本没机会拦截或处理。
真正要盯住的是三处:
- shell 启动时的
ulimit -n值 - systemd service 文件里是否显式设了
LimitNOFILE= - Docker 容器启动参数或 Kubernetes pod spec 中的
securityContext.limits
任何一处漏掉,都可能让 Composer 在某个环节突然失败,而且错误日志里只显示模糊的 “failed to extract” 或 “cannot open file”,不容易定位到根源。



















