Ubuntu 20.04 搭建 LEMP 环境:Nginx + PHP-FPM + MySQL 8.0 实战指南

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。步骤如下:

  1. 下载官方 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
    
  2. 安装配置工具 :这个 .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 了。

  3. 更新并安装 :配置好源之后,再次更新软件包索引,并安装 MySQL 服务器:

    sudo apt update
    sudo apt install mysql-server -y
    
  4. 安全加固 :安装完成后,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 文件

现在,所有组件都已安装完毕,但它们还只是各自为政的“零件”。我们需要一个简单的测试用例,把它们串联起来,亲眼见证整个链条是如何工作的。

  1. 创建网站根目录

    sudo mkdir -p /var/www/myapp
    
  2. 创建一个 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 密码。

  3. 设置正确的文件权限 :Web 服务器需要有读取这个文件的权限,但不能让它有写权限,以防被恶意篡改。

    sudo chown -R $USER:$USER /var/www/myapp
    sudo chmod -R 755 /var/www/myapp
    
  4. 启用我们刚才创建的网站配置

    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 # 重新加载配置,让改动生效。
    
  5. 最后一步,也是最关键的一步:测试 。在浏览器里访问 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 ,看看有没有服务意外崩溃了。
  • 备份数据库 :再稳定的系统也会出意外。一个简单的每日备份脚本就能救你一命:
    # 创建备份脚本
    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
    
    这个脚本会在每天凌晨 2 点,自动备份你的数据库到 /backup/ 目录。

我个人在实际操作中的体会是,LEMP 环境的搭建,其价值远不止于“让一个网站跑起来”。它是一把钥匙,一把能打开 Linux 服务器世界大门的钥匙。当你亲手配置好 Nginx 的每一个 location ,当你读懂 PHP-FPM 日志里那行 child 1234 exited on signal 11 (SIGSEGV) 的含义,当你第一次用 mysqldump 成功恢复一个被误删的表,你就不再是一个只会调用 API 的开发者,而是一个真正理解“代码如何在真实世界里呼吸”的工程师。这种掌控感,是任何框架、任何云服务都无法替代的底层力量。所以,别把它当成一个任务,当成一次和服务器的深度对话。每一个 sudo 命令,都是你向系统发出的一次握手。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值