部署前必须关闭app_debug、正确配置nginx的try_files与php处理、迁移前备份并预检、用supervisor管理队列、用系统cron运行定时任务,且确保权限路径用户一致。

部署前必须关掉 APP_DEBUG
线上环境开着 APP_DEBUG=true 是最常见也最危险的疏忽——它会把数据库密码、路径、完整异常堆栈全打在页面上。Laravel 默认安装时这个值是 true,但生产环境必须硬性改为 false,且不能只改 .env:要确认 config/app.php 中的 debug 键最终解析结果确实是 false(Laravel 9+ 会优先读 .env,但缓存可能残留旧值)。
实操建议:
- 运行
php artisan config:clear清掉配置缓存,再用php artisan tinker输入config('app.debug')确认返回false - 检查 Web 服务器(Nginx/Apache)是否禁止了
.env文件被直接访问(Nginx 要加location ~ \.env { deny all; }) - 别把
.env提交到 Git —— 如果已提交,用git rm --cached .env移出版本控制并加进.gitignore
Nginx 配置里最容易漏的 try_files 规则
Laravel 是单入口应用,所有请求都得落到 public/index.php,但很多 Nginx 配置抄来就用,没验证过静态资源是否真能直出。典型症状:CSS/JS 404,但页面能打开;或者路由 404(比如访问 /login 返回 Nginx 默认 404 而不是 Laravel 的 404 页面)。
实操建议:
-
root必须指向/path/to/laravel/public,不是项目根目录 -
location /块里必须有try_files $uri $uri/ /index.php?$query_string;—— 少了$query_string,带参数的 URL(如?page=2)会丢参 - 额外加一段
location ~ \.php$,里面指定fastcgi_pass到 PHP-FPM socket 或端口,别漏掉fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;(否则$_SERVER['SCRIPT_FILENAME']会错)
php artisan migrate 在生产环境不能裸跑
上线新版本常要跑迁移,但直接在服务器上执行 php artisan migrate 风险极高:如果迁移失败,应用可能半途崩掉,而且没人知道 DB 到底改到哪一步了。更糟的是,有些迁移不可逆(比如删字段),也没法靠重试解决。
实操建议:
- 先在本地或预发环境完整跑一遍迁移,导出 SQL(
php artisan schema:dump --prune或用mysqldump备份后比对) - 上线时用
php artisan migrate --pretend看实际要执行哪些语句,确认无高危操作(DROP、MODIFY大表字段等) - 真正执行前,手动备份数据库(
mysqldump -u user db_name > backup_$(date +%s).sql),再加--force强制运行 - 如果用 Envoyer 或 Deployer 这类工具,确保迁移命令在「停服务 → 备份 → 迁移 → 清缓存 → 启服务」流程里,而不是随手 SSH 进去敲
队列和定时任务不能只靠 php artisan queue:work 手动启
很多人测试时在终端里跑 php artisan queue:work,上线后发现队列不消费、邮件不发、统计不更新——因为终端关闭或 SSH 断开,进程就死了。Laravel 官方从不推荐这种用法。
实操建议:
- 用 Supervisor 管理队列进程:写好
supervisord.conf配置,关键项包括autostart=true、autorestart=true、user=www-data(匹配 Web 服务器用户)、redirect_stderr=true - 定时任务必须用系统 cron,而不是
php artisan schedule:run手动调——在/etc/cron.d/下建文件,内容写死为* * * * * cd /var/www/myapp && php artisan schedule:run >> /dev/null 2>&1 - 检查队列驱动是否设为
redis或database,别用sync(同步模式)上线,它会让请求卡住等队列执行完
权限、路径、用户三者对不上是队列和定时任务静默失败的主因,别只盯着 Laravel 日志看,先查 Supervisor 日志和 systemctl status supervisor 输出。










