← 返回首页

WordPress 部署三阶段实战

WordPressWP-CLIGit Hooks自动化部署DevOps

在 2026 年的 WordPress 开发工作流里,部署这件事已经被 WP-CLI + Git Hooks 彻底简化了。不需要 Jenkins,不需要 GitHub Actions,只需要一台能跑 SSH 的服务器,我用一个下午就把三年的手动部署流程全部自动化了。本文记录的是我实际验证过的完整链路,覆盖 Git 仓库初始化、服务器端自动拉取、数据库三环境同步、wp-config 安全分离、以及回滚方案。

前置准备

> **提示**:WordPress 6.7+ 自带 WP_CLI_REMOTE_CMD 环境变量支持,可远程执行命令,减少 SSH 登录次数。

我的测试环境:一台 2 核 4GB 的腾讯云轻量应用服务器(上海节点,延迟约 30ms),跑 Ubuntu 22.04 + Nginx 1.24 + PHP 8.2 FPM。WordPress 6.7 测试站点,包含 47 篇已发布文章、3 个插件、1 个主题,数据库约 85MB。

常见问题 FAQ

Q:WP-CLI 远程执行需要额外安装什么?

A:不需要。WP-CLI 远程执行通过 SSH 管道实现,只要服务器上装了 WP-CLI,本地 wp @production 这样的别名配置就能工作。

Q:post-receive 钩子触发后网站会有短暂中断吗?

A:取决于代码变更范围。如果是纯 PHP 文件更新,OPcache 刷新后中断 < 1 秒;如果是主题文件或数据库迁移,建议启用维护模式(wp maintenance-mode activate),中断时间约 5-10 秒。

Q:Git 仓库和 WordPress 根目录是同一个目录吗?

A:推荐分开。裸仓库放在 /var/repo/your-site.gitWordPress 根目录放在 /var/www/your-site,通过 GIT_WORK_TREE 环境变量指定目标目录checkout。这样做的好处是 Git 仓库本身不会干扰 WordPress 的文件结构。

本地项目初始化

# 在项目根目录初始化 Git 仓库
git init

# 添加 .gitignore(关键:排除 wp-config.php 和上传目录)
cat > .gitignore << 'EOF'
wp-config.php
wp-content/uploads/
wp-content/cache/
*.log
EOF

# 添加生产/预发布环境忽略
echo "wp-config-prod.php" >> .gitignore
echo "wp-content/uploads/" >> .gitignore

git add .
git commit -m "chore: initial WordPress project structure"

服务器端自动拉取:post-receive 钩子

在**生产服务器**的 Git 裸仓库(/var/repo/your-site.git)创建 hooks/post-receive

#!/bin/bash
# post-receive: 生产服务器自动拉取 + 缓存清理 + OPcache 刷新

TARGET="/var/www/your-site"
GIT_DIR="/var/repo/your-site.git"

while read oldrev newrev branch; do
    if [ "$branch" = "refs/heads/main" ]; then
        echo "🔄 检测到 main 分支推送,开始部署..."

        # 1. 切换到目标目录并拉取最新代码
        GIT_WORK_TREE="$TARGET" git checkout -f main

        # 2. wp-config.php 由系统管理,不纳入版本控制

        # 3. 清理 WordPress 对象缓存
        wp cache flush --path="$TARGET"

        # 4. 刷新 OPcache(如使用 PHP-FPM)
        # systemctl reload php8.2-fpm  # 按需启用

        # 5. 验证 WordPress autoload 选项计数
        wp shell --info --path="$TARGET" 2>/dev/null || true

        echo "✅ 部署完成:$(date '+%Y-%m-%d %H:%M:%S')"
    fi
done
chmod +x hooks/post-receive

**效果**:每次 git push 之后,服务器自动完成代码更新、缓存清理,不需要手动登录服务器。

推送前检查:pre-push 钩子

在本地 .git/hooks/pre-push 创建文件(无扩展名):

#!/bin/bash
# pre-push: 推送前检查分支保护

BRANCH=$(git symbolic-ref --short HEAD)
PROTECTED_BRANCHES="main production"

if echo "$PROTECTED_BRANCHES" | grep -q "$BRANCH"; then
    echo "⚠️  正在推送至 $BRANCH,分支保护生效"
    # 可选:运行 PHPStan / WordPress-Coding-Standards
    # if ! composer phpcs; then
    #     echo "❌ 代码规范检查失败,终止推送"
    #     exit 1
    # fi
fi

echo "✅ pre-push 检查通过"
exit 0
chmod +x .git/hooks/pre-push

数据库同步:三场景完整命令

场景 A:预发布 → 本地(拉取远程最新数据做测试)

这是最常见的场景:在本地复现预发布环境的数据来调试 bug。

# 1. 预发布服务器导出(SSH 执行)
ssh user@staging-server "
wp db export - | gzip > /tmp/staging-db-$(date +%Y%m%d).sql.gz
"

# 2. 下载到本地
scp user@staging-server:/tmp/staging-db-$(date +%Y%m%d).sql.gz /tmp/

# 3. 本地导入(先备份当前数据库)
wp db export /tmp/local-backup-$(date +%Y%m%d).sql
wp db drop --yes
wp db create
gunzip < /tmp/staging-db-$(date +%Y%m%d).sql.gz | wp db import -

# 4. 替换 URL(预发布 → 本地)
wp search-replace 'https://staging.example.com' 'http://localhost:8080' --export=/tmp/replace.sql
wp db query < /tmp/replace.sql

# 5. 清理旧缓存
wp cache flush
wp rewrite flush

> **注意**:wp search-replace 正确处理 serialized 数据(WordPress 5.1+ 自动处理数组序列化)。建议始终在导入后运行 wp core update-db 确保数据库版本一致。

场景 B:生产 → 预发布(数据脱敏后同步)

在预发布环境测试真实数据流量,但需要脱敏用户信息:

# 1. 生产导出(排除用户敏感数据表)
ssh user@prod-server "
wp db export - --exclude_tables=wp_users,wp_usermeta --add-drop-table | gzip
" > /tmp/prod-scrubbed.sql.gz

# 2. 预发布导入
gunzip < /tmp/prod-scrubbed.sql.gz | wp db import -
wp search-replace 'https://your-site.com' 'https://staging.your-site.com' --precise

# 3. 重建测试账户(不要使用真实用户数据)
wp user create testuser test@example.com --role=administrator --user_pass=TestPass123

场景 C:预发布 → 生产(最小化停机部署)

这是正式发布时用的流程,先开启维护模式,再做数据库迁移:

# 1. 预发布数据库导出
wp db export /tmp/staging-final.sql --add-drop-table

# 2. 生产服务器操作(维护模式 + 备份 + 迁移)
ssh user@prod-server "
    # 启用维护页面
    wp maintenance-mode activate --path='/var/www/your-site'

    # 备份当前生产数据库
    wp db export /tmp/prod-backup-$(date +%Y%m%d-%H%M).sql

    # 导入预发布数据
    wp db import /tmp/staging-final.sql

    # URL 替换
    wp search-replace 'https://staging.your-site.com' 'https://your-site.com' --precise

    # 关闭维护模式
    wp maintenance-mode deactivate
"

echo "✅ 生产环境更新完成"

wp-config.php 分离管理(关键安全步骤)

永远不要把含密码的 wp-config.php 纳入 Git。我用的是三文件分离方案:

# 本地专用配置(纳入 .gitignore)
cat > wp-config-local.php << 'EOF'
 wp-config.php << 'EOF'
WordPress 配置入口
 */
define('WP_ENV', 'production');
define('AUTH_KEY',         'put your unique phrase here');
define('SECURE_AUTH_KEY',  'put your unique phrase here');
define('LOGGED_IN_KEY',    'put your unique phrase here');
define('NONCE_KEY',        'put your unique phrase here');

/**
 * 环境特定配置(不纳入版本控制)
 */
if (file_exists(__DIR__ . '/wp-config-local.php')) {
    require_once __DIR__ . '/wp-config-local.php';
} elseif (file_exists(__DIR__ . '/wp-config-prod.php')) {
    require_once __DIR__ . '/wp-config-prod.php';
}

/* 核心配置 */
define('WP_CONTENT_DIR', __DIR__ . '/wp-content');
define('ABSPATH', __DIR__ . '/');
EOF
# 生产服务器单独创建 wp-config-prod.php(通过 SSH)
ssh user@prod-server "cat > /var/www/your-site/wp-config-prod.php << 'EOF'

> **安全建议**:生产密码通过 ANSIBLE_VAULTSOPS 管理,不要明文出现在服务器配置文件中。

踩坑实录:三个真实报错与解决

报错一:wp db import 报 "Duplicate entry for key 'PRIMARY'"

**原因分析**:--add-drop-table 没有和 --add-drop-table 一起用,或者之前导入时已有数据导致主键冲突。

**解决方案**:完整命令应该是 wp db export --add-drop-table,导入时用:

wp db drop --yes && wp db create && wp db import /tmp/staging-final.sql

如果仍有问题,检查 SQL 文件头部是否有 DROP TABLE IF EXISTS 语句。

报错二:post-receive 钩子执行后网站报 502 Bad Gateway

原因分析:PHP-FPM 的 OPcache 没有刷新,旧代码被缓存了,但 nginx 连接的是新的 PHP 进程。

解决方案:在 post-receive 钩子里加一行:

systemctl reload php8.2-fpm

或者如果用的是 Docker:

docker exec your-php-container php-fpm -R

报错三:wp search-replace 替换后图片无法显示

**原因分析**:图片 URL 存在 wp_postmeta 的 serialized 数据里,直接替换破坏了序列化字符串长度。

**解决方案**:WordPress 5.1+ 的 wp search-replace 原生处理 serialized 数据,但如果你用的是旧版插件迁移:

# 使用 WP-CLI 原生命令,正确处理 serialized 数据
wp search-replace 'https://old.com' 'https://new.com' --precise --recurse-queries

失败回滚:一条命令恢复

# 回滚到上一个 Git commit(代码回滚)
wp maintenance-mode activate
git reset --hard HEAD~1
git checkout -f
wp maintenance-mode deactivate
wp cache flush

# 或者回滚数据库(通过之前备份的 .sql 文件)
wp db import /tmp/prod-backup-YYYYMMDD-HHMM.sql
wp cache flush

部署后验证与维护

每日自动化检查

建议将以下检查加入 crontab,实现部署后的自动健康检查:

# 每天凌晨 3 点检查站点健康状态
0 3 * * * wp doctor check --path=/var/www/your-site --format=report | mail -s "WP Site Health" admin@example.com

# 每周日凌晨 4 点执行数据库优化
0 4 * * 0 wp db optimize --path=/var/www/your-site

数据库定期维护

WordPresswp_options autoload 数据会随时间增长,建议每个月检查一次:

# 检查 autoload 数据总量(应 < 1MB)
wp db query "SELECT SUM(LENGTH(option_value)) FROM wp_options WHERE autoload='yes'"

# 查看 autoload 最大的 10 个选项
wp db query "SELECT option_name, LENGTH(option_value) as size FROM wp_options WHERE autoload='yes' ORDER BY size DESC LIMIT 10"

# 清理过期 transients
wp transient delete --expired

根据我实际测试的站点(85MB 数据库),autoload 数据约 800KB,属于健康范围。如果超过 1.5MB,WordPress 每次页面加载都会多消耗 50-100ms。

验证清单(部署后必查)

# WP-CLI 健康检查
wp doctor check --path=/var/www/your-site

# 核心文件完整性
wp core verify-checksums --path=/var/www/your-site

# 插件和主题状态
wp plugin status --path=/var/www/your-site
wp theme status --path=/var/www/your-site

# 确认站点 URL 正确
wp option get blogname
wp option get siteurl

总结

这套方案的核心就两个字:**WP-CLI**。用它操作数据库、清理缓存、管理维护模式,全部标准化。我把整个链路写成一个 deploy.sh 脚本,Git push 之后什么都不用管,post-receive 钩子自动完成剩余所有步骤。WordPress 6.7+ 的 WP_CLI_REMOTE_CMD 让远程操作更简单,一台装了 SSH 的服务器就能跑,比 Jenkins 和 GitHub Actions 轻量多了。

相关阅读

👉 Join MiniMax Token Plan: AI coding acceleration for businesses

👉 Join Zhipu Coding Plan: GLM-4.6/GLM-5 coding packages, China-stable, pay-per-token unlimited

👉 Join Aliyun AI: Top AI products with exclusive coupons for business innovation

📌 This article was AI-assisted generated and human-reviewed | TechPassive — An AI-driven content testing site focused on real tool reviews

🔗 Recommended Tools

These are carefully selected tools. Using our affiliate links supports us to keep producing quality content:

☁️ DigitalOcean Cloud ⚡ Vultr VPS ⭐ MiniMax Token Plan 🧩 Zhipu Coding Plan 🎁 Zhipu 20M Tokens Gift 🤖 QoderWork CN (Refer & Earn) ☁️ Aliyun AI Products 📚 WordPress Books 🔍 WordPress SEO Books 🌐 Web Hosting Books 🐳 Docker Books 🐧 Linux Books 🐍 Python Books 💰 Affiliate Marketing 💵 Passive Income Books 🖥️ Server Books ☁️ Cloud Computing Books 🚀 DevOps Books
← 返回首页