尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

从零搭建Linux LEMP环境:Nginx+PHP-FPM+MariaDB实战指南

从零搭建Linux LEMP环境:Nginx+PHP-FPM+MariaDB实战指南 1. 项目概述从零构建一个健壮的Linux Web服务栈每次看到有人想搭个网站第一反应就是去找那些一键安装包或者面板工具这当然没问题效率很高。但作为一个在运维和开发线上摸爬滚打了十多年的老手我始终认为亲手从零开始用最经典的Nginx、PHP、MySQL现在更流行MariaDB这套组合来搭建一个网站环境是理解Web服务如何运作的绝佳方式。这不仅仅是把几个软件装上去那么简单它关乎你对请求流转、资源调度和安全边界的深刻理解。今天我就带你走一遍这个流程目标不是最快而是最稳、最明白。我们会从一台干净的Linux服务器以Ubuntu 22.04 LTS为例开始一步步搭建起一个能处理动态PHP页面、连接数据库、并通过高性能的Nginx对外服务的完整环境。无论你是想部署自己的博客、测试一个项目还是为深入学习运维打基础这套“手动档”的操作经验都至关重要。2. 核心组件选型与架构设计解析2.1 为什么是Nginx PHP-FPM MySQL/MariaDB这套组合被称为LEMPLinux, Nginx, MySQL/MariaDB, PHP或LNMP是经过无数生产环境验证的黄金搭档。选择它们背后有清晰的逻辑。首先Nginx是我们的Web服务器和反向代理。与老牌的Apache相比Nginx采用事件驱动、异步非阻塞的架构在处理高并发静态请求时资源占用极低性能优势明显。它就像一个高效的前台和调度员负责接收所有外来访客HTTP请求如果是请求图片、CSS等静态文件它自己就能快速处理并返回如果访客要找的是动态内容比如一个PHP页面它会立刻联系后端的专业处理员。后端的专业处理员就是PHP-FPM。PHP本身是一种脚本语言需要解析器来执行。PHP-FPM是一个独立的FastCGI进程管理器。你可以把它理解为一个常驻后台的PHP脚本执行池。Nginx通过FastCGI协议将PHP请求“转发”给PHP-FPMPHP-FPM从池子里分配一个空闲的worker进程来执行这个PHP脚本执行完毕后再将结果通常是HTML交还给Nginx由Nginx最终响应给用户。这种解耦的架构使得Web服务器Nginx和应用处理器PHP-FPM可以独立扩展、优化稳定性大大增强。至于数据库MySQL或其完全兼容的开源分支MariaDB是关系型数据库的事实标准。对于绝大多数Web应用如WordPress、Laravel项目等它们都是首选。MariaDB在性能优化和新特性方面更为激进且完全兼容MySQL的命令和协议这里我们选择它。整个数据流向是这样的用户请求 - Nginx监听80/443端口- 静态文件直接响应 - 动态请求.php通过FastCGI协议传递给PHP-FPM监听9000端口或Unix Socket- PHP进程执行脚本必要时连接MariaDB默认3306端口查询数据 - PHP生成HTML - 返回给Nginx - Nginx响应给用户。理解这个链条是后续一切配置和排错的基础。2.2 环境准备与规划要点在开始敲命令之前做好规划能让整个过程更顺畅。假设我们使用一台全新的Ubuntu 22.04 LTS服务器。系统用户与权限永远不要用root用户直接运行服务或进行日常操作。我们的策略是使用一个具有sudo权限的普通用户例如webadmin来安装和配置软件而服务进程则以它们自己专用的系统用户身份运行如www-data用户运行Nginx和PHP-FPM这符合最小权限原则。目录结构规划清晰的目录结构是良好管理的开始。我习惯将网站文件放在/var/www/目录下每个网站在其下拥有独立的子目录例如/var/www/my_site/public。这里public目录是网站的根目录只存放Web可公开访问的文件如index.php, css, js其他如配置文件、日志等放在外层。Nginx的站点配置放在/etc/nginx/sites-available/通过软链接启用到/etc/nginx/sites-enabled/。日志统一存放在/var/log/nginx/和/var/log/php/下。防火墙策略确保服务器的防火墙如ufw只开放必要的端口SSH22 HTTP80 HTTPS443。在安装过程中可以先暂时禁用或配置好规则避免把自己关在外面。注意生产环境中务必在安装前配置好SSH密钥登录并禁用密码登录同时确保防火墙规则正确。本文以学习环境为例会简化部分安全步骤但会指出关键的安全配置点。3. 分步安装与基础配置实战3.1 系统更新与基础工具安装首先用你的具有sudo权限的用户登录服务器。第一步永远是更新系统包列表并升级现有软件这能确保我们从一个稳定的基础开始。sudo apt update sudo apt upgrade -y安装一些后续可能用到的工具如用于编辑配置的vim或nano用于解压的unzip等。sudo apt install -y vim curl wget unzip3.2 安装并配置MariaDB数据库MariaDB是MySQL的替代品在Ubuntu的仓库中通常已替换了MySQL。安装MariaDB服务器与客户端sudo apt install -y mariadb-server mariadb-client运行安全安装脚本这是至关重要的一步。刚安装的MariaDB存在默认的空密码和测试数据库等安全隐患。运行以下脚本进行交互式安全加固sudo mysql_secure_installation你会被问到一系列问题我的建议如下设置root密码输入Y并设置一个强密码。注意这里的“root”是数据库的root用户不是系统root。移除匿名用户输入Y。匿名用户允许任何人无需密码登录数据库必须移除。禁止root远程登录输入Y。除非你有特殊需求否则数据库root用户只允许从本地localhost登录极大增强安全。移除测试数据库输入Y。测试数据库test默认对所有用户开放存在风险。重新加载权限表输入Y。使上述安全设置立即生效。为Web应用创建专用数据库和用户永远不要让你的PHP应用使用数据库的root用户去连接。我们应该创建一个专属的数据库和用户。sudo mysql -u root -p输入你刚才设置的root密码进入MariaDB命令行。执行以下SQL语句以创建一个名为mywebdb的数据库和一个名为webuser的用户为例请务必替换YourStrongPasswordHere为实际的强密码-- 创建数据库 CREATE DATABASE mywebdb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- 创建用户并设置密码。localhost表示只允许从本机连接 CREATE USER webuserlocalhost IDENTIFIED BY YourStrongPasswordHere; -- 授予用户对mywebdb数据库的所有权限 GRANT ALL PRIVILEGES ON mywebdb.* TO webuserlocalhost; -- 刷新权限使授权生效 FLUSH PRIVILEGES; -- 退出 EXIT;3.3 安装PHP与PHP-FPMUbuntu的仓库提供了多个PHP版本。我们需要安装PHP本身以及PHP-FPM还有你的应用可能需要的扩展。安装PHP-FPM及常用扩展这里我们安装PHP 8.1版本Ubuntu 22.04默认。php-fpm是核心php-mysql用于连接MariaDBphp-curl,php-gd,php-mbstring,php-xml等是许多CMS如WordPress和框架如Laravel所必需的。sudo apt install -y php8.1-fpm php8.1-mysql php8.1-curl php8.1-gd php8.1-mbstring php8.1-xml php8.1-zip php8.1-cli验证PHP-FPM服务状态安装后PHP-FPM服务会自动启动并设置为开机自启。检查一下sudo systemctl status php8.1-fpm你应该看到状态为active (running)。一个关键配置调整性能与安全默认情况下PHP-FPM监听一个TCP端口127.0.0.1:9000。但在同一台机器上使用Unix Socket文件通信比TCP Loopback更快、更安全。我们来修改其配置。sudo vim /etc/php/8.1/fpm/pool.d/www.conf找到这一行listen /run/php/php8.1-fpm.sock确认它已经是这样新版本Ubuntu默认已是socket。如果不是请将其从listen 127.0.0.1:9000修改为上述socket路径。同时确保下面几行的权限设置合理listen.owner www-data listen.group www-data listen.mode 0660这设置了socket文件的属主和权限让Nginx进程也以www-data用户运行能够读写它。保存并退出。重启PHP-FPM使配置生效sudo systemctl restart php8.1-fpm3.4 安装并配置Nginx安装Nginxsudo apt install -y nginx调整防火墙允许HTTP和HTTPS流量。sudo ufw allow Nginx Full # 允许80和443端口 sudo ufw status # 查看规则是否生效创建网站根目录并设置权限sudo mkdir -p /var/www/my_site/public # 将目录所有权赋予你的当前用户方便上传文件但组设为www-data sudo chown -R $USER:www-data /var/www/my_site # 设置目录权限让www-data组有读写执行权限 sudo chmod -R 775 /var/www/my_site创建Nginx服务器块配置Nginx的站点配置文件称为“服务器块”。我们先在sites-available中创建配置再链接到sites-enabled来启用。sudo vim /etc/nginx/sites-available/my_site将以下配置粘贴进去。这是一个支持PHP、并做了基础优化的配置模板请将server_name替换为你的域名或服务器IP。server { listen 80; listen [::]:80; # 将 your_domain_or_ip 替换为你的实际域名或IP地址 server_name your_domain_or_ip; root /var/www/my_site/public; index index.php index.html index.htm; # 日志文件 access_log /var/log/nginx/my_site_access.log; error_log /var/log/nginx/my_site_error.log; location / { try_files $uri $uri/ /index.php?$query_string; } # 处理PHP请求关键配置 location ~ \.php$ { include snippets/fastcgi-php.conf; # 与php-fpm中配置的listen方式保持一致 fastcgi_pass unix:/run/php/php8.1-fpm.sock; # 或者如果是TCP方式fastcgi_pass 127.0.0.1:9000; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; include fastcgi_params; } # 禁止访问隐藏文件如.htaccess location ~ /\. { deny all; } # 静态文件缓存设置提升性能 location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg)$ { expires 30d; add_header Cache-Control public, immutable; } }启用配置并测试# 创建软链接以启用站点 sudo ln -s /etc/nginx/sites-available/my_site /etc/nginx/sites-enabled/ # 测试Nginx配置语法是否正确 sudo nginx -t如果看到syntax is ok和test is successful的输出说明配置无误。重启Nginx服务sudo systemctl restart nginx4. 深度测试与验证4.1 创建测试文件验证各组件协作现在三个核心服务都已就位。我们需要验证它们是否能协同工作。创建PHP信息页在网站根目录创建一个info.php文件这是最直接的测试方法。echo ?php phpinfo(); ? | sudo tee /var/www/my_site/public/info.php在浏览器中访问打开你的浏览器访问http://your_domain_or_ip/info.php。如果成功你会看到一个详细的PHP配置信息页面。在这个页面上搜索“mysql”或“mysqli”确认PHP的MySQL扩展已启用。同时查看“Server API”一项应该是“FPM/FastCGI”。这证明Nginx成功将PHP请求转发给了PHP-FPM处理。如果失败如果看到“502 Bad Gateway”通常是Nginx无法连接到PHP-FPM的socket或端口。检查/etc/nginx/sites-available/my_site中的fastcgi_pass路径是否与PHP-FPM配置中的listen一致。检查socket文件的权限ls -l /run/php/php8.1-fpm.sock确保www-data用户有权限访问。查看Nginx和PHP-FPM的错误日志/var/log/nginx/error.log和/var/log/php8.1-fpm.log获取具体线索。创建数据库连接测试脚本为了验证PHP能否连接MariaDB我们创建一个简单的测试脚本测试后务必删除。sudo vim /var/www/my_site/public/dbtest.php输入以下内容将YourStrongPasswordHere替换为你之前为webuser设置的密码。?php $host localhost; $dbname mywebdb; $user webuser; $pass YourStrongPasswordHere; try { $pdo new PDO(mysql:host$host;dbname$dbname;charsetutf8mb4, $user, $pass); $pdo-setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); echo 数据库连接成功; // 可以执行一个简单查询例如$stmt $pdo-query(SELECT VERSION()); echo $stmt-fetchColumn(); } catch (PDOException $e) { echo 数据库连接失败: . $e-getMessage(); } ?在浏览器中访问http://your_domain_or_ip/dbtest.php。如果看到“数据库连接成功”则证明整个栈Nginx - PHP-FPM - PHP - MariaDB已完全打通。重要安全提示info.php和dbtest.php会暴露服务器敏感信息。测试完成后必须立即删除它们sudo rm /var/www/my_site/public/info.php /var/www/my_site/public/dbtest.php4.2 部署一个真实应用以WordPress为例理论测试通过后我们来部署一个真实的PHP应用比如WordPress这能检验环境对复杂应用的兼容性。下载并解压WordPresscd /tmp wget https://wordpress.org/latest.tar.gz tar -xzvf latest.tar.gz复制文件到网站目录并设置权限sudo cp -r /tmp/wordpress/* /var/www/my_site/public/ # 将文件所有权设为www-data以便WordPress可以在线更新和安装插件 sudo chown -R www-data:www-data /var/www/my_site/public/ # 设置合理的目录权限 sudo find /var/www/my_site/public/ -type d -exec chmod 755 {} \; sudo find /var/www/my_site/public/ -type f -exec chmod 644 {} \;为WordPress创建数据库我们之前已经创建了mywebdb和webuser可以直接使用。如果需要新建可以参照3.2节的方法。通过Web安装向导完成安装在浏览器中访问你的域名或IP应该会跳转到WordPress著名的“五分钟安装”页面。根据提示输入数据库名 (mywebdb)、用户名 (webuser)、密码、数据库主机 (localhost) 和表前缀即可完成安装。5. 性能调优与安全加固要点环境跑起来只是第一步要让其稳定、高效、安全地服务于生产还需要进行一系列优化。5.1 PHP-FPM进程管理优化PHP-FPM的进程池配置直接影响性能和资源消耗。关键参数在/etc/php/8.1/fpm/pool.d/www.conf中。pm进程管理方式。对于内存充足、追求性能的机器static固定子进程数或dynamic动态调整是常见选择。ondemand按需生成适合内存非常紧张的环境但请求到来时会有进程创建的开销。pm.max_children同一时刻存活的子进程最大数量。这决定了你的PHP能处理的最大并发请求数。设置过高会耗尽内存过低则无法应对流量。一个粗略的估算公式最大内存 / 单个PHP进程平均内存占用。例如服务器2G内存单个PHP进程约50M则max_children可设为2000MB / 50MB ≈ 40再预留一些给系统和其他服务设为30-35比较安全。pm.start_servers启动时创建的子进程数dynamic模式有效。pm.min_spare_servers/pm.max_spare_servers动态模式下空闲进程的最小和最大数量。 一个适用于中小流量站点的dynamic配置示例pm dynamic pm.max_children 30 pm.start_servers 5 pm.min_spare_servers 3 pm.max_spare_servers 10 pm.process_idle_timeout 10s修改后需要重启PHP-FPMsudo systemctl restart php8.1-fpm。5.2 Nginx性能与缓存优化调整Worker进程在/etc/nginx/nginx.conf的events块上方可以设置worker_processes auto;让Nginx自动根据CPU核心数设置工作进程。worker_connections定义了每个worker能处理的最大连接数可以适当调高如1024或2048但受系统打开文件数限制。启用Gzip压缩在nginx.conf的http块中通常已包含基础的gzip配置确保其启用可以显著减少文本类资源的传输大小。配置静态文件缓存如前面服务器块配置所示为图片、CSS、JS等静态文件设置较长的过期时间利用浏览器缓存减少服务器请求。启用FastCGI缓存对于动态但变化不频繁的页面如博客文章页可以启用Nginx的FastCGI缓存将PHP的执行结果缓存起来直接由Nginx返回极大减轻PHP和数据库压力。配置稍复杂但效果显著。5.3 至关重要的安全配置禁用不必要的信息暴露在Nginx的服务器块或全局配置中关闭显示Nginx版本号。server_tokens off;在PHP配置 (/etc/php/8.1/fpm/php.ini) 中设置expose_php Off限制PHP执行权限在Nginx配置中确保location ~ \.php$块只对确切的文件执行PHP防止上传的恶意文件被当作PHP执行。使用try_files检查文件是否存在是一个好习惯。文件权限原则遵循“最小权限”原则。Web根目录下的文件所有者设为www-data权限设为644文件和755目录。上传目录如wp-content/uploads可能需要给www-data写权限但应严格限制可执行文件的权限。配置SSL/TLSHTTPS使用Let‘s Encrypt的Certbot可以免费、自动化地获取和部署SSL证书。这是现代网站的标配不仅能加密通信也是很多浏览器特性如HTTP/2的要求。sudo apt install certbot python3-certbot-nginx sudo certbot --nginx -d your_domain.comCertbot会自动修改你的Nginx配置启用HTTPS并设置自动续期。定期更新保持系统、Nginx、PHP、MariaDB的软件包处于最新状态以获取安全补丁。sudo apt update sudo apt upgrade -y6. 故障排查与日常维护指南即使配置再仔细线上环境也难免遇到问题。掌握排查方法至关重要。6.1 日志是你的第一手资料Nginx访问日志/var/log/nginx/access.log和站点特定的日志。记录所有请求用于分析流量、排查错误请求。Nginx错误日志/var/log/nginx/error.log和站点特定的错误日志。这里会记录配置错误、权限错误、上游服务如PHP-FPM连接失败等关键信息。遇到502、504错误首先查这里。PHP-FPM错误日志/var/log/php8.1-fpm.log。记录PHP脚本本身的解析错误、致命错误等。MariaDB错误日志通常在/var/log/mysql/error.log。记录数据库连接、查询错误。查看日志的常用命令# 实时查看Nginx错误日志 sudo tail -f /var/log/nginx/error.log # 查看PHP-FPM日志最后50行 sudo tail -n 50 /var/log/php8.1-fpm.log # 在日志中搜索特定错误如“Permission denied” sudo grep -i permission denied /var/log/nginx/error.log6.2 常见问题速查表问题现象可能原因排查步骤502 Bad GatewayNginx无法连接到PHP-FPM后端。1. 检查PHP-FPM服务是否运行systemctl status php8.1-fpm。2. 核对Nginx配置中fastcgi_pass的地址/端口是否与PHP-FPMlisten配置一致。3. 检查Socket文件权限如果是Unix Socket确保Nginx用户www-data有读写权限。ls -l /run/php/php8.1-fpm.sock。4. 查看Nginx错误日志。403 Forbidden权限不足Nginx用户无法访问请求的文件或目录。1. 检查网站根目录及其父目录的权限和所有权。确保www-data用户至少有读取和执行权限。2. 检查Nginx配置中root指令指向的路径是否正确。3. 检查SELinux/AppArmor如果启用是否阻止了访问。404 Not Found请求的文件不存在。1. 确认文件是否在正确的root目录下。2. 检查index指令配置的默认首页文件名是否正确。3. 检查try_files指令的逻辑。空白页或PHP代码直接显示PHP未被执行被当作纯文本返回。1. Nginx配置中缺少对.php文件的处理location块。2.fastcgi_pass指令配置错误或指向的PHP-FPM未运行。3. PHP-FPM池配置错误。数据库连接失败PHP脚本无法连接到MariaDB。1. 确认数据库服务运行systemctl status mariadb。2. 检查PHP脚本中的连接参数主机、用户名、密码、数据库名是否正确。3. 确认数据库用户是否有从localhost连接的权限以及密码是否正确。4. 检查MariaDB是否只绑定了127.0.0.1默认而PHP脚本尝试从其他地址连接。6.3 服务管理常用命令查看状态sudo systemctl status nginx,sudo systemctl status php8.1-fpm,sudo systemctl status mariadb启动/停止/重启服务sudo systemctl start/stop/restart service_name重新加载配置不中断服务sudo systemctl reload nginx(Nginx),sudo systemctl reload php8.1-fpm(PHP-FPM)设置开机自启sudo systemctl enable service_name测试Nginx配置语法sudo nginx -t手动搭建这样一个环境初期会花费一些时间也会遇到各种“坑”但这个过程带给你的对Web架构的深入理解是使用面板工具无法比拟的。当你能够从容地根据日志定位到是Nginx配置错误、PHP-FPM进程池耗尽还是数据库连接超时并快速解决时你就真正掌握了这套技术的命脉。这套LEMP栈的灵活性极高你可以根据应用需求轻松集成Redis做对象缓存用Memcached做数据库查询缓存或者配置Nginx作为负载均衡器。基础打牢了上层建筑才能稳固。
返回列表