post-install-cmd在生产环境默认不执行,因--no-dev禁用dev相关逻辑,需显式添加--no-scripts以外的参数;脚本须定义在composer.json根级scripts下,命名严格匹配事件名,且需验证是否注册成功。

部署时 composer install 看似跑通了,但缓存没清、权限不对、配置没生效——根本不是命令没执行,而是脚本压根没触发,或触发了却在错误上下文里失败。
post-install-cmd 为什么本地能跑,上线就静默跳过?
生产环境默认禁用所有 dev 相关逻辑,包括 post-install-cmd 这类钩子。它不是“被忽略”,而是根本不会加载进执行队列。
- 必须显式加
--no-dev同时确保没加--no-scripts(后者会直接关掉所有脚本) -
post-install-cmd只在composer install成功后触发;若install因缺少composer.lock或权限问题中途退出,脚本连启动机会都没有 - CI/CD 环境中常设
COMPOSER_NO_INTERACTION=1,这本身不影响脚本,但若脚本里有交互式命令(如php artisan key:generate --force),得补--force或等价参数
scripts 字段写在哪、怎么命名才有效?
脚本必须定义在 composer.json 的最外层 scripts 键下,缩进错一级、塞进 extra 或 config 里,全都不生效。
- 事件钩子名严格固定:
post-install-cmd、post-update-cmd、post-root-package-install—— 多一个空格、少一个短横线都无效 - 自定义脚本名(如
deploy:clear-cache)不能自动触发,必须用composer run deploy:clear-cache显式调用 - 验证是否注册成功:运行
composer run --list,看到你的脚本名才说明解析正确
权限和路径问题怎么避开?
脚本运行时的当前工作目录是 composer.json 所在路径,但 PHP CLI 的 user、umask、open_basedir 都可能和 Web 用户不一致,导致 chmod 失败或 php artisan 报 Permission denied。
- 别写
chmod -R 755 storage,改用 PHP 脚本做判断:@php -r "is_writable('storage') ?: mkdir('storage', 0755, true);" - 调用 Artisan 命令时,统一用
php ./artisan(相对路径),而非php artisan(依赖 PATH) - 避免硬编码
/var/www/html这类绝对路径;要用${PWD}或$(pwd)动态锚定
部署命令怎么组合才安全?
把所有动作塞进一个 post-install-cmd 数组里看着省事,但任意一步失败,后续全中断,且无法单独重试。
- 拆成原子脚本:
"clear-cache": "php ./artisan cache:clear"、"set-perms": "@php scripts/set-perms.php" - 主部署流程用
"deploy": ["@clear-cache", "@set-perms", "@php ./artisan config:cache"],失败时可定位到具体步骤 - 生产环境务必加
--optimize-autoloader和--no-dev,否则vendor/autoload.php加载慢,且可能意外引入phpunit等开发工具
最容易被忽略的是:脚本里调用的 PHP 类,不会自动加载 vendor/autoload.php。哪怕你只写一行 @php -r "new Illuminate\Foundation\Application();",也得先 require __DIR__ . '/vendor/autoload.php';,否则直接报错——这个细节在内联 -r 脚本里根本藏不住。











