1. 项目概述:在 Ubuntu 20.04 上亲手搭起一个能跑 PHP 网站的 LEMP 环境
你是不是也经历过这样的场景:刚买了一台云服务器,或者在 VMware 里装好 Ubuntu 20.04,满心欢喜想部署一个 WordPress、Typecho 或者自己写的 PHP 后台,结果打开浏览器只看到 “Welcome to nginx!”——页面是活的,但你的代码压根没跑起来?别急,这不是你不会写 PHP,而是少了一整套“让 PHP 在 Linux 上真正干活”的基础设施。这个标题说的 LEMP(Linux + Nginx + MySQL + PHP),就是 Web 开发和运维领域最经典、最轻量、也最考验基本功的一套组合拳。它不是什么高深莫测的黑科技,而是一套被全球数百万网站验证过的、稳定可靠的运行底座。Linux 是操作系统根基,Nginx 是那个站在最前面、高效处理用户请求的“门卫”,MySQL 是默默存着你所有用户数据、订单信息的“保险柜”,PHP 则是连接前后端、把数据库里的数据变成网页内容的“翻译官”。这四者环环相扣,缺一不可。我带过不少刚从学校出来的新人,他们 PHP 语法背得滚瓜烂熟,一到真实环境就卡在“为什么我的 index.php 打不开”上,问题往往出在 Nginx 没配对 PHP 的通信方式,或者 MySQL 的 root 密码设错了却不知道怎么重置。这篇内容,就是为你把这套流程掰开揉碎,不讲虚的理论,只讲你在终端里敲下的每一行命令背后到底发生了什么,以及为什么必须这么敲。无论你是想快速上线一个个人博客,还是为公司内部系统搭建测试环境,甚至只是想彻底搞懂自己每天打交道的服务器是怎么工作的,这篇实操指南都值得你从头到尾跟着走一遍。它不依赖任何图形界面,全程在命令行完成,确保你在任何一台纯净的 Ubuntu 20.04 机器上——无论是物理机、虚拟机,还是 WSL2 里的子系统——都能复现成功。
2. 整体设计思路与方案选型逻辑
2.1 为什么是 LEMP,而不是 LAMP?
在 Ubuntu 20.04 这个时间点上,选择 Nginx 而非 Apache 作为 Web 服务器,绝不是为了赶时髦。这背后有非常实在的性能和运维逻辑。Apache 采用的是“进程/线程模型”,每个用户请求都会占用一个独立的进程或线程。当并发量不大时,它很稳;但一旦遇到流量高峰,比如你发了一篇爆款文章,瞬间几百人同时访问,Apache 就会疯狂 fork 新进程,内存和 CPU 使用率会像坐火箭一样飙升,服务器可能直接卡死。而 Nginx 用的是“事件驱动、异步非阻塞”的模型,它就像一个经验老道的餐厅领班,手里只有一支笔(单个主线程),却能同时盯住几十张桌子(成千上万个连接)。客人点菜(HTTP 请求)来了,它记下需求,转头就去招呼下一位,等厨房(后端 PHP 处理)做好了,再把菜(响应)端给对应的客人。这种设计让 Nginx 在处理静态文件(图片、CSS、JS)时效率极高,内存占用极低。我曾经在一个只有 1GB 内存的 VPS 上,用 Nginx + PHP-FPM 跑了三个 WordPress 站点,CPU 平均负载长期维持在 0.1 以下;换成 Apache 后,同样的配置,光一个站点就经常把内存吃干抹净。所以,LEMP 不是名词游戏,它是对资源更吝啬、对高并发更友好的务实选择。
2.2 为什么是 Ubuntu 20.04,而不是更新的 22.04 或更老的 18.04?
Ubuntu 20.04 LTS(Long Term Support)是一个极其关键的分水岭。它的生命周期长达 5 年(到 2025 年 4 月),这意味着官方会持续提供安全补丁和关键错误修复,对于生产环境来说,稳定性压倒一切。更重要的是,20.04 是第一个将 PHP 7.4 作为默认版本的 Ubuntu LTS 版本。PHP 7.4 引入了“箭头函数”、“空合并赋值运算符(??=)”等大量提升开发效率的语法糖,同时在性能上比 7.3 有约 3% 的提升。而更新的 22.04 默认是 PHP 8.1,虽然功能更强大,但很多老项目(尤其是基于 WordPress 插件或 ThinkPHP 3.x 的系统)还没完全适配 PHP 8 的严格类型检查,贸然升级可能导致白屏报错。至于 18.04,它的 PHP 7.2 已经在 2020 年底停止官方支持,继续使用存在已知的安全漏洞风险。所以,20.04 是一个完美的“甜点区间”:足够新以获得现代 PHP 特性,又足够稳以保障长期运行。这也是为什么我在给客户做交付时,合同里明确要求的操作系统版本永远是 Ubuntu 20.04 LTS。
2.3 为什么 PHP 要通过 PHP-FPM,而不是直接用 Apache 的 mod_php 模块?
这是整个 LEMP 架构中最容易被新手忽略,却又是最核心的一环。在 LAMP 中,PHP 是作为 Apache 的一个模块(mod_php)被加载的,Apache 进程本身就能解析 PHP 代码。但在 LEMP 中,Nginx 本身
并不具备解析 PHP 的能力
。它只是一个高效的 HTTP 服务器,负责收发请求和响应。那么 PHP 代码谁来执行?答案是 PHP-FPM(FastCGI Process Manager)。你可以把它想象成一个独立的、专门负责“执行 PHP 代码”的服务工厂。Nginx 收到一个
.php
文件的请求后,不会自己去解析,而是把这个请求“转发”给 PHP-FPM 工厂。PHP-FPM 接收到请求,启动一个工作进程(worker),加载并执行对应的 PHP 脚本,然后把执行结果(HTML 内容)原路返回给 Nginx,最后由 Nginx 把结果发给用户的浏览器。这种“解耦”设计带来了巨大的好处:第一,安全性更高。Nginx 和 PHP-FPM 可以运行在不同的用户身份下(比如 Nginx 用
www-data
用户,PHP-FPM 用
phpuser
用户),即使 PHP 代码里有漏洞被利用,攻击者也很难突破到 Nginx 的权限层。第二,灵活性更强。你可以为不同的网站配置不同的 PHP-FPM 池(pool),每个池可以设置独立的内存限制、最大执行时间、甚至不同的 PHP 配置文件(
php.ini
),实现真正的资源隔离。第三,便于调试。当 PHP 脚本出错时,错误日志会清晰地记录在 PHP-FPM 的日志里,而不是混在 Nginx 的日志中,排查问题一目了然。所以,理解并正确配置 PHP-FPM,是掌握 LEMP 的钥匙。
2.4 MySQL 与 MariaDB 的抉择:为什么坚持用 MySQL 官方版?
Ubuntu 20.04 的软件源里,默认提供的其实是 MariaDB,它是 MySQL 的一个分支,由 MySQL 原作者创建,目标是保持开源和兼容。在绝大多数应用场景下,MariaDB 和 MySQL 几乎可以无缝互换。但这里有一个非常现实的考量:企业级应用和主流 CMS 的兼容性认证。WordPress、Drupal、Joomla 等几乎所有主流内容管理系统,在其官方文档和系统要求中,明确列出的支持数据库是 “MySQL 5.6+” 或 “MySQL 8.0+”,而不是 “MariaDB”。虽然它们在实际运行中通常也能兼容 MariaDB,但一旦出现一个极其罕见的 SQL 语法差异或存储引擎行为不一致的问题,你向官方寻求技术支持时,对方的第一句话往往是:“请先在标准的 MySQL 环境下复现问题。” 这会极大地拖慢故障排查进度。此外,MySQL 8.0 引入了强大的“角色(Role)”管理机制,可以让你轻松地为不同开发人员分配“只读”、“增删改”等细粒度权限,这在团队协作中是刚需。而 MariaDB 的角色功能直到较新版本才完善。因此,尽管安装 MySQL 官方版需要多走几步(从官网下载
.deb
包),但为了未来项目的可维护性和技术支持的顺畅,这笔“额外功夫”是绝对值得的。这就像买汽车,你可以选一个外观相似的国产替代品,但如果你要开长途、要进 4S 店保养、要查全国维修点,原厂配件和官方认证永远是最省心的选择。
3. 核心细节解析与实操要点
3.1 系统准备:从一张“白纸”开始的必要清理
在正式安装任何软件之前,我们必须确保这张“白纸”是干净且健康的。这一步看似简单,却是后续所有操作顺利进行的基石。很多人跳过这一步,结果在安装 Nginx 时发现端口 80 已被占用,或者安装 MySQL 时提示依赖冲突,最后花了几个小时在各种报错里打转。所以,请务必耐心执行以下命令:
# 第一步:更新软件包索引。这就像刷新你的“应用商店”列表,确保你知道所有可用的最新版本。
sudo apt update
# 第二步:升级所有已安装的软件包到最新稳定版。这非常重要,因为 Ubuntu 20.04 的初始镜像可能包含一些已知的安全漏洞,升级能一键修复。
sudo apt upgrade -y
# 第三步:清理掉那些已经没用的旧内核和缓存文件。Ubuntu 在升级过程中会保留旧的内核,以防新内核出问题可以回滚,但这会白白占用几 GB 的磁盘空间。
sudo apt autoremove --purge -y
# 第四步:检查当前系统状态。这是一个好习惯,能让你对服务器有个全局了解。
uname -r # 查看当前内核版本
df -h # 查看磁盘使用情况,确保 /var 目录(存放日志和数据库)有足够空间
free -h # 查看内存使用情况
提示:
-y参数的作用是自动确认所有apt的交互式提问,避免在脚本执行中卡住。但在生产环境中,我建议第一次手动执行时不加-y,亲眼看看它打算升级哪些包,以防万一升级了某个关键服务(如openssh-server)导致你远程连接中断。等熟悉了之后,再用-y提高效率。
3.2 Nginx 安装与基础配置:不只是“欢迎页”
Ubuntu 20.04 的官方源里已经包含了 Nginx,安装非常简单:
sudo apt install nginx -y
安装完成后,Nginx 会自动启动。你可以用
systemctl status nginx
查看其运行状态。此时,如果你在浏览器里输入服务器的 IP 地址,就会看到经典的 “Welcome to nginx!” 页面。但这只是万里长征第一步。真正的配置,藏在
/etc/nginx/
这个目录里。我们需要重点关注两个文件:
-
/etc/nginx/nginx.conf:这是 Nginx 的主配置文件,定义了全局参数,如工作进程数(worker_processes)、错误日志路径、HTTP 协议的默认设置等。对于初学者,我们一般不修改它,除非你有特殊的性能调优需求。 -
/etc/nginx/sites-available/:这是一个存放“网站配置模板”的目录。每一个你想托管的网站,都应该在这里创建一个独立的配置文件。 -
/etc/nginx/sites-enabled/:这是一个存放“已启用网站”的目录。它里面的文件,实际上是sites-available里对应文件的符号链接(symlink)。
标准的操作流程是:先在
sites-available
里创建一个配置文件(比如叫
myapp
),然后用
ln -s
命令把它链接到
sites-enabled
目录下,最后用
nginx -t
测试配置语法是否正确,再用
systemctl reload nginx
重新加载配置。这是一种非常安全的“配置即代码”实践,可以让你随时回滚到上一个版本。
下面是一个最精简、但功能完整的 PHP 网站配置模板,保存为
/etc/nginx/sites-available/myapp
:
server {
listen 80;
server_name localhost; # 这里可以改成你的域名,比如 example.com
root /var/www/myapp; # 这是你 PHP 项目的根目录
index index.php index.html;
# 这段是关键!它告诉 Nginx,当请求以 .php 结尾时,不要尝试去磁盘上找这个文件,
# 而是把请求转发给 PHP-FPM 处理。
location ~ \.php$ {
include snippets/fastcgi-php.conf; # 这个文件里定义了 FastCGI 的通用参数
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock; # 这是 PHP-FPM 监听的 Unix socket 地址
}
# 这段是为了防止用户直接访问 .htaccess 或其他敏感文件
location ~ /\.ht {
deny all;
}
}
注意:
fastcgi_pass这一行里的php7.4-fpm.sock必须和你实际安装的 PHP 版本完全一致。如果你后面安装的是 PHP 8.1,这里就必须改成php8.1-fpm.sock。这个路径是 PHP-FPM 服务启动后自动创建的,如果这里写错了,Nginx 就无法和 PHP 通信,所有 PHP 页面都会返回 502 Bad Gateway 错误。这是新手踩坑最多的地方之一。
3.3 MySQL 安装:绕过官方源,直取 MySQL 8.0
如前所述,我们要安装官方 MySQL,而不是 Ubuntu 自带的 MariaDB。步骤如下:
-
下载官方 DEB 包 :访问 MySQL 官网的下载页面(搜索 “MySQL APT Repository”),找到适用于 Ubuntu 20.04 的
.deb包(文件名类似mysql-apt-config_0.8.24-1_all.deb)。在服务器上,我们可以用wget直接下载:wget https://dev.mysql.com/get/mysql-apt-config_0.8.24-1_all.deb -
安装配置工具 :这个
.deb包不是一个数据库,而是一个“配置向导”。安装它会自动帮你把 MySQL 的官方软件源添加到系统的/etc/apt/sources.list.d/目录下。sudo dpkg -i mysql-apt-config_0.8.24-1_all.deb在安装过程中,它会弹出一个文本界面(ncurses 界面),让你选择要安装的 MySQL 组件。用方向键移动,空格键选择,回车确认。 最关键的一步是:在 “Select MySQL version” 这一项,一定要用方向键选中 “mysql-8.0”,然后按 Tab 键切换到
<OK>,再按回车。 如果你没动,它默认可能是 “mysql-5.7”,那后面装出来的就不是我们想要的 8.0 了。 -
更新并安装 :配置好源之后,再次更新软件包索引,并安装 MySQL 服务器:
sudo apt update sudo apt install mysql-server -y -
安全加固 :安装完成后,MySQL 会自动生成一个随机的 root 密码,并将其写入
/etc/mysql/debian.cnf文件。但为了安全,我们必须立刻运行mysql_secure_installation脚本来加固它。这个脚本会引导你完成一系列关键操作:- 设置 root 用户的密码(强烈建议设置一个强密码,而不是留空)。
- 删除匿名用户(Anonymous User)。
-
禁止 root 用户远程登录(只允许
localhost登录,这是最安全的默认设置)。 -
删除测试数据库(
test)及其访问权限。 -
重新加载权限表(
FLUSH PRIVILEGES)。
实操心得:
mysql_secure_installation是 MySQL 安装后 必须 执行的一步。我见过太多人因为跳过这一步,导致服务器暴露在公网上,被自动化脚本扫描到弱密码或空密码的 root 账户,几分钟内就被植入挖矿木马。这绝不是危言耸听,而是血泪教训。
3.4 PHP 及扩展安装:不止是 php7.4,还有它的“左膀右臂”
安装 PHP 本身很简单:
sudo apt install php7.4 php7.4-fpm php7.4-mysql php7.4-curl php7.4-gd php7.4-mbstring php7.4-xml php7.4-xmlrpc php7.4-zip -y
这一长串命令里,每个包都有其不可替代的作用:
-
php7.4-fpm:这是核心,PHP-FPM 服务本身。 -
php7.4-mysql:这是 PHP 连接 MySQL 数据库的驱动。没有它,你的 PHP 代码里mysqli_connect()函数会直接报错 “Call to undefined function mysqli_connect()”。 -
php7.4-curl:用于发起 HTTP 请求,很多 API 调用、微信支付 SDK 都依赖它。 -
php7.4-gd:图像处理库,WordPress 上传图片时自动生成缩略图,就靠它。 -
php7.4-mbstring:多字节字符串处理库,对中文、日文等 UTF-8 字符串的截取、大小写转换至关重要。没有它,很多中文网站的标题、文章摘要会显示乱码。 -
php7.4-xml和php7.4-xmlrpc:XML 解析和 RPC 通信支持,是很多老系统和 RSS 订阅功能的基础。 -
php7.4-zip:用于解压缩 ZIP 文件,WordPress 后台一键升级主题和插件,就靠它。
安装完成后,别忘了启动并启用 PHP-FPM 服务:
sudo systemctl start php7.4-fpm
sudo systemctl enable php7.4-fpm
enable
命令的作用是让 PHP-FPM 在系统开机时自动启动,否则每次重启服务器,你的网站就全挂了。
4. 实操过程与核心环节实现
4.1 创建测试环境:一个能“说话”的 PHP 文件
现在,所有组件都已安装完毕,但它们还只是各自为政的“零件”。我们需要一个简单的测试用例,把它们串联起来,亲眼见证整个链条是如何工作的。
-
创建网站根目录 :
sudo mkdir -p /var/www/myapp -
创建一个
info.php文件 ,这是 PHP 的“Hello World”,但它能告诉我们所有关键信息:sudo nano /var/www/myapp/info.php在编辑器里输入以下内容:
<?php // 这行代码会输出 PHP 的详细信息,包括版本、已加载的扩展、配置文件路径等 phpinfo(); // 这几行代码用来测试 MySQL 连接 $link = mysqli_connect('127.0.0.1', 'root', 'your_mysql_root_password'); if (!$link) { die('Connect Error: ' . mysqli_connect_error()); } echo "MySQL connection successful!"; mysqli_close($link); ?>注意:请务必将
'your_mysql_root_password'替换成你在mysql_secure_installation步骤中设置的 root 密码。 -
设置正确的文件权限 :Web 服务器需要有读取这个文件的权限,但不能让它有写权限,以防被恶意篡改。
sudo chown -R $USER:$USER /var/www/myapp sudo chmod -R 755 /var/www/myapp -
启用我们刚才创建的网站配置 :
sudo ln -sf /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/ sudo nginx -t # 这是关键!测试配置语法。如果看到 "syntax is ok" 和 "test is successful",说明没问题。 sudo systemctl reload nginx # 重新加载配置,让改动生效。 -
最后一步,也是最关键的一步:测试 。在浏览器里访问
http://your_server_ip/info.php。如果一切顺利,你将看到一个密密麻麻、信息量爆炸的 PHP 信息页。向下滚动,找到 “Loaded Configuration File” 这一行,它会告诉你当前生效的php.ini文件路径(通常是/etc/php/7.4/fpm/php.ini)。再找到 “mysqlnd” 部分,确认 MySQL 扩展已加载。最后,页面底部应该能看到 “MySQL connection successful!” 这行字。这证明 Nginx -> PHP-FPM -> MySQL 这条链路,已经 100% 打通。
4.2 深入 PHP-FPM 配置:从“能跑”到“跑得稳”
默认的 PHP-FPM 配置(
/etc/php/7.4/fpm/pool.d/www.conf
)是为通用场景设计的,但对于一个真实的网站,我们需要根据服务器的硬件资源进行微调,否则可能会在流量稍大时出现 504 Gateway Timeout 错误。
打开配置文件:
sudo nano /etc/php/7.4/fpm/pool.d/www.conf
找到并修改以下几项关键参数:
-
pm = dynamic:这是进程管理方式。dynamic表示 PHP-FPM 会根据负载动态调整工作进程数,比static(固定数量)和ondemand(按需启动)更平衡。 -
pm.max_children = 5:这是最大子进程数。一个进程大约消耗 20-30MB 内存。如果你的服务器有 2GB 内存,5是一个安全的起点。公式是:max_children ≈ (Total Memory * 0.6) / 25MB。 -
pm.start_servers = 2:PHP-FPM 启动时创建的初始进程数。 -
pm.min_spare_servers = 1:空闲时最少保持的进程数。 -
pm.max_spare_servers = 3:空闲时最多保持的进程数。 -
pm.max_requests = 500:每个子进程处理完 500 个请求后就自动退出并重启。这是为了防止 PHP 脚本中的内存泄漏问题越积越多,最终耗尽内存。这是一个非常重要的“健康检查”机制。
修改完成后,记得重启服务:
sudo systemctl restart php7.4-fpm
4.3 Nginx 性能优化:让“门卫”更高效
Nginx 的默认配置同样可以优化。编辑主配置文件:
sudo nano /etc/nginx/nginx.conf
在
http { ... }
块内,添加或修改以下参数:
-
client_max_body_size 100M;:允许用户上传的最大文件大小。WordPress 上传大主题或插件时,经常会遇到 1MB 的默认限制,导致上传失败。 -
gzip on;:开启 Gzip 压缩。这会让 Nginx 在发送 HTML、CSS、JS 等文本文件前,先进行压缩,通常能减少 60%-70% 的传输体积,显著提升网页加载速度。 -
gzip_types text/plain application/xml text/css application/javascript;:指定哪些 MIME 类型的文件需要被压缩。
修改后,同样需要测试并重载:
sudo nginx -t && sudo systemctl reload nginx
4.4 MySQL 8.0 的关键配置:告别“Access denied”
MySQL 8.0 引入了一个重大的安全变更:默认的身份验证插件从
mysql_native_password
改为了
caching_sha2_password
。这个新插件更安全,但很多老的 PHP MySQL 扩展(尤其是
mysql
扩展,虽然它已被废弃)和一些 GUI 工具(如旧版的 Navicat)并不支持它。当你用 PHP 连接 MySQL 时,可能会遇到一个让人抓狂的错误:
SQLSTATE[HY000] [1045] Access denied for user 'root'@'localhost' (using password: YES)
,即使密码完全正确。
解决方法是在创建用户时,显式指定旧的认证插件:
-- 登录 MySQL
sudo mysql -u root -p
-- 创建一个新用户,并指定认证插件
CREATE USER 'webuser'@'localhost' IDENTIFIED WITH mysql_native_password BY 'StrongPassword123!';
-- 授予该用户对某个数据库的所有权限
CREATE DATABASE myapp_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
GRANT ALL PRIVILEGES ON myapp_db.* TO 'webuser'@'localhost';
-- 刷新权限
FLUSH PRIVILEGES;
这样,你的 PHP 应用就可以用
webuser
这个账号,安全、稳定地连接数据库了。记住,永远不要在生产环境中直接用 root 账号连接你的网站应用,这是最基本的安全准则。
5. 常见问题与排查技巧实录
5.1 问题速查表:从现象到根源的精准定位
| 现象 | 可能原因 | 排查命令/步骤 | 解决方案 |
|---|---|---|---|
| 浏览器显示 502 Bad Gateway | Nginx 无法连接到 PHP-FPM |
sudo systemctl status php7.4-fpm
ls -l /var/run/php/
|
检查 PHP-FPM 是否在运行;确认
fastcgi_pass
路径是否与
ls
列出的
.sock
文件名完全一致。
|
| 浏览器显示 504 Gateway Timeout | PHP-FPM 处理请求超时 |
sudo tail -f /var/log/php7.4-fpm.log
sudo nginx -T | grep "fastcgi_read_timeout"
|
查看 PHP-FPM 日志是否有
WARNING: [pool www] child ... timeout
;在 Nginx 配置的
location ~ \.php$
块内,增加
fastcgi_read_timeout 300;
。
|
| PHP 页面显示源代码,而不是执行结果 |
Nginx 没有把
.php
请求转发给 PHP-FPM
|
sudo nginx -T | grep -A 10 "location ~ \.php$"
|
检查 Nginx 配置中是否遗漏了
location ~ \.php$
块,或者该块内是否缺少
include snippets/fastcgi-php.conf;
。
|
mysqli_connect()
报错 “Call to undefined function”
|
php7.4-mysql
扩展未安装或未启用
|
php -m | grep mysql
|
运行此命令,如果没有任何输出,说明扩展未加载。执行
sudo apt install php7.4-mysql
并重启
php7.4-fpm
。
|
| MySQL 连接报错 “Access denied” | MySQL 8.0 默认认证插件不兼容 |
sudo mysql -u root -p -e "SELECT user,host,plugin FROM mysql.user;"
|
查看 root 用户的
plugin
字段。如果是
caching_sha2_password
,则按 4.4 节方法创建一个使用
mysql_native_password
的新用户。
|
5.2 我踩过的坑:那些文档里不会写的“潜规则”
-
坑一:
/var/www/myapp目录的属主问题 。我曾经把项目文件用root用户cp进去,结果 PHP-FPM 工作进程(默认以www-data用户身份运行)没有权限读取这些文件,导致 403 Forbidden 错误。解决方案永远是:sudo chown -R www-data:www-data /var/www/myapp,而不是chown -R $USER:$USER。www-data是 Nginx 和 PHP-FPM 共同的“工作身份”,让文件属于它,是最稳妥的做法。 -
坑二:
php.ini的修改不生效 。PHP 有多个配置文件:/etc/php/7.4/cli/php.ini(命令行模式)和/etc/php/7.4/fpm/php.ini(FPM 模式)。你在命令行里php -i看到的配置,和网站里phpinfo()显示的,是两个不同的文件。修改了 CLI 的配置,对网站毫无影响。务必确认你编辑的是fpm目录下的php.ini。 -
坑三:防火墙拦截了 80 端口 。Ubuntu 默认安装了
ufw(Uncomplicated Firewall)。如果你在本地测试一切正常,但外网无法访问,第一反应应该是检查防火墙:sudo ufw status verbose # 查看状态 sudo ufw allow 'Nginx Full' # 允许所有 Nginx 端口(80, 443) -
坑四:SELinux?不存在的 。这是 CentOS/RHEL 系统的烦恼,Ubuntu 默认不启用 SELinux,所以你不需要折腾
setsebool这类命令。把精力集中在chmod和chown上就够了。
5.3 日常维护与监控:让服务器自己“说话”
一个搭建好的环境,不是一劳永逸的。你需要建立一套简单的监控习惯:
-
日志是你的朋友
:Nginx 的错误日志在
/var/log/nginx/error.log,PHP-FPM 的在/var/log/php7.4-fpm.log,MySQL 的在/var/log/mysql/error.log。当网站出问题时,第一时间tail -f这三个文件,90% 的问题都能在那里找到线索。 -
定期检查服务状态
:养成习惯,每周执行一次
sudo systemctl list-units --type=service --state=failed,看看有没有服务意外崩溃了。 -
备份数据库
:再稳定的系统也会出意外。一个简单的每日备份脚本就能救你一命:
这个脚本会在每天凌晨 2 点,自动备份你的数据库到# 创建备份脚本 sudo nano /usr/local/bin/backup-mysql.sh # 内容: #!/bin/bash mysqldump -u webuser -p'YourPassword' myapp_db > /backup/myapp_db_$(date +\%Y\%m\%d).sql # 设置权限并加入定时任务 sudo chmod +x /usr/local/bin/backup-mysql.sh sudo crontab -e # 添加一行:0 2 * * * /usr/local/bin/backup-mysql.sh/backup/目录。
我个人在实际操作中的体会是,LEMP 环境的搭建,其价值远不止于“让一个网站跑起来”。它是一把钥匙,一把能打开 Linux 服务器世界大门的钥匙。当你亲手配置好 Nginx 的每一个
location
,当你读懂 PHP-FPM 日志里那行
child 1234 exited on signal 11 (SIGSEGV)
的含义,当你第一次用
mysqldump
成功恢复一个被误删的表,你就不再是一个只会调用 API 的开发者,而是一个真正理解“代码如何在真实世界里呼吸”的工程师。这种掌控感,是任何框架、任何云服务都无法替代的底层力量。所以,别把它当成一个任务,当成一次和服务器的深度对话。每一个
sudo
命令,都是你向系统发出的一次握手。
375

被折叠的 条评论
为什么被折叠?



