生产环境部署laravel必须严格设置app_debug=false、nginx root指向public目录并配置try_files和pathinfo、执行composer install --no-dev --optimize-autoloader、正确设置storage和bootstrap/cache权限、按序运行php artisan config:cache等缓存命令,缺一不可。

APP_DEBUG=false 必须在首次访问前设好,否则调试信息会直接暴露在页面上,且部分缓存命令(如 config:cache)会因环境未识别为 production 而拒绝执行。
nginx 配置必须指向 public 目录,且启用 pathinfo 或 rewrite
直接把 root 设成项目根目录会导致 .env 文件被 Web 服务器直接读取返回,构成严重安全风险。Nginx 必须将 root 指向 public/ 子目录,并正确处理 PHP 路由转发。
常见错误配置:
- root 指向
/var/www/myapp(错)→ 应该是/var/www/myapp/public - 漏掉
try_files $uri $uri/ /index.php?$query_string;→ 导致除首页外所有路由 404 - 没启用
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;→ 触发 “No input file specified” 错误
LNMP 用户注意:enable-php-pathinfo.conf 必须启用,否则 Laravel 的路由参数(如 /user/{id})无法被正确解析。
composer install --no-dev --optimize-autoloader 缺一不可
开发依赖(如 phpunit、laravel/pint)留在生产环境不仅浪费内存和磁盘,还可能引入未审计的代码执行路径。--optimize-autoloader 会生成更高效的 classmap,避免运行时遍历整个 vendor/ 目录。
容易踩的坑:
- 用
composer update替代install→ 可能升级到不兼容版本,破坏 lock 文件一致性 - 漏掉
--no-dev→php -m可能报出Class 'PHPUnit\Framework\TestCase' not found等异常 - 在非 root 用户下运行,导致
vendor/权限混乱 → 后续php artisan命令报 permission denied
storage 和 bootstrap/cache 目录权限必须由 web server 用户可写
Laravel 运行时要往 storage/logs/ 写日志、storage/framework/views/ 编译模板、bootstrap/cache/config.php 存缓存文件。如果 www-data(Ubuntu)或 nginx(CentOS)用户没有写权限,会静默失败或报 file_put_contents(): Failed to open stream: Permission denied。
正确操作顺序:
- 先
chown -R $USER:www-data storage bootstrap/cache - 再
chmod -R 775 storage bootstrap/cache(不要用 777,尤其上线后) - 确保
storage/app/下上传文件目录(如 avatar/)也继承相同权限 - 若用 SELinux(如 CentOS),还需
chcon -R -t httpd_sys_rw_content_t storage/
缓存命令必须按顺序执行,且不能跳过 config:cache
php artisan config:cache 是其他缓存命令的前提:它把所有 config/*.php 合并为单个 PHP 数组文件,并强制后续所有配置读取该缓存。如果跳过这步,route:cache 会读到未合并的原始配置,导致中间件、域名约束等失效。
推荐执行顺序:
-
php artisan config:cache(必须第一) -
php artisan route:cache(仅适用于非闭包路由) -
php artisan view:cache(预编译 Blade 模板,减少首次访问延迟) -
php artisan event:cache(Laravel 10+,可选)
注意:config:cache 会忽略 .env 中未通过 env() 函数读取的变量;所有环境相关逻辑必须显式写进 config 文件里,比如 'redis' => ['host' => env('REDIS_HOST', '127.0.0.1')] 才有效。
chown,就可能让 view:cache 生成的文件无法被 Web 进程读取;漏掉一次 config:cache,整个路由缓存就形同虚设。这些不是“可选优化”,而是生产环境能跑起来的底线。











