第 12 章 · Web 服务与 LNMP 实战
你「不想用宝塔但自己又不会配置」的症结,在于不知道面板背后替你做了什么。本章亲手搭一套 LNMP(Linux + Nginx + MySQL + PHP)并部署一个真实站点,你会惊讶:面板 90% 的功能不过是几条命令加一个配置文件。学完再决定要不要面板,就是「会了之后的选择」而不是「不会的依赖」。
本章目录
12.1 面板替你做了什么 12.2 LNMP 架构总览 12.3 Nginx 安装与配置 12.4 MySQL/MariaDB 12.5 PHP 与 PHP-FPM 12.6 串联部署 WordPress 12.7 站点目录与权限 12.8 HTTPS 证书 12.9 宝塔替代方案对比 自测题12.1面板到底替你做了什么(拆开看就不神秘了)
| 宝塔的功能 | 底层其实是 |
|---|---|
| 一键装 Nginx/MySQL/PHP | apt/dnf 或官方源安装(第 6 章) |
| 网站管理(新建站点/伪静态/反向代理) | 在 /etc/nginx/conf.d/ 生成一个 server 配置文件(本章 12.3) |
| 数据库管理 | MySQL 用户与库的创建 + 命令行/phpMyAdmin 操作 |
| SSL 证书 | certbot 自动申请 Let's Encrypt 证书(本章 12.8) |
| 防火墙/安全 | ufw/firewalld 规则 + fail2ban(第 9 章) |
| 监控面板/日志 | top/ss/journalctl/nginx access log(第 10 章) |
| 定时任务/计划任务 | cron(第 7/11 章) |
| 文件管理 | 命令行 + 权限规范(第 3/5 章) |
结论
面板 = 把第 3、5、6、7、8、9、10 章的命令包了一层 Web UI。你学到的每一条命令,都是面板能力的「1.0 版本且无广告」。所谓「不会配置」,只是还没把这些命令串起来 —— 本章就是串起来的那根线。
12.2LNMP 架构总览:请求怎么走
图 12-1 · LNMP 请求链路(示意)
12.3Nginx:安装、起服务、建第一个站点
sudo apt install nginx # Ubuntu;Rocky: sudo dnf install nginx
sudo systemctl enable --now nginx
ss -tlnp | grep :80 # 确认在监听
curl -I http://localhost # 本机自测(应返回 200)
sudo nginx -t # 配置语法测试(改配置后必做)
sudo systemctl reload nginx # 热重载(不中断连接)
server {
listen 80;
server_name example.com www.example.com; # 换成你的域名
root /data/web/example; # 站点根目录(第 3 章规范的 /data)
index index.html index.php;
location / {
try_files $uri $uri/ =404;
}
# PHP 请求转发给 PHP-FPM(第 12.6 节再解释)
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
结构记忆:Nginx 配置 = 全局段 + http 段 + server(站点)段 + location(路径规则)段。一个 server 块就是一个网站;站点的 conf 文件放 /etc/nginx/conf.d/(或 sites-available + sites-enabled 软链接模式)。
12.4MySQL / MariaDB:安装与安全初始化
sudo apt install mysql-server # Ubuntu
sudo dnf install mariadb-server # Rocky
sudo systemctl enable --now mysql # Rocky: mariadb
sudo mysql_secure_installation # 安全初始化:设 root 密码、删匿名用户、禁远程 root
sudo mysql -u root -p # 登录(Ubuntu 新装默认可用 sudo mysql 免密进)
CREATE DATABASE wordpress CHARACTER SET utf8mb4;
CREATE USER 'wp'@'localhost' IDENTIFIED BY '强密码';
GRANT ALL PRIVILEGES ON wordpress.* TO 'wp'@'localhost';
FLUSH PRIVILEGES;
# 只给应用该有的权限:应用只需 wordpress 库,账号只用 localhost
# 绝对不要给 root 开远程登录(第 9 章红线)
12.5PHP 与 PHP-FPM:动态请求的执行者
# Ubuntu 默认源版本较新:
sudo apt install php8.3-fpm php8.3-mysql php8.3-curl php8.3-gd \
php8.3-mbstring php8.3-xml php8.3-zip
# Rocky 默认 PHP 版本旧,用 Remi 源装新版(第 6 章社区源):
sudo dnf install https://rpms.remirepo.net/enterprise/remi-release-9.rpm
sudo dnf module reset php -y && sudo dnf module enable php:remi-8.3 -y
sudo dnf install php php-fpm php-mysqlnd php-curl php-gd php-mbstring php-xml php-zip
sudo systemctl enable --now php8.3-fpm # Rocky: php-fpm
ss -tlnp | grep 9000 # 或在监听 unix socket
PHP-FPM 是什么:PHP 以 FastCGI 进程池方式常驻(比老的 mod_php 更省内存更稳定),Nginx 把 .php 请求交给它。它监听 9000 端口或 unix socket;两者在 Nginx 的 fastcgi_pass 里对应配置。
12.6串联:部署一个真实 WordPress(LNMP 全家桶验收)
sudo mkdir -p /data/web/example && cd /data/web/example
sudo wget https://wordpress.org/latest.tar.gz && sudo tar -xzf latest.tar.gz --strip-components=1
# 下载 WordPress,解压到站点目录(注意属主,见 12.7)
sudo chown -R www-data:www-data /data/web/example
# 创建数据库与用户(见 12.4),复制配置模板:
sudo cp wp-config-sample.php wp-config.php
sudo vim wp-config.php # 填 DB_NAME/DB_USER/DB_PASSWORD 与 DB_HOST=localhost
# Nginx 配置已含 PHP location(12.3),reload 后浏览器访问域名即进入安装页
sudo nginx -t && sudo systemctl reload nginx
验收清单:浏览器打开域名 → WordPress 安装向导 → 填库信息 → 上线。全程没有面板,全程每步都能解释「为什么」。这就是「高手感」的来源。
12.7站点目录与权限规范(LNMP 的常见漏洞来源)
- 站点根目录:/data/web/站点名(数据与系统分离,第 3 章)。
- 属主:文件属主设为
www-data(Ubuntu,PHP-FPM 用户)/nginx(Rocky),权限755目录 /644文件。 - 上传目录(wp-content/uploads)需要写:目录
775或设组 www-data;绝不 777。 - 禁止执行上传目录里的 PHP(防 webshell):在 Nginx 加
location ~ \.php$ { deny all; }于 uploads 下。 - 备份重点:/data/web 全部 + 数据库 dump + /etc/nginx、/etc/php 配置(第 17 章)。
12.8HTTPS:Let's Encrypt 免费证书(certbot 一条命令)
sudo apt install certbot python3-certbot-nginx # Rocky: dnf install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com
# 自动改 Nginx 配置开启 HTTPS + 自动续期任务(certbot 已内置 timer/cron)
sudo certbot renew --dry-run # 验证续期配置正常
# 强制跳转 HTTPS:Nginx 里加 return 301 https://$host$request_uri;
12.9宝塔替代方案对比(按你的需求选)
| 方案 | 特点 | 适合 | 代价 |
|---|---|---|---|
| 纯命令行(本章路线) | 零多余服务、最省资源、完全可控、技能本身保值 | 想真正学会、追求资源与自由 | 需要学习投入(你正在做) |
| Cockpit | 红帽官方 Web 管理:状态/日志/服务,极轻量无广告 | 要 Web 看板但不要全家桶 | 不管理站点配置细节 |
| 1Panel(开源) | 类宝塔的开源面板,Docker 架构,口碑较好 | 想要面板体验但反感广告/闭源 | 仍是面板,仍有学习依赖风险 |
| Webmin | 老牌全功能 Web 管理 | 传统环境 | 界面老旧、攻击面较大需加固 |
给你的行动建议
先按本章手动搭一遍 LNMP(理解全部原理);日常状态用 Cockpit + 命令行;等手动熟练后,若仍想要「建站快」,再评估 1Panel —— 届时你会带着判断力选它,而不是被它绑架。
本章自测题
- 面板的「一键装环境/建站/装证书/防火墙」分别对应什么底层操作?
- Nginx 的 server/location 段各管什么?改配置后两个必做动作?
- PHP-FPM 是什么?Nginx 怎么把 PHP 请求转给它?
- 建数据库用户的正确姿势(库/用户/授权,至少 4 条命令)。
- 站点目录属主应该是什么?上传目录权限多少?为什么不能 777?
- 免费 HTTPS 证书怎么申请与自动续期?
- 说出宝塔的三个替代方案与各自的取舍。
参考答案
1. apt/dnf 装环境、生成 Nginx server 配置、certbot 装证书、ufw/firewalld+fail2ban。
2. server=一个站点;location=路径规则(静态/php 转发);nginx -t 验证 + systemctl reload。
3. PHP 常驻进程池(FastCGI);location ~ \.php$ 里 fastcgi_pass 指向 socket/9000。
4. CREATE DATABASE ...; CREATE USER ...; GRANT ...; FLUSH PRIVILEGES;(应用只用 localhost 与专属库)。
5. www-data(Rocky: nginx);上传目录 775/组写;777 等于允许任意用户写,是 webshell 温床。
6. certbot --nginx -d 域名;certbot renew --dry-run 验证自动续期。
7. 纯命令行(零成本最自由)、Cockpit(轻量 Web 状态)、1Panel(开源面板替代宝塔)。