Composer的--timeout参数仅控制其对子进程的等待超时,不防止系统级kill;真正导致进程被杀的是外层timeout命令、Docker stop-timeout、CI超时或OOM Killer。

Composer 本身不控制进程是否被系统杀死,它只管自己内部的超时逻辑;真正会“被系统杀死”的,是外层 timeout 命令、Docker stop-timeout、CI runner 超时机制,或 OOM Killer —— 这些和 composer install --timeout=600 完全无关。
为什么 --timeout 参数不能防止系统级 kill
Composer 的 --timeout(或 process-timeout 配置)只影响 Composer 主进程对子进程(如 git clone、curl 下载、解压脚本)的等待时间。一旦超时,它抛出 ProcessTimedOutException 并退出,属于“主动放弃”,不是被系统中断。
而系统级 kill 是另一回事:
- Docker 容器中用了
docker run --stop-timeout=10,容器收到 SIGTERM 后 10 秒没退出就会被 SIGKILL 强杀 —— Composer 来不及响应 - GitHub Actions 默认 job 超时为 6 小时,但某些 runner(如 self-hosted)可能被配置为 30 分钟硬限制,超时直接终止进程树
- Linux 内存不足时触发 OOM Killer,会按评分选进程干掉,
php进程常首当其冲,和 timeout 设置毫无关系
如何避免被系统 kill:关键检查点
别只盯着 Composer 配置,先确认外层环境是否在“定时清场”:
- 在 CI 中执行前加
echo "PID: $$"; ps auxf,看当前进程是否被嵌套在timeout 300或bash -c 'timeout ...'里 - Docker 场景下检查:
docker inspect <container> | grep StopTimeout</container>;若为 0 或很小,需改用--stop-timeout=1200 - GitHub Actions 中显式声明超时:
timeout-minutes: 45,并确保COMPOSER_PROCESS_TIMEOUT≤ 这个值(否则 Composer 先挂,系统不会等) - 用
free -h和dmesg -T | grep -i "killed process"排查是否 OOM —— 此时调大process-timeout反而更易触发 OOM
COMPOSER_PROCESS_TIMEOUT 环境变量的隐含行为
这个变量确实能覆盖默认 process-timeout,但它不是“保命开关”,反而可能掩盖真实瓶颈:
- 设为
0表示禁用 Composer 自身超时,但若网络卡死在git clone阶段,进程会无限挂起,最终仍被外层 timeout 或 OOM 干掉 - 它不改变 PHP 的
max_execution_time,所以 post-install-cmd 脚本里的 PHP 逻辑仍可能因超时被 PHP 中止(报Maximum execution time exceeded) - 在 Docker 中设置该变量后,需确认未被 entrypoint 覆盖 —— 某些基础镜像会在启动时重置环境变量
真正有效的组合策略
单靠 timeout 设置无法防系统 kill,必须分层应对:
- 网络层:配 GitHub Token + 换阿里镜像源 +
COMPOSER_DISABLE_PARALLEL=true,减少并发连接压力 - 资源层:Docker 启动时加
--memory=2g --memory-swap=2g,避免 OOM;CI 中用runs-on: ubuntu-22.04(内存更足) - 进程层:用
php -d max_execution_time=0 -d memory_limit=-1 composer install,解除 PHP 自身限制 - 兜底层:CI 脚本中用
timeout 1800 composer install || echo "Composer failed, check logs",把系统级超时显式暴露出来,而不是让它静默消失
最常被忽略的是:你以为在调 Composer 超时,其实系统早就给你设好了更短的倒计时——先查外层,再调内层。


















