WordPress HTTPS 部署踩坑全过程

前言

在阿里云 ECS 上部署个人 WordPress 博站时,本以为配置 HTTPS 是一件简单的事,没想到从证书申请到最终浏览器正常访问,踩了
一连串的坑。本文完整记录整个排查过程,希望能帮到遇到类似问题的朋友。

## 环境信息

    • 服务器:阿里云 ECS(Ubuntu)
    • WordPress:Docker 部署(wordpress + mysql 容器)
    • Web 服务器:Nginx 1.18
    • 域名:bellwinter.top / www.bellwinter.top

    ## 第一关:Certbot HTTP 验证失败(403)

    ### 现象

    执行 certbot certonly --webroot 申请证书时,Let’s Encrypt 返回 403 Unauthorized:

    Detail: 47.106.178.146: Invalid response from
    http://bellwinter.top/.well-known/acme-challenge/xxx: 403

    排查

    首先检查 Nginx 配置,确认 .well-known/acme-challenge/ 路径已正确指向 /var/www/certbot

    “`nginx
    location /.well-known/acme-challenge/ {
    alias /var/www/certbot/.well-known/acme-challenge/;
    default_type text/plain;
    allow all;
    }

    文件权限也没问题,本地 curl 测试返回 200:

    curl http://bellwinter.top/.well-known/acme-challenge/testfile
    # 返回 200 OK

    但从外部电脑 curl 同一地址返回 403——说明有东西在服务器和外部请求之间拦截了流量。

    原因

    域名经过阿里云 WAF(Web 应用防火墙)或 CDN 代理,ACME 验证请求被安全策略拦截。

    解决

    放弃 HTTP 验证,改用 DNS 验证方式:

    certbot certonly –manual –preferred-challenges dns \
    -d bellwinter.top -d www.bellwinter.top

    Certbot 会要求你添加两条 DNS TXT 记录:
    主机记录 │ 类型 │ 说明 │

    _acme-challenge │ TXT │ 验证 bellwinter.top │

    _acme-challenge.www │ TXT │ 验证 http://www.bellwinter.top

    在阿里云 DNS 控制台添加后等待 1-2 分钟生效,回到终端按回车即可。

    小结: 当 HTTP 验证被 WAF/CDN 拦截时,DNS 验证是最可靠的替代方案。

    第二关:配置 HTTPS 后 Nginx 报错

    现象

    申请到证书后,修改 Nginx 配置启用 SSL,执行 nginx -t 报错:

    cannot load certificate “/etc/letsencrypt/live/nellwinter.top/fullchain.pem”:
    No such file or directory

    原因

    配置文件中域名拼写错误:nellwinter.top(n 开头)应为 bellwinter.top(b 开头)。

    解决

    修正拼写后 nginx -t 通过,nginx -s reload 生效。

    教训: 复制粘贴虽好,但一定要检查路径是否正确。

    第三关:WordPress 重定向到 8080 端口

    现象

    浏览器访问 https://bellwinter.top 被重定向到 https://bellwinter.top:8080/,页面无法打开。

    原因

    WordPress 是 Docker 部署的,容器内部端口是 8080 映射到宿主机的 80。WordPress 的 siteurl 和 home 配置还是旧的
    http://47.106.178.146:8080。

    解决

    方法一:修改 wp-config.php

    在 wp-config.php 中 /* That’s all, stop editing! */ 前添加:

    define(‘WP_HOME’, ‘https://bellwinter.top’);
    define(‘WP_SITEURL’, ‘https://bellwinter.top’);

    方法二:直接修改数据库

    USE wordpress;
    UPDATE wp_options SET option_value = ‘https://bellwinter.top’
    WHERE option_name = ‘siteurl’;
    UPDATE wp_options SET option_value = ‘https://bellwinter.top’
    WHERE option_name = ‘home’;

    两种方式都需要重启容器:docker restart wordpress-app

    注意: 容器内可能没有 nano 编辑器,可以用 docker cp 把文件拷到宿主机编辑后再拷回去。

    第四关:浏览器表现不一致

    现象

    • Edge:有无 VPN 都能访问
    • Firefox:不开 VPN 能访问,开 VPN 不行
    • Chrome:有无 VPN 都不能访问 原因
    1. Chrome 有独立的 DNS 缓存,记住了旧的解析结果
    2. VPN 会干扰 SSL 握手,部分浏览器受影响 解决
    • Chrome:访问 chrome://net-internals/#dns 清除 DNS 缓存,再访问 chrome://net-internals/#sockets 刷新 socket 连接
    • 通用:使用无痕模式(Ctrl + Shift + N)访问
    • VPN:访问自己的服务器时建议关闭 VPN

    总结

    这次部署踩坑让我学到了几点:

    1. 分层排查:从 Nginx → 文件权限 → 网络层 → 浏览器缓存,逐层定位问题
    2. ACME 验证方式:HTTP 验证依赖域名直接可达,有 WAF/CDN 时应直接用 DNS 验证
    3. Docker 中的 WordPress:修改配置需要考虑容器隔离,注意编辑器可用性和文件拷贝
    4. 浏览器缓存:不同浏览器有独立的 DNS 和连接缓存,排查时要用无痕模式排除干扰 希望这篇文章能帮你少走弯路!

    发表回复

    您的邮箱地址不会被公开。 必填项已用 * 标注