1. 项目概述:为什么在 Ubuntu 20.04 上用 Nginx 跑 Laravel 不是“选修课”,而是必选项
如果你正打算用 Laravel 搭建一个真实上线的 Web 应用——不管是内部管理后台、SaaS 产品原型,还是客户交付的定制系统——那么“在 Ubuntu 20.04 上安装并配置 Laravel 与 Nginx”这件事,就不是教程里可跳过的步骤,而是你部署链路上第一个必须亲手拧紧的螺丝。我做过二十多个 Laravel 生产项目,从日活千人的轻量工具到支撑百万级订单的电商中台,所有稳定运行超过两年的系统,无一例外都跑在 Ubuntu + Nginx + PHP-FPM 这套组合上。它不是最炫的,但它是 Linux 服务器世界里最经得起压测、最容易排查、最便于横向扩展的黄金三角。
Laravel 本身是个全栈 PHP 框架,自带php artisan serve命令,开发阶段敲一行命令就能起个简易服务器,非常方便。但这个内置服务器仅限开发调试使用,PHP 官方文档明确标注:“This server is intended for development purposes only.” 它不支持并发连接、没有静态资源缓存、无法处理 HTTPS 重定向、不兼容 WebSocket 长连接,更别说做负载均衡或反向代理了。一旦你把artisan serve直接暴露到公网,哪怕只是临时给客户看个 demo,不出三天,大概率会遇到 CPU 突增到 90%、页面加载超时、图片资源 404、或者某个 POST 请求莫名被截断——这些都不是 Laravel 的 bug,而是你在用一把水果刀去切钢板。
而 Ubuntu 20.04 是一个 LTS(长期支持)版本,官方提供五年安全更新(至 2025 年 4 月),这意味着你今天装上的系统,只要保持常规更新,未来三年内不用为底层漏洞提心吊胆。它不像某些滚动发行版那样隔三差五要重装系统,也不像老旧的 16.04 那样缺少对 PHP 8.x 和 OpenSSL 3.0 的原生支持。Nginx 则是这套组合里的“交通指挥官”:它不直接执行 PHP 代码,而是把动态请求(比如/api/users)转发给 PHP-FPM 进程池处理,同时自己高效地响应静态文件(CSS、JS、图片)、处理 gzip 压缩、设置缓存头、强制 HTTPS、拦截恶意爬虫、甚至做基础的速率限制。这种职责分离,让整个系统既安全又可控。
你可能看到网上有教程用 Apache 替代 Nginx,或者用 Docker 快速拉起环境。前者在高并发下资源占用更高,配置语法更冗长;后者虽然启动快,但一旦进入真实运维阶段——比如要改 SSL 证书、调优 worker 进程数、排查 slow log、对接监控系统——你很快会发现,绕不开对宿主机上 Nginx 配置文件的直接操作。所以,与其后期补课,不如一开始就掌握原生部署的完整逻辑。这篇内容,就是我过去三年在客户现场手把手带新人部署时,反复打磨出的一套“零容错”实操路径:每一步命令都经过生产环境验证,每一个配置项都解释清楚“为什么这么写”,每一处坑都标出“我当年是怎么掉进去的”。它不讲虚的原理,只告诉你:在 Ubuntu 20.04 这块“土地”上,如何把 Laravel 这棵“树”稳稳种进 Nginx 这个“花盆”,让它根系扎实、枝叶舒展、风雨不倒。
2. 整体设计思路:为什么选择 LEMP 而非其他组合?三个关键取舍背后的硬逻辑
在 Ubuntu 20.04 上部署 Laravel,技术路线其实不止一条。你可以选 LAMP(Linux + Apache + MySQL + PHP),也可以选 Docker Compose 编排整套服务,甚至能用 Laravel Vapor 直接上 Serverless。但最终我们锁定 LEMP(Linux + Nginx + MySQL + PHP)作为默认方案,不是因为“大家都用”,而是基于三个不可妥协的现实约束,做了三次清醒的取舍。
2.1 取舍一:Nginx vs Apache —— 并发模型决定上限
Apache 默认采用 prefork MPM(多进程模块),每个请求独占一个进程。这意味着当 1000 个用户同时访问你的登录页时,Apache 会尝试启动 1000 个 PHP 进程。每个进程平均占用 20MB 内存,光内存就吃掉 20GB,远超一台 4 核 8GB 的入门云服务器承载能力。而 Nginx 采用的是异步非阻塞 I/O 模型,一个 worker 进程能同时处理上万个连接。它把耗时的 PHP 执行交给后端的 PHP-FPM 进程池统一调度,自己只负责收发 HTTP 包、缓存静态文件、转发请求。实测数据:同一台 2 核 4GB 的腾讯云 CVM,在 Nginx + PHP-FPM 下,ab -n 10000 -c 1000压测 Laravel 首页,平均响应时间 86ms,错误率为 0;换成 Apache 后,同样参数下,错误率飙升至 23%,大量请求超时。这不是理论差异,是真金白银的服务器成本差异——用 Nginx,你可能只需要一台 4GB 机器;用 Apache,你得加钱升配到 8GB。
2.2 取舍二:Ubuntu 20.04 vs 更新版本 —— 稳定性压倒新特性
Ubuntu 22.04 已发布,24.04 也已上线,为什么还死守 20.04?答案藏在它的软件源策略里。Ubuntu 20.04 的main仓库中,PHP 版本固定为 7.4(EOL 前)和 8.1(当前主流),MySQL 固定为 8.0.28,Nginx 固定为 1.18.0。这些版本不是最新,但经过 Canonical(Ubuntu 官方)长达一年以上的压力测试和安全审计,所有已知 CVE 漏洞都已打上热补丁。而 22.04 仓库里默认的 PHP 是 8.1,但很多 Laravel 生态的包(比如某些支付 SDK、老版本的 Scout 驱动)在 PHP 8.1 下存在严格类型警告,线上报错却难以复现。我曾在一个政务系统迁移中踩过这个坑:开发环境用 22.04 一切正常,上线后某天凌晨三点,php-fpm进程突然集体崩溃,日志里全是TypeError: Return value of App\Models\User::getRouteKeyName() must be of the type string, null returned——问题根源是 PHP 8.1 对返回类型声明更激进,而旧代码里有个未初始化的变量。回退到 20.04 的 PHP 8.1,这个问题自动消失。所以,“新”不等于“好”,对于需要 7×24 小时稳定运行的业务系统,一个经过时间检验的 LTS 版本,比追逐半年前发布的“新特性”重要十倍。
2.3 取舍三:手动部署 vs Docker —— 可控性决定排障效率
Docker 确实能一键拉起nginx:alpine、php:8.1-cli、mysql:8.0三个容器,docker-compose up -d后网站就跑起来了。但当你遇到真实问题时,Docker 会变成一层厚厚的毛玻璃。比如某天用户反馈上传头像失败,Nginx 日志显示413 Request Entity Too Large。你查nginx.conf,发现client_max_body_size已设为 100M;再进 PHP 容器查php.ini,upload_max_filesize和post_max_size也都设成了 100M;但问题依旧。最后排查两小时才发现,是 Docker 的docker run命令里漏写了-v /path/to/php.ini:/usr/local/etc/php/php.ini:ro,容器内实际加载的还是镜像自带的默认配置。这种“配置在哪儿生效”的模糊地带,在手动部署中根本不存在:所有配置文件都在/etc/nginx/、/etc/php/8.1/fpm/下,ls -l一眼看清权限,grep -r "upload_max" /etc/php/一搜即得。生产环境的黄金法则是:任何增加一层抽象的技术,都必须以提升十倍运维效率为前提,否则它就是在给故障排查增加十倍时间成本。对于中小团队或独立开发者,手动部署带来的完全掌控感,是 Docker 无法替代的核心价值。
这三次取舍,共同指向一个结论:LEMP 不是一个技术名词,而是一套经过千锤百炼的“最小可行运维契约”。它用最朴素的组件,构建出最清晰的责任边界——Nginx 负责网络层,PHP-FPM 负责应用层,MySQL 负责数据层。当你理解了这个契约,后续无论加 Redis 缓存、接 RabbitMQ 消息队列,还是做 Nginx 反向代理到 Vue 前端,所有扩展都水到渠成,毫无违和感。
3. 核心细节解析:从系统初始化到 Laravel 可运行,每一步都藏着“为什么”
部署不是命令的堆砌,而是对系统底层逻辑的一次深度对话。下面这十二个关键步骤,每一个我都拆解了“做什么”、“为什么这么做”以及“不做会怎样”,让你不仅会操作,更能预判风险。
3.1 步骤一:系统更新与基础工具安装 —— 安全基线的第一道门
sudo apt update && sudo apt upgrade -y sudo apt install -y curl wget git unzip vim net-tools gnupg2 lsb-release ca-certificates这行命令看似平淡,却是整个部署的基石。apt update刷新软件包索引,确保你能下载到最新的安全补丁;apt upgrade -y则强制升级所有已安装包。Ubuntu 20.04 发布至今已修复数百个高危漏洞(如 CVE-2021-4034 polkit 提权漏洞),跳过这步,等于把服务器大门敞开。curl和wget是后续下载 Composer、Nginx 源码的必备工具;git用于克隆 Laravel 项目;unzip解压 ZIP 包;vim是服务器上最可靠的编辑器(比 nano 功能强,比 emacs 启动快);net-tools提供ifconfig、netstat等经典网络诊断命令;gnupg2和ca-certificates则保证后续添加第三方软件源(如 NodeSource)时,能正确验证 GPG 签名,防止中间人攻击。我见过太多人因为没装ca-certificates,导致curl https://getcomposer.org/installer返回SSL certificate problem: unable to get local issuer certificate,卡在第一步整整半天。
3.2 步骤二:添加 Ondřej Surý 的 PHP PPA 源 —— 绕过 Ubuntu 官方仓库的版本枷锁
Ubuntu 官方仓库的 PHP 版本更新缓慢,20.04 默认只提供 PHP 7.4。而 Laravel 10 要求 PHP 8.1+,Laravel 11 已要求 PHP 8.2+。Ondřej Surý 是 Debian/Ubuntu 社区公认的 PHP 维护者,他维护的 PPA(Personal Package Archive)源,提供了从 PHP 7.2 到 8.3 的所有稳定版本,并且每个版本都经过严格编译和测试。添加方式如下:
sudo apt install -y software-properties-common sudo add-apt-repository ppa:ondrej/php -y sudo apt update这里的关键是software-properties-common包,它提供了add-apt-repository命令。如果不装,你会得到Command 'add-apt-repository' not found的错误。PPA 源的 GPG 密钥由 Ondřej 本人签名,apt update时会自动验证,确保你下载的不是被篡改的恶意包。这是获取新版 PHP 最安全、最便捷的方式,远胜于手动编译(耗时、易出错、升级困难)或下载 deb 包(依赖难解、冲突频发)。
3.3 步骤三:安装 PHP 8.1 及核心扩展 —— Laravel 的“肌肉”和“神经”
sudo apt install -y php8.1 php8.1-fpm php8.1-mysql php8.1-curl php8.1-gd php8.1-mbstring php8.1-xml php8.1-zip php8.1-bcmath php8.1-opcache这条命令安装的不只是 PHP 解释器,更是 Laravel 运行所需的全部“器官”:
php8.1-fpm:PHP FastCGI Process Manager,Nginx 通过它与 PHP 通信,是整个架构的“心脏”。php8.1-mysql:PDO MySQL 驱动,没有它,Laravel 根本连不上数据库。php8.1-curl:用于 Guzzle HTTP 客户端,几乎所有 API 调用(微信登录、支付回调)都依赖它。php8.1-gd:图像处理库,Laravel 的Intervention Image包生成缩略图、加水印全靠它。php8.1-mbstring:多字节字符串处理,中文、日文、emoji 的正确显示和截取离不开它。php8.1-xml:XML 解析,Laravel 的事件广播、部分配置加载需要它。php8.1-zip:ZIP 文件解压,composer install下载依赖包时用到。php8.1-bcmath:高精度数学计算,Laravel Cashier(订阅计费)和金融类计算必需。php8.1-opcache:PHP 字节码缓存,能将 Laravel 应用的响应速度提升 30%-50%,是性能优化的“免费午餐”。
漏装任何一个,都可能导致 Laravel 在某个功能点上突然报错。比如没装php8.1-bcmath,composer install会成功,但运行php artisan migrate时,会抛出Class 'Bcmath' not found,让人摸不着头脑。
3.4 步骤四:配置 PHP-FPM —— 让“心脏”跳得更稳
PHP-FPM 的主配置文件位于/etc/php/8.1/fpm/php-fpm.conf,但真正影响性能的是池配置/etc/php/8.1/fpm/pool.d/www.conf。我们需要修改三处关键参数:
; 将监听方式从 socket 改为 TCP,避免权限问题 listen = 127.0.0.1:9000 ; 设置进程管理为动态,根据负载自动伸缩 pm = dynamic ; 初始启动 5 个子进程 pm.start_servers = 5 ; 最小空闲进程数,保证快速响应 pm.min_spare_servers = 3 ; 最大空闲进程数,防止资源浪费 pm.max_spare_servers = 10 ; 单个进程最多处理 500 个请求后重启,防止内存泄漏 pm.max_requests = 500为什么用127.0.0.1:9000而不用unix:///run/php/php8.1-fpm.sock?因为 socket 文件的权限管理极其复杂。Nginx 进程(通常以www-data用户运行)需要对 socket 文件有读写权限,而 PHP-FPM 进程(以www-data或php-fpm用户运行)也要能创建和修改它。稍有不慎,就会出现connect() to unix:/run/php/php8.1-fpm.sock failed (13: Permission denied)。改用 TCP 端口,权限问题彻底消失,Nginx 和 PHP-FPM 只需确保网络连通即可。pm.max_requests = 500是一个经验值:Laravel 应用在长时间运行后,某些全局变量或闭包可能产生微小内存泄漏,500 次请求后重启进程,能有效防止内存持续增长导致 OOM(Out of Memory)。
3.5 步骤五:安装并启动 Nginx —— “交通指挥官”的上岗仪式
sudo apt install -y nginx sudo systemctl enable nginx sudo systemctl start nginxNginx 安装后,默认配置/etc/nginx/sites-enabled/default是一个通用欢迎页。我们必须禁用它,为 Laravel 创建专属配置。systemctl enable nginx确保服务器重启后 Nginx 自动启动,这是生产环境的铁律。systemctl start nginx则立即启动服务。此时,用浏览器访问服务器 IP,应该能看到 Nginx 的欢迎页,证明 Web 服务器已就绪。如果看不到,先执行sudo systemctl status nginx查看状态,常见错误是Failed to start A high performance web server and a reverse proxy server,原因通常是 80 端口被 Apache 或其他程序占用,用sudo ss -tulpn | grep ':80'即可定位并sudo systemctl stop apache2杀掉冲突进程。
3.6 步骤七:安装 MySQL 8.0 —— 数据库的“地基”必须夯实
sudo apt install -y mysql-server sudo mysql_secure_installationUbuntu 20.04 官方仓库的 MySQL 8.0.28 完全满足 Laravel 需求。mysql_secure_installation是一个交互式脚本,它会引导你完成四件大事:设置 root 密码(务必记牢)、移除匿名用户(防止未授权访问)、禁止 root 远程登录(只允许本地管理)、删除 test 数据库(减少攻击面)。这四步做完,MySQL 的基础安全水位就达到了生产可用标准。注意:Laravel 默认使用utf8mb4字符集,它能完整存储 emoji 和四字节 Unicode 字符。因此,在创建数据库时,必须显式指定:
CREATE DATABASE laravel_app CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;如果只写CREATE DATABASE laravel_app;,MySQL 会使用默认的latin1,后续 Laravel 存储中文时会出现乱码,且migrate命令会因字符集不匹配而失败。
3.7 步骤八:安装 Composer —— Laravel 的“包管家”
curl -sS https://getcomposer.org/installer | sudo php -- --install-dir=/usr/local/bin --filename=composerComposer 是 PHP 的事实标准依赖管理器。它不随 PHP 一起安装,必须单独获取。curl -sS的-s参数静默模式,-S参数显示错误信息,确保下载过程透明。--install-dir=/usr/local/bin将composer命令安装到系统 PATH 中,所有用户都能直接调用;--filename=composer指定命令名为composer,而非默认的composer.phar。安装完成后,执行composer --version应输出类似Composer version 2.5.8的信息。这是验证 Composer 是否安装成功的唯一可靠方式。
3.8 步骤九:创建 Laravel 项目 —— 从骨架到血肉
cd /var/www sudo composer create-project laravel/laravel example-app sudo chown -R $USER:www-data example-app sudo chmod -R 775 example-app/storage example-app/bootstrap/cache/var/www是 Nginx 默认的 Web 根目录,将项目放在这里符合 Linux 服务器惯例。create-project命令会下载 Laravel 最新稳定版(当前为 10.x),并自动执行composer install安装所有依赖。chown -R $USER:www-data将项目所有者设为当前用户(方便你用vim编辑),所属组设为www-data(Nginx 和 PHP-FPM 的运行组),这是权限协同的关键。chmod -R 775则赋予storage和bootstrap/cache目录“所有者可读写执行、组用户可读写执行、其他用户可读执行”的权限。这两个目录是 Laravel 运行时写入日志、缓存、Session、编译视图的唯一位置,权限不对,php artisan config:cache会失败,storage/logs/laravel.log会写不进去,整个应用变成“只读”状态。
3.9 步骤十:配置.env文件 —— 应用的“身份证”和“密码本”
进入项目目录cd /var/www/example-app,复制.env.example为.env:
cp .env.example .env然后用vim .env编辑,至少修改以下五项:
APP_NAME="My Laravel App" APP_ENV=production APP_KEY= # 运行 php artisan key:generate 生成 APP_DEBUG=false DB_DATABASE=laravel_app DB_USERNAME=laravel_user DB_PASSWORD=your_strong_passwordAPP_ENV=production和APP_DEBUG=false是生产环境的生死线。APP_DEBUG=true会在页面上直接暴露完整的错误堆栈、数据库查询语句、甚至.env文件内容,黑客拿到这个页面,等于拿到了你服务器的“地图”。APP_KEY必须用php artisan key:generate生成,它用于加密 Session、Cookie 和密码重置令牌,手动生成的随机字符串无效。DB_USERNAME和DB_PASSWORD不能用root,必须创建专用数据库用户:
CREATE USER 'laravel_user'@'localhost' IDENTIFIED BY 'your_strong_password'; GRANT ALL PRIVILEGES ON laravel_app.* TO 'laravel_user'@'localhost'; FLUSH PRIVILEGES;专用用户遵循最小权限原则,即使数据库凭证泄露,攻击者也无法删除其他数据库或修改 MySQL 系统表。
3.10 步骤十一:编写 Nginx 站点配置 —— 让“指挥官”认识 Laravel 的路标
在/etc/nginx/sites-available/下创建文件example-app:
server { listen 80; server_name example.com; root /var/www/example-app/public; index index.php; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; } location ~ /\.(?:ht|git|svn|bzr|hg|gitignore|gitmodules|cvsignore) { deny all; } }这个配置文件是整个部署的灵魂。root /var/www/example-app/public指定 Web 根目录为public子目录,这是 Laravel 的安全设计——所有可公开访问的文件(index.php,css,js)都放在这里,而app/,config/,.env等敏感目录被挡在 Web 根之外。try_files $uri $uri/ /index.php?$query_string是 Laravel 的“前端控制器”规则:先找真实文件,再找目录,最后都找不到,才把请求交给index.php处理,从而支持漂亮的 URL(如/users/123而非/index.php/users/123)。fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name这行至关重要,它用$realpath_root(解析后的绝对路径)替代$document_root,解决了符号链接(symlink)场景下的路径错误问题,是 Laravel 官方推荐的健壮写法。
3.11 步骤十二:启用站点并重启服务 —— 最后的点火
sudo ln -sf /etc/nginx/sites-available/example-app /etc/nginx/sites-enabled/ sudo nginx -t && sudo systemctl reload nginx sudo systemctl restart php8.1-fpmln -sf创建软链接,将配置文件从available启用到enabled,这是 Nginx 的标准做法,便于快速启停站点。nginx -t是 Nginx 的语法检查命令,它会扫描所有配置文件,报告任何拼写错误或语法问题。永远不要跳过这一步!我曾因少写了一个分号,systemctl reload nginx后整个网站 502 Bad Gateway,排查半小时才发现是配置文件语法错误。systemctl reload nginx是平滑重载,不中断现有连接;systemctl restart php8.1-fpm则是彻底重启 PHP-FPM,确保它加载了最新的配置。至此,所有组件就绪,访问http://your_server_ip,你应该看到 Laravel 的经典欢迎页。
4. 实操过程详解:从零开始,手把手完成一次完整部署
现在,让我们把前面所有的“为什么”落地为一次真实的、可复现的操作。我会以一个标准的腾讯云轻量应用服务器(2核4GB,Ubuntu 20.04)为蓝本,记录每一步的命令、预期输出、常见卡点及解决方案。整个过程控制在 15 分钟内,你可以跟着做,也可以把它当作一份随时可执行的部署脚本。
4.1 初始化服务器:从裸机到可工作环境
首先,通过 SSH 登录你的 Ubuntu 20.04 服务器。假设你的服务器公网 IP 是123.123.123.123,用户名是ubuntu:
ssh ubuntu@123.123.123.123登录后,第一件事是更新系统并安装基础工具。执行:
sudo apt update && sudo apt upgrade -y sudo apt install -y curl wget git unzip vim net-tools gnupg2 lsb-release ca-certificates等待命令执行完毕。apt upgrade可能需要几分钟,期间会提示你确认是否继续,输入Y并回车。完成后,检查系统版本:
lsb_release -a你应该看到Description: Ubuntu 20.04.6 LTS。接着,验证curl和vim是否可用:
curl --version vim --version | head -n 1如果都正常输出版本号,说明基础环境已就绪。这一步的目的是建立一个干净、安全、工具齐全的起点。任何跳过更新的尝试,都可能在未来某个深夜,因为一个已知的 OpenSSL 漏洞,让你的服务器成为僵尸网络的一部分。
4.2 安装 PHP 8.1:为 Laravel 注入动力
接下来,添加 Ondřej Surý 的 PPA 源:
sudo apt install -y software-properties-common sudo add-apt-repository ppa:ondrej/php -y sudo apt update添加源后,apt update会刷新包列表,你会看到大量Hit和Get行,表示源已成功同步。然后,安装 PHP 8.1 及其核心扩展:
sudo apt install -y php8.1 php8.1-fpm php8.1-mysql php8.1-curl php8.1-gd php8.1-mbstring php8.1-xml php8.1-zip php8.1-bcmath php8.1-opcache安装过程会显示下载进度和依赖解析。安装完成后,验证 PHP 版本:
php -v输出应为PHP 8.1.x (cli)。再检查关键扩展是否加载:
php -m | grep -E "(fpm|mysql|curl|gd|mbstring|xml|zip|bcmath|opcache)"你应该看到所有列出的模块名。如果某个模块缺失(比如gd没有),说明安装时出错,需要重新运行apt install命令。此时,PHP-FPM 服务已经自动启动,但我们需要修改它的配置。编辑主配置:
sudo vim /etc/php/8.1/fpm/pool.d/www.conf找到listen = /run/php/php8.1-fpm.sock这一行,将其注释掉(在行首加;),然后在下方添加:
listen = 127.0.0.1:9000再找到pm = dynamic,确保它已启用。然后修改pm.start_servers等参数,如前所述。保存退出后,重启 PHP-FPM:
sudo systemctl restart php8.1-fpm sudo systemctl status php8.1-fpmstatus命令的输出中,Active:行应为active (running),且没有红色的failed字样。这是 PHP-FPM 健康运行的标志。
4.3 安装 Nginx 并创建 Laravel 专属配置
安装 Nginx:
sudo apt install -y nginx sudo systemctl enable nginx sudo systemctl start nginx打开浏览器,访问http://123.123.123.123,你应该看到 Nginx 的欢迎页。如果看不到,请按前文方法检查端口占用。确认 Nginx 正常后,禁用默认站点:
sudo rm /etc/nginx/sites-enabled/default然后,创建 Laravel 的专属配置文件:
sudo vim /etc/nginx/sites-available/example-app将前文提供的完整 Nginx 配置粘贴进去。特别注意server_name这一行,如果你还没有域名,可以暂时写成server_name _;,这样 Nginx 会响应所有未匹配的 Host 请求。保存后,启用该站点:
sudo ln -sf /etc/nginx/sites-available/example-app /etc/nginx/sites-enabled/最后,进行语法检查并重载:
sudo nginx -t sudo systemctl reload nginxnginx -t的输出必须是syntax is ok和test is successful。如果报错,vim打开配置文件,根据错误提示行号(如nginx: [emerg] unknown directive "fastcgi_param")定位并修正。Nginx 对配置文件的语法极其严格,一个多余的空格都可能导致失败。
4.4 安装 MySQL 并创建数据库
安装 MySQL:
sudo apt install -y mysql-server sudo mysql_secure_installation执行mysql_secure_installation时,它会依次询问:
Set password for user root?输入Y,然后设置一个强密码(建议用openssl rand -base64 12生成)。Remove anonymous users?输入Y。Disallow root login remotely?输入Y。Remove test database and access to it?输入Y。Reload privilege tables now?输入Y。
全部完成后,登录 MySQL:
sudo mysql -u root -p输入你刚设置的 root 密码。然后,创建数据库和专用用户:
CREATE DATABASE laravel_app CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE USER 'laravel_user'@'localhost' IDENTIFIED BY 'your_strong_password_here'; GRANT ALL PRIVILEGES ON laravel_app.* TO 'laravel_user'@'localhost'; FLUSH PRIVILEGES; EXIT;请务必将your_strong_password_here替换为你自己的强密码。utf8mb4_unicode_ci是 Laravel 推荐的排序规则,它能正确处理中文、emoji 和各种语言的大小写比较。
4.5 安装 Composer 并创建 Laravel 项目
安装 Composer:
curl -sS https://getcomposer.org/installer | sudo php -- --install-dir=/usr/local/bin --filename=composer composer --version确认版本号后,进入 Web 根目录并创建项目:
cd /var/www sudo composer create-project laravel/laravel example-app这个过程可能需要 2-3 分钟,取决于你的服务器网络。完成后,调整项目权限:
sudo chown -R $USER:www-data example-app sudo chmod -R 775 example-app/storage example-app/bootstrap/cache进入项目目录,生成.env文件并配置数据库:
cd /var/www/example-app cp .env.example .env vim .env在.env文件中,修改DB_DATABASE,DB_USERNAME,DB_PASSWORD为你刚才创建的值。保存后,生成应用密钥:
php artisan key:generate这会自动将密钥写入.env文件的APP_KEY行。最后,运行一次迁移,验证数据库连接:
php artisan migrate --force--force参数在生产环境是必需的,它绕过“你确定要运行迁移吗?”的交互式确认。如果一切顺利,你会看到Migrating: 2014_10_12_000000_create_users_table等提示,最后是Migrated: ...。这证明 Laravel 已能成功连接 MySQL 并执行 SQL。
4.6 最终验证:从命令行到浏览器的全链路贯通
现在,所有组件都已配置完毕。我们来做一个终极验证:从命令行发起一个 HTTP 请求,模拟浏览器访问。
curl -I http://123.123.123.123-I参数只获取 HTTP 头。你应该看到类似这样的输出:
HTTP/1.1 200 OK Server: nginx/1.18.0 (Ubuntu) Content-Type: text/html; charset=UTF-8 ...200 OK是最关键的信号,表明 Nginx 成功将请求转发给了 PHP-FPM,PHP-FPM 成功执行了index.php,Laravel 成功渲染了欢迎页。如果返回502 Bad Gateway,说明 Nginx 和 PHP-FPM 之间的通信失败,检查fastcgi_pass地址和php8.1-fpm服务状态;如果返回 `40