最新Ubuntu用宝塔部署WordPress,生产环境上线前证书与备份应核对哪些事项?
在最新的 Ubuntu 系统上安装宝塔和 WordPress,生产环境上线前不能只看面板能否打开、首页能否访问。真正需要核对的是:域名是否指向正确入口,Nginx 与 PHP-FPM 是否形成正确请求链路,证书是否覆盖所有实际访问域名并能自动续期,日志是否能定位 4xx、5xx 和进程问题,以及数据库、网站文件和配置是否都能从独立位置恢复。
证书与备份的验收也不是两个孤立动作。证书要从 DNS、80/443 端口、证书内容和续期任务逐层验证;备份要同时包含数据库和网站文件,并在隔离环境完成一次恢复检查。下面以受支持的 Ubuntu LTS 版本为例,具体以服务器实际系统和宝塔当前安装器兼容范围为准。2 vCPU、4 GB 内存、40 GB SSD 可以作为小型内容站的起步参考,但图片数量、访问量、插件、数据库增长和备份保留周期都会改变资源需求,不能当成固定配置。
先确定入口、资源和安全边界
宝塔部署普通 WordPress 时,常见链路是:
用户浏览器
↓ HTTPS
Nginx(宝塔网站入口)
↓ FastCGI
PHP-FPM
↓
WordPress
↓
MySQL 或 MariaDB
如果前面还有 CDN、负载均衡或其他企业 HTTP 入口,则链路会变成:
用户浏览器
↓ HTTPS
前置入口
↓ HTTP/HTTPS
宝塔所在服务器的 Nginx
↓ FastCGI
PHP-FPM
这里要先区分“反向代理”和 PHP-FPM 转发。普通 WordPress 的 PHP 请求通常由 Nginx 通过 fastcgi_pass 交给 PHP-FPM,这不等同于 HTTP 反向代理。只有后端存在独立 HTTP 服务,例如应用监听在 127.0.0.1:8080,才需要使用 proxy_pass。不要为了满足“反向代理”这个说法,把 proxy_pass 和 PHP-FPM 的 location ~ \.php$ 同时套进普通 WordPress 配置,否则可能出现重复转发、502 或请求路径不一致。

安装前应准备好以下条件:
- 具备 root 或 sudo 权限的 SSH 账号。
- 已注册并可修改 DNS 的域名;使用 IPv6 时还要能核对 AAAA 记录。
- 云平台安全组和服务器本机防火墙允许 SSH、HTTP、HTTPS。
- 服务器上没有正在占用 80、443、3306 的旧版 Nginx、Apache 或数据库服务。
- 最好使用干净系统,不要在已经运行多个业务的服务器上直接安装面板。
- 已确定备份存储位置,至少有一份备份位于当前服务器之外。
- 已安排维护时间。系统升级、服务重载和站点切换都可能造成短暂中断。
先核对系统、架构、内存、磁盘和监听端口,不要直接执行安装脚本:
cat /etc/os-release
uname -m
free -h
df -h
timedatectl status
ss -lntp
如果是新装服务器,可以更新软件包。执行前先创建云主机快照,或确认服务器上没有正在运行的生产业务;内核和关键库升级后可能需要重启,出现异常时通常通过恢复快照或切换旧系统盘回滚。
sudo apt update
sudo apt upgrade
防火墙调整时,必须先保留当前 SSH 来源,避免把自己锁在服务器外。下面的 203.0.113.10 是文档保留地址,只能作为示例,应替换为实际管理出口。如果 SSH 来源不固定,可以先通过云安全组限制面板端口,再在服务器上逐步收紧规则。
sudo ufw status verbose
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow from 203.0.113.10 to any port 8888 proto tcp
sudo ufw status numbered
先从另一条 SSH 连接确认新规则有效,再考虑执行 ufw enable。规则有误时,可以使用 sudo ufw status numbered 查看编号并删除对应规则,但删除前必须确认 SSH 放行规则仍然存在。数据库端口通常不应直接暴露公网;面板端口也不应当当作网站端口,网站对外通常只需要 80 和 443。
安装宝塔并创建独立的 WordPress 站点
宝塔的 Ubuntu 安装入口和脚本地址可能随版本调整,应以宝塔官网当前提供的 Ubuntu 安装方式为准。下面只展示常见的下载、检查和执行流程:
curl -fL --proto '=https' --tlsv1.2 \
-o /tmp/bt-install.sh \
'https://download.bt.cn/install/install-ubuntu_6.0.sh'
less /tmp/bt-install.sh
sudo bash /tmp/bt-install.sh
执行前要核对下载域名、脚本内容和系统兼容范围。不要把来源不明的脚本直接交给 bash。如果官网已经更换安装地址,旧地址失败时不要反复执行,也不要从非官方转载页面复制带有额外参数的命令。
安装完成后记录面板访问地址、面板端口和初始登录信息,并立即完成这些操作:
- 修改面板管理员密码,不继续使用安装器生成的简单密码。
- 将面板端口限制为管理出口可访问。
- 如果当前版本提供,开启面板登录保护或二次验证。
- 将面板配置、站点配置和计划任务纳入备份范围。
- 不把面板端口、数据库端口直接暴露给所有公网地址。
在宝塔软件管理中选择明确的运行环境组合:Nginx 作为网站入口,MySQL 或 MariaDB 使用当前环境支持的版本,PHP 选择与 WordPress 和插件兼容的版本,并按实际插件需要安装扩展。常见扩展包括 curl、dom、fileinfo、gd、mbstring、mysqli、openssl、pdo_mysql 和 zip。可以开启 PHP OPcache,但不能为了缓存而挤压 PHP-FPM、数据库和系统所需内存。
“最新 Ubuntu”不代表 PHP、数据库和所有插件都应该无条件选择最新版本。对于依赖多年未更新插件的站点,应先在测试站验证 PHP 和数据库兼容性,再决定生产版本,不要上线后才通过整体降级来处理兼容问题。
创建站点时,建议一次完成以下设置:
- 添加主域名和实际使用的
www域名。 - 使用独立的网站根目录,例如
/www/wwwroot/example.com。 - 创建独立数据库和独立数据库用户,不让多个站点共用 WordPress 数据库账号。
- 数据库字符集使用
utf8mb4。 - 选择已经验证兼容的 PHP 版本。
- 使用宝塔生成的 WordPress 重写规则,或在确认站点类型后手动核对。
- 不把数据库密码写入公开文档、工单或命令历史。
随后通过宝塔应用部署或上传 WordPress 文件。若证书尚未签发,可以暂时用 HTTP 完成初始安装,但正式上线前必须把站点地址、后台地址和页面资源统一切换到 HTTPS。数据库表前缀可以改为随机字符串,降低明显的默认特征,但这不能替代权限控制、更新和备份。
核验 Nginx、PHP-FPM、计划任务和资源边界
WordPress 的固定链接依赖 Nginx 将不存在的静态文件交给 index.php。常见规则如下:
location / {
try_files $uri $uri/ /index.php?$args;
}
PHP 请求则要交给实际运行的 PHP-FPM 套接字或端口。不同 PHP 版本、宝塔安装方式和系统环境路径可能不同,不要直接猜测,可以先检查宝塔生成的配置:
grep -R "fastcgi_pass" /www/server/panel/vhost/nginx/ 2>/dev/null
配置中可能看到类似内容:
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/实际环境中的/php-fpm.sock;
}
这里的套接字路径只是格式示例,必须替换为实际路径,并确认该文件确实存在。面板已经生成完整 PHP 配置时,优先通过面板修改 PHP 版本和站点设置,不要直接覆盖整份 Nginx 配置。修改前保存原配置,修改后先测试语法,再平滑重载:
sudo nginx -t
sudo systemctl reload nginx
nginx -t 失败时不要重载。回滚时恢复修改前的站点配置,再次执行 nginx -t,确认通过后才重载。
只有后端确实存在独立 HTTP 服务时,才使用类似下面的反向代理配置:
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_http_version 1.1;
}
使用前先确认后端正在监听:
sudo ss -lntp | grep ':8080'
没有监听服务时,proxy_pass 会导致 502。如果 HTTPS 在前置入口终止,宝塔 Nginx 收到的可能是 HTTP,此时前置入口要正确传递 X-Forwarded-Proto: https。WordPress 只应信任来自受控前置入口的协议头,否则可能出现后台反复跳转、混合内容或 HTTP/HTTPS 重定向循环。
PHP-FPM 的进程数量不能只看 CPU,也不能把并发进程数直接当成每秒请求数。一个更稳妥的初步估算是:
可分配给 PHP-FPM 的内存 ÷ 单个 PHP-FPM 进程平均内存
例如服务器有 4 GB 内存,扣除系统、数据库、Nginx、面板和文件缓存后只剩约 1.5 GB;如果单个 PHP 进程平均占用约 80 MB,理论上限约为 18 个进程。考虑突发流量和其他服务,pm.max_children 可以先从 10~12 个开始观察,而不是直接设为 50。这个计算只用于估算同时运行的 PHP 工作进程上限,不等于每秒能处理多少请求;每秒请求数还取决于请求耗时、缓存命中率、数据库和外部接口。
在面板 PHP-FPM 配置中至少核对:
pm.max_children没有超过内存承受能力。pm.max_requests可先设置为几百量级,用于回收长期运行后内存持续增长的进程。request_terminate_timeout能终止异常长请求。memory_limit、max_execution_time、upload_max_filesize和post_max_size与业务需求匹配。- Nginx、PHP-FPM 和数据库服务已设置为开机启动,并能通过系统服务管理恢复。
可以用下面的命令查找实际服务名称,而不是凭经验硬编码:
sudo systemctl list-units --type=service \
| grep -Ei 'nginx|php|mysql|mariadb'
sudo systemctl is-active nginx
sudo systemctl is-enabled nginx
WordPress 默认 WP-Cron 可能在访客请求中触发。访问量增加后,它会与页面请求争用 PHP-FPM。可以先备份 wp-config.php,再决定是否改为系统计划任务:
define('DISABLE_WP_CRON', true);
然后确认当前命令行 PHP 的实际位置和版本:
command -v php
readlink -f "$(command -v php)"
计划任务路径仅作参考,实际路径应以服务器检查结果为准:
*/5 * * * * /www/server/php/82/bin/php /www/wwwroot/example.com/wp-cron.php >/dev/null 2>&1
两套调度方式不能同时长期启用。若系统计划任务没有成功运行,删除 DISABLE_WP_CRON 配置项并恢复原文件,即可回到由访问请求触发 WP-Cron 的方式。
证书、DNS 和日志必须通过实际请求验证
证书显示“已签发”并不等于用户访问一定正常。先检查主域名、www 域名和 IPv6 记录:
dig +short A example.com
dig +short A www.example.com
dig +short AAAA example.com
如果存在 AAAA 记录,IPv6 也必须能够到达正确入口。否则部分用户可能优先走 IPv6,表现为有人能访问、有人超时。暂时不使用 IPv6 时,不要保留指向旧服务器的 AAAA 记录。
从外部网络检查 HTTP 和 HTTPS:
curl -sSIL --max-redirs 5 http://example.com
curl -sSIL --max-redirs 5 https://example.com
通常 HTTP 应跳转到 HTTPS,HTTPS 最终返回 200 或业务预期的 3xx。若出现连续多次 301/302,检查宝塔强制 HTTPS、Nginx 的 return 301、前置 CDN 或负载均衡的跳转设置。明确由一个入口负责跳转,避免多层重复配置。
再检查证书实际内容,而不是只看面板状态:
openssl s_client \
-connect example.com:443 \
-servername example.com /dev/null \
| openssl x509 -noout -dates -issuer -subject -ext subjectAltName
至少核对以下项目:
subjectAltName包含主域名和实际使用的www域名。notAfter距离上线日有足够余量。- 证书链完整,不能只上传叶子证书。
- 浏览器访问
https://example.com/wp-admin/没有证书警告。 - 图片、脚本和样式没有继续引用 HTTP 地址。
开启 HSTS 前,先确认所有相关子域名和备用入口都支持 HTTPS。证书刚上线、域名仍在迁移时,不宜立即开启长期 HSTS 或加入预加载列表,否则错误配置可能扩大影响范围。
自动续期也要实际核对。宝塔管理证书时,应在面板计划任务或证书管理页面确认续期任务存在,并查看任务日志。不要在面板已经管理证书的情况下,又额外部署另一套证书客户端,让两套任务同时修改 Nginx 配置。续期通常依赖以下条件:
- 域名仍然解析到当前入口。
- 80 端口未被防火墙拦截。
- 证书验证目录没有被重写规则或权限规则拦截。
- Nginx 配置可以通过
nginx -t。 - 续期后 Nginx 可以重新加载新证书。
续期失败时,先修复 DNS、端口或验证目录问题,再手动重新签发。不要先删除当前有效证书,保留旧证书可以避免排障过程中把网站变成完全不可访问。
上线前还要知道日志位置。宝塔常见的网站日志目录为 /www/wwwlogs/,但具体文件名以站点配置为准:
ls -lh /www/wwwlogs/
grep -R "access_log\|error_log" /www/server/panel/vhost/nginx/ 2>/dev/null
tail -n 100 /www/wwwlogs/example.com.error.log
排障时应从外到内进行:先查 DNS 和端口,再查 Nginx,之后查 PHP-FPM、数据库和 WordPress 插件。常见现象与优先位置如下:
| 现象 | 优先检查 | 通常含义 |
|---|---|---|
| 404 | Nginx 重写、站点根目录、固定链接 | 请求未进入正确的 index.php,或文件确实不存在 |
| 403 | 文件权限、访问规则、WAF 规则 | Nginx 或 PHP 用户没有读取权限,或规则误拦截 |
| 502 | fastcgi_pass、PHP-FPM 服务、套接字路径 | PHP-FPM 未运行、套接字不匹配或进程耗尽 |
| 504 | PHP 慢请求、数据库、外部接口、进程数 | 请求超过上游等待时间,不一定是 Nginx 本身故障 |
| 301 循环 | 强制 HTTPS、协议头、WordPress 地址 | 多层入口对当前协议判断不一致 |
| 磁盘不足 | df -h、日志、备份目录 | 日志、备份或缓存挤占空间 |
不要看到 502 就直接重启全部服务。重启 PHP-FPM 会中断正在执行的请求,重启数据库的影响更大,应先查看日志并确认有可用备份,再在维护窗口执行。
备份必须能恢复,而不只是生成文件
WordPress 不能只备份网站目录,也不能只导出数据库。最低备份范围包括:
| 对象 | 内容 | 验证方式 |
|---|---|---|
| 数据库 | 文章、页面、用户、设置和插件数据 | 在隔离数据库导入 |
wp-content | 上传图片、主题和插件 | 抽查图片、主题和插件文件 |
wp-config.php | 数据库连接和关键配置 | 加密保存,不放在公开目录 |
| Nginx/PHP 配置 | 重写、PHP 版本和上传限制 | 保存站点配置与修改记录 |
| 证书信息 | 证书配置和续期方式 | 记录管理位置与续期任务 |
| 计划任务 | WP-Cron、备份和监控任务 | 导出任务并查看执行日志 |
宝塔计划任务可以用于网站文件和数据库备份,但要确认备份写入的位置、是否成功上传到独立存储以及保留周期。只保存在当前服务器上的备份,无法抵御磁盘损坏、误删、系统盘故障或整机不可用。
命令行备份可用于核验宝塔任务的结果。下面的操作会产生磁盘和 I/O 负载,执行前确认磁盘空间充足;数据库名、账号和路径必须替换为真实值,数据库密码使用交互式提示,不要直接写进命令参数:
sudo install -d -m 700 /var/backups/wp-example
sudo mysqldump \
--single-transaction \
--quick \
--no-tablespaces \
--default-character-set=utf8mb4 \
-u wp_user -p wp_db \
| gzip \
| sudo tee /var/backups/wp-example/wp_db_$(date +%F).sql.gz >/dev/null
sudo tar \
--exclude='example.com/wp-content/cache' \
--exclude='example.com/wp-content/uploads/cache' \
-czf /var/backups/wp-example/wp_files_$(date +%F).tar.gz \
-C /www/wwwroot example.com
sudo gzip -t /var/backups/wp-example/wp_db_$(date +%F).sql.gz
sudo tar -tzf /var/backups/wp-example/wp_files_$(date +%F).tar.gz >/dev/null
sudo sha256sum /var/backups/wp-example/*
如果系统中的导出命令名称、数据库权限或文件路径不同,应先用 command -v mysqldump、面板数据库信息和站点配置核对,不要盲目修改线上账号权限。导出失败时不要把不完整文件当成可用备份上传。
备份完成后,应上传到独立存储并保留多个时间点。例如数据库可以每天备份并保留 7~14 个版本,网站文件根据上传频率每天或每周备份,重要站点再增加月度版本。具体周期应按照内容更新频率、可接受的数据丢失范围和合规要求调整。
恢复验证不能只看文件大小。较安全的流程是:

- 在隔离目录或临时服务器创建新数据库。
- 导入数据库备份,不覆盖当前生产数据库。
- 将网站文件解压到新目录。
- 使用对应版本的
wp-config.php连接临时数据库。 - 检查首页、后台登录、文章、图片、固定链接和插件。
- 确认数据库备份时间与网站文件备份时间匹配。
如果必须恢复生产环境,先进入维护状态,并保留当前目录和数据库快照。数据库恢复属于破坏性操作,可能丢失备份时间点之后新增的文章、评论和用户数据。优先使用新目录、新数据库验证后再切换站点根目录;失败时切回旧目录和旧数据库,避免直接覆盖后失去回退路径。
上线验收和失败回滚
正式切换前,先执行低风险检查:
dig +short A example.com
curl -sSIL --max-redirs 5 https://example.com
sudo nginx -t
sudo systemctl is-active nginx
sudo systemctl list-units --type=service | grep -Ei 'php|mysql|mariadb'
df -h
free -h
浏览器端还应检查首页、文章页、分类页、搜索页和后台登录页;上传一张小图片,确认媒体库和前台引用正常;修改一篇测试文章,确认数据库可写;使用无缓存窗口检查 HTTP 是否只跳转一次到 HTTPS;同时观察 Nginx、PHP-FPM 和数据库日志,确认没有持续出现 502、504 或数据库连接错误。测试完成后,只删除刚刚创建的测试文件或文章,不要使用未经路径核对的批量删除命令。
上线后的处理应按照故障范围选择回滚动作:
| 故障 | 先检查什么 | 回滚方式 |
|---|---|---|
| HTTPS 证书错误 | 域名、证书 SAN、证书链和 443 入口 | 保留旧有效证书,恢复上一份 Nginx 证书配置 |
| HTTP/HTTPS 循环 | 多余跳转和 X-Forwarded-Proto | 恢复修改前的 Nginx 与 WordPress 地址配置 |
| 全站 502 | PHP-FPM 状态、fastcgi_pass 和套接字 | 恢复上一份站点配置,确认套接字后再重载 |
| 页面数据异常 | 停止继续写入并确认备份时间点 | 在隔离数据库验证后恢复对应数据库和文件 |
| 磁盘迅速增长 | 日志、备份和缓存目录 | 暂停异常任务,保留必要日志后调整保留策略 |
| 资源持续打满 | PHP-FPM、数据库和慢请求日志 | 回退最近启用的插件、计划任务或参数,不要盲目增加进程数 |
最容易遗漏的复核点,往往不是首页能否打开,而是主域名与 www 是否都在证书中、AAAA 是否指向正确入口、证书续期任务是否真的执行、备份是否存放在另一处,以及数据库和网站文件是否来自同一时间点。只有这些项目都完成验证并留下记录,宝塔、Nginx、PHP-FPM 和 WordPress 才具备可回退、可定位、可恢复的生产上线条件。