WordPress 部署复盘
一、项目背景与目标
在 Ubuntu 22.04+ 系统上部署私人 WordPress 博客网站,与已有的 Nginx 文件共享服务共存。通过本地 hosts 解析域名访问博客和文件共享。
初始环境:
- Ubuntu 系统,已安装并运行 Nginx
- Nginx 已配置
/etc/nginx/sites-available/file-share用于文件目录浏览 - 服务器 IP:
192.168.x.x(示例,实际为内网地址) - 目标:博客 + 文件共享互不影响
二、部署架构设计
┌──────────────────────────────────────────────────────────────────────────────────┐
│ Nginx (80端口) │
├──────────────────────────────────────────────────────────────────────────────────┤
│ server_name: example.blog → /var/www/html/wordpress (博客)
│ server_name: file.example.blog + 192.168.x.x → /home/user/downloads (文件共享)
├──────────────────────────────────────────────────────────────────────────────────┤
│ PHP 8.3-FPM │
│ unix socket: php8.3-fpm.sock │
├──────────────────────────────────────────────────────────────────────────────────┤
│ MariaDB │
│ 数据库: wordpress 用户: wp_user │
└──────────────────────────────────────────────────────────────────────────────────┘
核心设计思路:
- 通过 Nginx 的
server_name指令区分不同服务 - WordPress 使用独立配置文件,与文件共享配置分离
- 客户端通过修改 hosts 文件实现域名解析(无需 DNS 服务器)
三、部署关键步骤及命令详解
步骤1:安装 LNMP 环境
1.1 安装 PHP 8.3
bash
sudo apt update
sudo apt install -y php8.3-fpm php8.3-mysql php8.3-gd php8.3-mbstring php8.3-curl
命令意图:
php8.3-fpm:PHP FastCGI 进程管理器,Nginx 通过它处理 PHP 请求php8.3-mysql:PHP 连接 MySQL/MariaDB 的扩展php8.3-gd:图像处理扩展,WordPress 生成缩略图必需php8.3-mbstring:多字节字符串处理,处理中文内容必需php8.3-curl:HTTP 请求库,WordPress 访问外部 API/更新时需要
1.2 安装 MariaDB
bash
sudo apt install -y mariadb-server
sudo systemctl enable mariadb --now
命令意图:
enable --now:同时执行"开机自启"和"立即启动"两个操作
1.3 安全初始化数据库
bash
sudo mysql_secure_installation
命令意图:交互式安全配置脚本,依次询问:设置 root 密码、删除匿名用户、禁止 root 远程登录、删除测试数据库。
1.4 创建 WordPress 数据库和用户
sql
CREATE DATABASE wordpress CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'wp_user'@'localhost' IDENTIFIED BY 'your_password';
GRANT ALL PRIVILEGES ON wordpress.* TO 'wp_user'@'localhost';
FLUSH PRIVILEGES;
命令意图:
CHARACTER SET utf8mb4:支持完整的 UTF-8 字符集(包括 emoji 表情)'wp_user'@'localhost':限定用户只能从本机连接,提高安全性FLUSH PRIVILEGES:让权限变更立即生效
步骤2:配置 Nginx 虚拟主机
2.1 文件共享配置(已有,仅展示关键部分)
nginx
server {
listen 80;
server_name file.example.blog 192.168.x.x; # 域名+IP双匹配
root /home/user/downloads;
location / {
autoindex on; # 开启目录列表
autoindex_exact_size off; # 显示文件大小为KB/MB而非字节
autoindex_localtime on; # 显示本地时间而非UTC
charset utf-8; # 支持中文文件名显示
}
}
2.2 WordPress 博客配置(新建)
nginx
server {
listen 80;
server_name example.blog www.example.blog;
root /var/www/html/wordpress;
index index.php index.html index.htm;
# URL 重写,实现伪静态
location / {
try_files $uri $uri/ /index.php?$args;
}
# PHP 请求代理到 FPM
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
}
# 禁止访问隐藏文件(安全防护)
location ~ /\. {
deny all;
}
# 静态资源缓存优化
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires max;
log_not_found off;
}
}
配置意图:
try_files $uri $uri/ /index.php?$args:WordPress 伪静态的核心配置。先尝试直接访问文件或目录,都不存在时交给index.php处理fastcgi_pass unix:/var/run/php/php8.3-fpm.sock:通过 Unix socket 连接 PHP-FPM,比 TCP 性能更好location ~ /\.:阻止访问.git、.env等敏感文件expires max:静态资源设置远期过期时间,减少重复请求
2.3 启用配置并重载
bash
sudo ln -s /etc/nginx/sites-available/wordpress /etc/nginx/sites-enabled/
sudo nginx -t # 测试配置文件语法
sudo systemctl reload nginx # 重载配置(不中断服务)
步骤3:部署 WordPress
3.1 下载并解压
bash
cd /tmp
wget https://wordpress.org/wordpress-6.6.tar.gz
sudo tar -xzf /tmp/wordpress-6.6.tar.gz -C /var/www/html/
命令意图:下载 WordPress 6.6 版本(兼容 PHP 8.3),解压到 Nginx 根目录
3.2 设置文件权限
bash
sudo chown -R www-data:www-data /var/www/html/wordpress
sudo chmod -R 755 /var/www/html/wordpress
命令意图:
www-data:Ubuntu 上 Nginx 和 PHP-FPM 的默认运行用户755:目录和文件所有者可读写执行,其他用户可读可执行
步骤4:配置 wp-config.php
php
<?php
define('DB_NAME', 'wordpress');
define('DB_USER', 'wp_user');
define('DB_PASSWORD', 'your_password');
define('DB_HOST', 'localhost');
define('DB_CHARSET', 'utf8mb4');
define('DB_COLLATE', '');
$table_prefix = 'wp_';
// 调试配置
define('WP_DEBUG', false);
@ini_set('display_errors', 0);
if (!defined('ABSPATH')) {
define('ABSPATH', __DIR__ . '/');
}
require_once ABSPATH . 'wp-settings.php';
配置意图:
WP_DEBUG:设为false禁止在前端显示错误@ini_set('display_errors', 0):强制关闭错误输出,@符号抑制可能的错误提示
四、问题与应对措施详解
问题1:PHP 版本依赖冲突
现象:
php-common : 破坏: php8.1-common 但是 8.1.2-1ubuntu2.23 正要被安装
E: 无法修正错误
原因: 系统中已有的 php-common 包与 php8.1-common 冲突。
应对措施:
bash
# 先检查系统中已有的 PHP 相关包
dpkg -l | grep php
# 移除冲突的旧包
sudo apt remove php-common
# 更新软件源后重新安装
sudo apt update
sudo apt install php8.3-fpm
有效性: ✅ 有效
缺陷: 如果系统中有其他应用依赖旧版 PHP,直接移除会导致它们无法运行。
问题2:DNS 解析到错误 IP
现象:
http://192.168.x.x能正常访问http://example.blog访问失败
原因: 客户端 hosts 文件中 IP 配置错误。
应对措施:
bash
# 1. 在服务器上确认实际 IP
ip a | grep "inet " | grep -v 127.0.0.1
# 输出示例:inet 192.168.x.x/24
# 2. 在客户端修正 hosts 文件
# Windows: C:\Windows\System32\drivers\etc\hosts
# Mac/Linux: /etc/hosts
# 添加:
192.168.x.x example.blog file.example.blog
# 3. 刷新 DNS 缓存
# Windows: ipconfig /flushdns
# Mac: sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
有效性: ✅ 有效
缺陷: 仅限修改的那台机器生效,局域网其他设备需要各自配置 hosts。
问题3:get_magic_quotes_gpc() 函数未定义
现象:
PHP Fatal error: Uncaught Error: Call to undefined function get_magic_quotes_gpc()
in /var/www/html/wordpress/wp-includes/load.php on line 651
原因: 此函数在 PHP 7.4 中被标记为废弃,PHP 8.0 中完全移除。部分 WordPress 版本仍有多处调用。
应对措施:
bash
# 方案:下载兼容版本(根本解决方案)
cd /tmp
wget https://wordpress.org/wordpress-6.6.tar.gz
sudo tar -xzf /tmp/wordpress-6.6.tar.gz -C /tmp/
sudo cp -a /tmp/wordpress/wp-admin /var/www/html/wordpress/
sudo cp -a /tmp/wordpress/wp-includes /var/www/html/wordpress/
sudo cp /tmp/wordpress/wp-*.php /var/www/html/wordpress/
有效性: ✅ 彻底解决,WordPress 6.6+ 已适配 PHP 8.x
缺陷: 旧版本 WordPress 站点若存量较大,升级核心文件需提前全量备份。
问题4:数据库表缺失
现象:
Table 'wordpress.wp_options' doesn't exist
Table 'wordpress.wp_terms' doesn't exist
原因: 手动清空数据库后安装流程中断,建表不完整。
应对措施:
sql
-- 用 WordPress 核心函数重建所有表
-- 执行 wp_install() 前需要运行:
sudo -u www-data php -r "
define('WP_INSTALLING', true);
require_once '/var/www/html/wordpress/wp-load.php';
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
wp_install('我的博客', 'admin_user', 'admin@example.blog', true, null, 'admin_password');
"
有效性: ✅ 有效
缺陷: 依赖 WordPress 自身加载流程,如果依赖的基础表不存在,函数本身也会失败。
问题5:管理员账号不存在
现象:
- 能进入登录页面
- 输入账号密码提示用户不存在
原因: 数据库表存在,但 wp_users 表为空。
应对措施:
sql
-- 直接用 SQL 创建管理员用户
INSERT INTO wp_users (user_login, user_pass, user_nicename, user_email, user_registered, display_name)
VALUES (
'admin_user',
'$2y$10$...', -- password_hash() 结果
'admin_user',
'admin@example.blog',
NOW(),
'admin_user'
);
INSERT INTO wp_usermeta (user_id, meta_key, meta_value)
VALUES
(1, 'wp_capabilities', 'a:1:{s:13:"administrator";b:1;}'),
(1, 'wp_user_level', '10');
有效性: ✅ 直接有效
缺陷: 需要了解 WordPress 用户元数据的序列化格式,手动拼写容易出错。
问题6:FastCGI 缓冲区溢出
现象:
- 页面 502 Bad Gateway
- 错误日志:
upstream sent too big header while reading response header from upstream
原因: PHP 输出的大量 Deprecated 警告超出了 Nginx 默认的 FastCGI 缓冲区大小。
应对措施:
bash
# 方案1:在 php.ini 中彻底关闭错误输出(治本)
sudo sed -i 's/^display_errors = .*/display_errors = Off/' /etc/php/8.3/fpm/php.ini
sudo sed -i 's/^display_startup_errors = .*/display_startup_errors = Off/' /etc/php/8.3/fpm/php.ini
# 方案2:增大 Nginx 缓冲区(辅助)
echo "fastcgi_buffer_size 128k;" | sudo tee -a /etc/nginx/conf.d/buffers.conf
echo "fastcgi_buffers 4 256k;" | sudo tee -a /etc/nginx/conf.d/buffers.conf
echo "fastcgi_busy_buffers_size 256k;" | sudo tee -a /etc/nginx/conf.d/buffers.conf
# 重启服务
sudo systemctl restart php8.3-fpm
sudo nginx -t && sudo systemctl reload nginx
有效性: ✅ 组合方案有效
缺陷: 单纯关闭 display_errors 而不升级 WordPress 版本,PHP 依然会在后台产生警告。
问题7:登录后仪表盘白屏
现象: 登录成功但页面空白,无报错,F12 无网络请求。
原因: 数据库中设置的主题在 wp-content/themes/ 目录中不存在。
应对措施:
bash
# 1. 检查可用主题
ls /var/www/html/wordpress/wp-content/themes/
# 2. 切换到存在的主题
sudo php -r "
\$mysqli = new mysqli('localhost', 'wp_user', 'your_password', 'wordpress');
\$mysqli->query(\"UPDATE wp_options SET option_value = 'twentysixteen' WHERE option_name = 'template'\");
\$mysqli->query(\"UPDATE wp_options SET option_value = 'twentysixteen' WHERE option_name = 'stylesheet'\");
\$mysqli->query(\"UPDATE wp_options SET option_value = 'twentysixteen' WHERE option_name = 'current_theme'\");
echo '已切换主题';
"
有效性: ✅ 有效
缺陷: 需要确认 wp-content/themes/ 中有可用主题。
问题8:WP_DEBUG 重复定义
现象:
PHP Warning: Constant WP_DEBUG already defined in wp-config.php on line 19
原因: 调试过程中多次向 wp-config.php 追加了 define('WP_DEBUG', false);
应对措施:
bash
# 方案:完整重写配置文件
sudo tee /var/www/html/wordpress/wp-config.php > /dev/null << 'EOF'
<?php
define('DB_NAME', 'wordpress');
define('DB_USER', 'wp_user');
define('DB_PASSWORD', 'your_password');
define('DB_HOST', 'localhost');
define('DB_CHARSET', 'utf8mb4');
define('DB_COLLATE', '');
$table_prefix = 'wp_';
define('WP_DEBUG', false);
@ini_set('display_errors', 0);
if (!defined('ABSPATH')) {
define('ABSPATH', __DIR__ . '/');
}
require_once ABSPATH . 'wp-settings.php';
EOF
有效性: ✅ 有效
缺陷: 完全重写时注意保留 $table_prefix 等自定义配置。
五、最终成功的完整部署方案
bash
# 1. 下载兼容 PHP 8.3 的 WordPress 6.6
cd /tmp
wget https://wordpress.org/wordpress-6.6.tar.gz
sudo tar -xzf wordpress-6.6.tar.gz -C /tmp/
# 2. 备份配置文件
sudo cp /var/www/html/wordpress/wp-config.php /tmp/wp-config.php.bak
# 3. 增量更新核心文件(保留 wp-content 和配置)
sudo cp -a /tmp/wordpress/wp-admin /var/www/html/wordpress/
sudo cp -a /tmp/wordpress/wp-includes /var/www/html/wordpress/
sudo cp /tmp/wordpress/wp-*.php /var/www/html/wordpress/
# 4. 恢复配置并关闭调试
sudo cp /tmp/wp-config.php.bak /var/www/html/wordpress/wp-config.php
sudo sed -i "s/define('WP_DEBUG', true);/define('WP_DEBUG', false);/" /var/www/html/wordpress/wp-config.php
# 5. 修复权限
sudo chown -R www-data:www-data /var/www/html/wordpress
sudo chmod -R 755 /var/www/html/wordpress
# 6. PHP 全局关闭错误显示
sudo sed -i 's/^display_errors = .*/display_errors = Off/' /etc/php/8.3/fpm/php.ini
# 7. 重启所有服务
sudo systemctl restart php8.3-fpm
sudo systemctl restart nginx
# 8. 浏览器访问,点击"Update WordPress Database"完成升级
六、经验教训
| 序号 | 教训 | 详细说明 |
|---|---|---|
| 1 | 版本匹配是基础 | 部署前确认 WordPress 版本与 PHP 版本的兼容性。PHP 8.3 + WordPress 6.6 是经过验证的稳定组合 |
| 2 | 慎用手动操作数据库 | 直接 SQL 建表容易遗漏字段和索引,WordPress 的 wp_install() 是更可靠的选择 |
| 3 | 错误日志是定位问题第一手资料 | sudo tail -f /var/log/nginx/error.log 是排查 PHP 问题的核心入口 |
| 4 | 增量更新优于全量重装 | 覆盖核心文件时保留 wp-content 和 wp-config.php,避免丢失上传内容和配置 |
| 5 | 生产环境务必关闭错误显示 | WP_DEBUG=false + php.ini 中 display_errors=Off,两者缺一不可 |
| 6 | hosts 文件是双刃剑 | 本地调试方便,但也容易因忘记修改而误导排查方向 |
| 7 | sed -i 操作前先备份 |
批量替换时极易破坏文件语法结构,大范围正则替换前先备份原文件 |
| 8 | 502 Bad Gateway 不一定是服务挂了 |
可能只是响应头太大,检查 upstream sent too big header 关键字 |
七、部署检查清单
-
http://192.168.x.x→ 文件共享正常访问 -
http://file.example.blog→ 文件共享正常访问 -
http://example.blog→ WordPress 博客首页正常显示 -
http://example.blog/wp-admin/→ 后台登录正常 -
sudo tail /var/log/nginx/error.log→ 无 PHP Fatal 错误 -
sudo systemctl status nginx php8.3-fpm mariadb→ 三个服务均为 active - 上传图片测试 →
wp-content/uploads目录有写入权限 - 固定链接设置为"文章名" → 伪静态正常工作