部署前必须清空配置缓存,执行php artisan config:clear和cache:clear后再config:cache;确保app_env=production且.env文件存在可读;检查路由缓存不支持闭包、视图缓存慎用动态@include;修正storage和bootstrap/cache权限;app_key首次部署生成后勿重复执行。

部署前必须清空配置缓存
刚从本地推到服务器就报 Class 'App\Providers\AppServiceProvider' not found?大概率是旧的配置缓存没清理。Laravel 在生产环境强制要求缓存配置,但如果你直接 php artisan config:cache 而没先清掉旧缓存,它会把本地开发时注册的调试类(比如 Barryvdh\Debugbar\ServiceProvider)也硬塞进缓存里——线上没装这个包,自然报错。
- 上线前务必执行
php artisan config:clear和php artisan cache:clear - 再运行
php artisan config:cache,它只读取config/下的 PHP 文件,不加载服务提供者 - 如果用了自定义配置文件(比如
config/custom.php),确认它已提交且没依赖未加载的类 - 缓存后
config('app.debug')仍返回true?说明.env里的APP_DEBUG=true没生效——检查.env是否被 Git 忽略、是否真在服务器上、权限是否允许 Web 用户读取
APP_ENV=production 不只是个开关
APP_ENV=production 直接影响日志行为、异常显示、缓存驱动选择。设成 local 却跑 config:cache,缓存文件里会混入开发专用配置(比如 log_level => 'debug'),线上日志瞬间爆炸。
- 必须在
.env中明确写死APP_ENV=production,不能靠服务器环境变量覆盖 - 验证方式:执行
php artisan tinker后输入app()->environment(),应返回"production" - 别在
config/app.php里用env('APP_ENV') === 'local'做分支逻辑——缓存后env()返回null,整个判断失效 - Log channel 默认切到
stack,但若没配channels.single.path,日志会写到storage/logs/laravel.log,确保该目录存在且 Web 用户有写权限
route:cache 和 view:cache 的适用边界
route:cache 只缓存控制器路由(Route::get('/user', [UserController::class, 'index'])),闭包路由(Route::get('/', function () { ... }))直接报错;view:cache 对 Blade 模板有效,但如果你用 @include($partial) 动态引入,缓存后变量名变成硬编码字符串,运行时报 Undefined variable。
- 执行
php artisan route:cache前,全局搜索项目里有没有function ()形式的路由定义 -
view:cache不需要每次部署都跑——Blade 编译缓存默认开启,只要storage/framework/views/可写,首次访问自动编译 - 如果用了
webpack.mix.js编译前端资源,确认npm run production已执行,且生成的public/mix-manifest.json在线上存在 - 缓存路由后改了控制器方法名?必须重新
route:cache,否则 404——它不监听文件变化
权限和所有权经常被忽略
Web 服务器(Nginx/Apache)以 www-data 或 nginx 用户运行,但部署脚本常用 root 或开发者账户执行,导致 storage/ 和 bootstrap/cache/ 下的文件所有者不对,缓存写入失败,错误日志里只有 file_put_contents(...): failed to open stream: Permission denied 这种模糊提示。
- 部署后立刻执行:
chown -R www-data:www-data storage/ bootstrap/cache/(Debian/Ubuntu)或chown -R nginx:nginx storage/ bootstrap/cache/(CentOS) - 别用
chmod 777临时解决——Laravel 官方明确反对,且可能触发安全扫描告警 - 如果用 Supervisor 管理队列,它的用户也要有
storage/写权限,否则queue:work启动失败却无日志 -
APP_KEY必须在首次部署时生成并写入.env,重复执行php artisan key:generate会导致已加密数据(如 Cookie、Session)全部失效
缓存不是一劳永逸的事,而是每次代码变更后要重新评估的环节——特别是加了新配置项、改了路由结构、或者换了服务器用户时,最容易卡在某个缓存没刷新干净。











