Linux 运维与安全专家 12 · Web 服务与 LNMP 实战

第 12 章 · Web 服务与 LNMP 实战

阶段 C预计 8–10 小时宝塔替代的完整答案

你「不想用宝塔但自己又不会配置」的症结,在于不知道面板背后替你做了什么。本章亲手搭一套 LNMP(Linux + Nginx + MySQL + PHP)并部署一个真实站点,你会惊讶:面板 90% 的功能不过是几条命令加一个配置文件。学完再决定要不要面板,就是「会了之后的选择」而不是「不会的依赖」。

12.1面板到底替你做了什么(拆开看就不神秘了)

宝塔的功能底层其实是
一键装 Nginx/MySQL/PHPapt/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 架构总览:请求怎么走

浏览器 用户请求 Nginx(80/443) 静态文件直接返回 PHP-FPM(9000) 执行 PHP 代码 MySQL(3306) 读写数据 LNMP 请求链路:静态资源由 Nginx 直接给,动态请求转给 PHP-FPM 执行,数据存 MySQL。所有组件都以 systemd 服务运行(第 7 章管理它们)。

图 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   # 热重载(不中断连接)
/etc/nginx/conf.d/example.conf · 建一个网站
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:安装与安全初始化

终端 · 安装(Ubuntu 默认 MySQL;Rocky 默认 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:动态请求的执行者

终端 · 安装 PHP 8.3 与扩展
# 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 的常见漏洞来源)

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 —— 届时你会带着判断力选它,而不是被它绑架。

本章自测题

  1. 面板的「一键装环境/建站/装证书/防火墙」分别对应什么底层操作?
  2. Nginx 的 server/location 段各管什么?改配置后两个必做动作?
  3. PHP-FPM 是什么?Nginx 怎么把 PHP 请求转给它?
  4. 建数据库用户的正确姿势(库/用户/授权,至少 4 条命令)。
  5. 站点目录属主应该是什么?上传目录权限多少?为什么不能 777?
  6. 免费 HTTPS 证书怎么申请与自动续期?
  7. 说出宝塔的三个替代方案与各自的取舍。
参考答案
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(开源面板替代宝塔)。