跳到主要内容
注册无需实名认证
安云主机 AnYun VPS

教程 · 建站与 Web

在 Debian 12 上用 LNMP 手工部署 WordPress

难度

进阶

预计时长

45 分钟

步骤

9

最近修订

基准系统

Debian 12

要点

在 Debian 12 上用 LNMP 手工部署 WordPress

LNMP 指 Linux + Nginx + MariaDB/MySQL + PHP-FPM。在 Debian 12 上依次安装 nginx、mariadb-server 与 php8.2-fpm 及常用扩展,建库建用户,把 WordPress 解压到站点目录并设好属主,最后写一段带 fastcgi_pass 的 server 块。全程约 45 分钟,比装面板费时,但每个组件在哪、怎么改,你都清楚。

前置条件

开始之前,先确认这些都具备

  • 一台至少 2 GB 内存的服务器(1 GB 也能跑,但必须配 swap 并调低 php-fpm 并发)
  • 一个已解析到该服务器的域名
  • 已完成基础加固与防火墙配置

操作步骤

9

  1. 步骤 01 / 09

    安装 Nginx、MariaDB 与 PHP-FPM #

    PHP 版本随发行版走:Debian 12 是 8.2,Ubuntu 24.04 是 8.3,命令里的版本号要跟着改。下面这套扩展是 WordPress 与主流插件的常见依赖,缺 gd 或 mbstring 会在后台看到功能异常。

    Shell
    sudo apt update
    sudo apt install -y nginx mariadb-server \
      php8.2-fpm php8.2-mysql php8.2-xml php8.2-curl \
      php8.2-gd php8.2-mbstring php8.2-zip php8.2-intl
    
    php -v
    systemctl status php8.2-fpm --no-pager
  2. 步骤 02 / 09

    初始化数据库的安全设置 #

    这一步会设置 root 认证方式、移除匿名用户与测试库。全部选是即可,不需要犹豫。

    Shell
    sudo mariadb-secure-installation
  3. 步骤 03 / 09

    建库与建用户 #

    字符集必须是 utf8mb4,否则文章里的表情符号会导致写入失败。权限只授予这一个库,绝不要让站点使用 root 账号连数据库 —— 一个插件漏洞就会变成整台数据库服务器的沦陷。

    SQL
    -- sudo mariadb
    CREATE DATABASE wordpress DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
    CREATE USER 'wpuser'@'localhost' IDENTIFIED BY '换成一个强密码';
    GRANT ALL PRIVILEGES ON wordpress.* TO 'wpuser'@'localhost';
    FLUSH PRIVILEGES;
    EXIT;
  4. 步骤 04 / 09

    下载 WordPress 并设置属主与权限 #

    中文版从 cn.wordpress.org 下载。权限用符号写法一次到位:目录 755、文件 644,属主 www-data。这样 PHP 能读能写上传目录,而其他用户不能改站点文件。

    Shell
    cd /tmp
    curl -LO https://cn.wordpress.org/latest-zh_CN.tar.gz
    tar -xzf latest-zh_CN.tar.gz
    
    sudo mv wordpress /var/www/example.com
    sudo chown -R www-data:www-data /var/www/example.com
    sudo chmod -R u=rwX,go=rX /var/www/example.com
  5. 步骤 05 / 09

    调整 PHP 的上传与内存限制 #

    默认值对 WordPress 偏紧:上传一张手机拍的图片就可能超限。改完必须 reload php-fpm,改 php.ini 而不重载是新手最常见的「改了没生效」。

    Shell
    sudo sed -i 's/^upload_max_filesize = .*/upload_max_filesize = 32M/' /etc/php/8.2/fpm/php.ini
    sudo sed -i 's/^post_max_size = .*/post_max_size = 32M/'             /etc/php/8.2/fpm/php.ini
    sudo sed -i 's/^memory_limit = .*/memory_limit = 256M/'              /etc/php/8.2/fpm/php.ini
    sudo sed -i 's/^max_execution_time = .*/max_execution_time = 120/'   /etc/php/8.2/fpm/php.ini
    
    sudo systemctl reload php8.2-fpm
    php -i | grep -E "upload_max_filesize|memory_limit"
  6. 步骤 06 / 09

    写 Nginx 站点配置 #

    try_files 那一行是固定链接能正常工作的关键,缺了它文章页会全是 404。下面几条 deny 规则拦住的是最常被扫描的攻击面:上传目录里的 PHP 文件、xmlrpc.php 以及隐藏文件。

    Nginx 配置
    # /etc/nginx/sites-available/example.com
    server {
        listen 80;
        server_name example.com www.example.com;
        root /var/www/example.com;
        index index.php index.html;
    
        client_max_body_size 32m;
    
        location / {
            try_files $uri $uri/ /index.php?$args;
        }
    
        location ~ \.php$ {
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        }
    
        # 上传目录里不应该有可执行的 PHP
        location ~* /wp-content/uploads/.*\.php$ {
            deny all;
        }
    
        location = /xmlrpc.php {
            deny all;
        }
    
        location ~ /\. {
            deny all;
        }
    }
  7. 步骤 07 / 09

    启用站点并完成安装向导 #

    浏览器打开域名,按提示填入刚才建的数据库名、用户与密码。装完立刻签证书 —— 后台登录密码走明文 HTTP 传输是不可接受的。

    Shell
    sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
    sudo rm -f /etc/nginx/sites-enabled/default
    sudo nginx -t && sudo systemctl reload nginx
    
    sudo certbot --nginx -d example.com -d www.example.com \
      --agree-tos -m [email protected] --no-eff-email --redirect
  8. 步骤 08 / 09

    收紧 wp-config.php #

    安装完成后加三条:禁用后台文件编辑器(拿到一个后台账号就能改 PHP 代码,这是常见的提权路径)、把文件系统方式设为 direct(否则更新插件时会要 FTP 账号),以及把 wp-config.php 权限收到 640。密钥盐值从官方接口获取,别用默认值。

    PHP
    // 加到 wp-config.php 中 "That's all" 注释之前
    define('DISALLOW_FILE_EDIT', true);
    define('FS_METHOD', 'direct');
    define('WP_AUTO_UPDATE_CORE', 'minor');
    
    // 盐值从官方接口生成后整段替换:
    // https://api.wordpress.org/secret-key/1.1/salt/
  9. 步骤 09 / 09

    小内存机器要调低 php-fpm 并发 #

    每个 php-fpm 子进程都吃内存,默认的动态策略在 1–2 GB 的机器上很容易把内存耗尽,表现是访问量一大就 502。按内存量把 max_children 调小,比事后加内存便宜。

    配置文件
    ; /etc/php/8.2/fpm/pool.d/www.conf
    pm = dynamic
    pm.max_children = 8
    pm.start_servers = 2
    pm.min_spare_servers = 2
    pm.max_spare_servers = 4
    pm.max_requests = 500

常见错误

这一步最容易踩的坑

下面每一条都对应一个真实会发生的故障。先读完再动手,比出问题之后再回来查要省时间。

  • 为了解决权限问题直接 chmod -R 777。这会让任何一个可写入的漏洞都变成完整的站点接管。
  • 让站点使用数据库 root 账号。一个插件的 SQL 注入就等于整台数据库沦陷。
  • 缺少 try_files 那一行,固定链接全部 404,而首页却是正常的 —— 很多人会误以为是伪静态规则「不支持」。
  • 更新插件时被要求输入 FTP 账号,说明站点文件属主不是 php-fpm 运行的用户。改属主,别去装 FTP 服务。
  • 1 GB 内存不配 swap 就跑 WordPress + MariaDB,流量一来就被 OOM Killer 结束进程。
  • 手工搭好 LNMP 之后又装面板。面板会重写 Nginx 与 PHP 配置,两套管理方式打架,事故只是时间问题。
  • xmlrpc.php 与后台登录页长期暴露且无任何限速,是 WordPress 站点被爆破的主要入口。

这篇教程的边界

  • 命令以 Debian 12 为准。Ubuntu 与 Rocky Linux 的差异只在正文明确标注之处,未标注的部分请以你所用发行版的官方文档为准。
  • 示例中的 IP 来自文档保留段 203.0.113.0/24,域名为 example.com,端口为示意值。复制后必须替换成自己的值, 原样执行不会有任何效果。
  • 教程不能替代备份。任何会改动数据或线上流量的步骤,执行前先确认有一份验证过能恢复的备份。
  • 本站不提供任何用于绕过网络审查的配置或说明,这篇也不例外。

发现命令过时或有误,请发邮件到 [email protected]。 指出错误的邮件比沉默的旧文档有价值得多。

联系 工单
扫码
手机访问

扫码在手机上打开