必须禁止在PHP-FPM中运行composer install,所有依赖须在构建阶段或CLI环境预装;生产镜像构建强制使用--no-dev --prefer-dist -o -a四参数组合,并通过多阶段构建剥离dev工具、切换非特权用户、验证vendor权限与OPcache预加载一致性。

别在 PHP-FPM 里跑 composer install
PHP-FPM 是为处理 Web 请求设计的,不是执行长时 CLI 任务的环境。你在 www.conf 里调高 request_terminate_timeout,或在 php.ini 里设 max_execution_time = 0,都只是在掩盖问题——FPM 进程会卡住、超时后被杀、日志里堆满 WARNING: [pool www] child 12345 exited on signal 9 (SIGKILL) after 300.000000 seconds。真正该做的是:彻底禁止在 FPM 上触发 composer install。所有依赖安装必须发生在构建阶段(Docker build)或部署前的 CLI 环境中。
容器构建阶段用 --no-dev --prefer-dist --optimize-autoloader --classmap-authoritative
这四个参数不是“可选优化”,是生产镜像构建的硬性组合。漏掉任意一个,vendor 目录体积、首次加载延迟、OPcache 命中率都会明显下降:
-
--no-dev:跳过require-dev下全部包(如phpunit、larastan),减少约 40% 的文件数量和解析时间 -
--prefer-dist:强制走 ZIP 包而非 Git 克隆,避免容器内无git或 SSH 密钥导致失败 -
--optimize-autoloader(或-o):生成vendor/composer/autoload_classmap.php,让类加载从路径拼接 +file_exists()变成 O(1) 查表 -
--classmap-authoritative(或-a):告诉 autoloader “类不在 classmap 就真没有”,关闭 PSR-4 fallback 扫描,大幅降低冷启动 I/O
命令示例:composer install --no-dev --prefer-dist -o -a
多阶段构建中,第二阶段必须丢掉 composer 和 dev 工具
第一阶段用 php:8.3-cli-alpine 安装依赖,第二阶段用 php:8.3-fpm-alpine(或更轻的 php:8.3-fpm-slim-bookworm)只复制 vendor/、public/、.env 等运行时必需文件。常见错误包括:
立即学习“PHP免费学习笔记(深入)”;
在 Linux 上通过 Docker 运行 OpenClaw,并使用 Tailscale 实现远程访问。⚠️ 涉及 sudo、Docker、Tailscale和凭证挂载——请先查阅安全章节...
- 第二阶段仍保留
/usr/bin/composer—— 不仅增大镜像,还可能被误触发执行 - 没清掉
vendor/bin/下的 dev 工具(如phpunit、phpcs),它们会随 autoloader 加载,拖慢 OPcache 预热 - 没切换
USER www-data,导致vendor/权限不对,FPM worker 读不了文件
验证方式:进容器执行 ls -l /var/www/html/vendor/bin/,生产镜像里这里应该为空或只留极少数 runtime 工具(如 phinx)。
OPcache preload 配合 classmap-authoritative 才能发挥最大效果
opcache.preload 不是开了就快,它预加载的脚本必须能稳定命中 classmap。如果 autoloader 还开着 fallback(即没加 --classmap-authoritative),preload 会失效——因为 PHP 在预加载时无法确定哪些类最终会被用到,只能退回到运行时动态解析。
典型配置片段:
opcache.preload=/var/www/html/preload.php opcache.preload_user=www-data opcache.validate_timestamps=0 opcache.max_accelerated_files=20000
其中 preload.php 内容应直接 require 所有核心类文件,而不是 include vendor/autoload.php。更稳妥的做法是让 Composer 生成 preload 文件:composer dump-autoload --optimize --classmap-authoritative 后,再配合 opcache.preload 指向 vendor/composer/autoload_classmap.php 对应的映射逻辑(需自行封装)。
容易被忽略的一点:每次更新 vendor 后,必须重启 PHP-FPM 进程(或调用 opcache_reset()),否则 preload 仍加载旧版本字节码。


















