Docker + Nginx + WordPress 环境下 SSL 证书过期后的续期完整流程

一、问题背景

网站 SSL 证书过期后,浏览器访问 HTTPS 会提示证书无效、连接不安全。对于使用 Docker 部署的 Nginx + WordPress 网站来说,证书续期不只是重新申请证书,还需要确认 Nginx 的真实配置路径、证书挂载目录,以及最终是否正确加载了新证书。

本文记录一次 Docker + Nginx + WordPress 环境下 SSL 证书续期的完整流程。文中的域名、证书文件名、服务器 IP、验证文件内容等均已脱敏。


二、整体流程概览

1. 确认 Docker 容器和端口映射
2. 确认 Nginx 配置文件和挂载目录
3. 确认当前 Nginx 加载的证书
4. 创建 SSL 文件验证目录
5. 上传 fileauth.txt 验证文件
6. 配置 Nginx 支持 HTTP 文件验证
7. 测试验证文件是否能访问
8. 修复可能存在的 DNS 解析问题
9. SSL 控制台完成域名验证
10. 下载 Nginx 类型的新证书
11. 上传并解压新证书
12. 替换 Nginx 中的 ssl_certificate 配置
13. 测试并重载 Nginx
14. 验证 HTTPS 是否恢复正常

需要注意的是:

SSL 文件验证成功,并不代表 HTTPS 会自动恢复。必须下载新证书,并替换到 Nginx 配置中,HTTPS 才会真正生效。


三、确认 Docker 容器环境

首先查看当前运行的 Docker 容器:

docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Ports}}\t{{.Status}}"

重点关注以下信息:

  • Nginx 容器是否正在运行
  • 80 端口是否映射到宿主机
  • 443 端口是否映射到宿主机
  • WordPress 容器名称是什么

示例输出:

NAMES       IMAGE          PORTS
nginx       nginx:latest   0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp
wordpress   wordpress      0.0.0.0:9999->80/tcp

如果 Nginx 容器没有映射 80 或 443,那么后续文件验证或 HTTPS 访问都可能失败。


四、确认 Nginx 挂载目录

Docker 部署的 Nginx,真正生效的配置文件通常不是宿主机默认的 /etc/nginx,而是容器中挂载的配置文件。

执行:

docker inspect nginx --format '{{range .Mounts}}{{println .Source " -> " .Destination}}{{end}}'

示例挂载关系:

/home/data/nginx/conf/nginx.conf -> /etc/nginx/nginx.conf
/home/data/nginx/conf/conf.d -> /etc/nginx/conf.d
/home/data/nginx/html -> /usr/share/nginx/html
/home/data/nginx/ssl -> /home/data/nginx/ssl

这里可以得出几个关键路径:

  • Nginx 配置目录:/home/data/nginx/conf/conf.d
  • Nginx 静态文件目录:/home/data/nginx/html
  • Nginx 证书目录:/home/data/nginx/ssl

五、查看 Nginx 实际加载的配置

如果宿主机没有安装 Nginx,直接执行 nginx -T 会报错。正确方式是进入容器执行:

docker exec nginx nginx -T 2>&1 | grep -nE "server_name|listen|ssl_certificate|ssl_certificate_key|root|proxy_pass|return 301|well-known|include"

这个命令可以确认:

  • 当前配置了哪些 server_name
  • 是否监听了 80 端口
  • 是否监听了 443 端口
  • 当前 HTTPS 使用的是哪个证书文件
  • 是否已经配置了 .well-known 文件验证路径

如果只看到 listen 443 ssl;,没有看到 listen 80;,那么 HTTP 文件验证很可能无法访问。


六、创建 SSL 文件验证目录

SSL 证书申请平台通常会要求在服务器上放置一个验证文件,例如:

/.well-known/pki-validation/fileauth.txt

由于前面已经确认宿主机静态目录是:

/home/data/nginx/html

所以创建目录:

mkdir -p /home/data/nginx/html/.well-known/pki-validation

然后创建验证文件:

vim /home/data/nginx/html/.well-known/pki-validation/fileauth.txt

把 SSL 平台提供的验证内容粘贴进去,例如:

<FILE_AUTH_TOKEN>

注意:真实的验证内容不要公开到文章或截图中。


七、配置 Nginx 支持 HTTP 文件验证

修改配置前先备份:

cp /home/data/nginx/conf/conf.d/example.conf /home/data/nginx/conf/conf.d/example.conf.bak.$(date +%F-%H%M)

编辑站点配置文件:

vim /home/data/nginx/conf/conf.d/example.conf

推荐配置结构如下:

server {
    listen 80;
    server_name example.com www.example.com;

    location ^~ /.well-known/pki-validation/ {
        root /usr/share/nginx/html;
        default_type text/plain;
        try_files $uri =404;
    }

    location / {
        return 301 https://www.example.com$request_uri;
    }
}

server {
    listen 443 ssl;
    server_name example.com www.example.com;

    ssl_certificate /home/data/nginx/ssl/old_certificate.crt;
    ssl_certificate_key /home/data/nginx/ssl/old_certificate.key;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    location ^~ /.well-known/pki-validation/ {
        root /usr/share/nginx/html;
        default_type text/plain;
        try_files $uri =404;
    }

    location / {
        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 https;
        proxy_pass http://wordpress:80;
    }
}

这里有几个关键点:

  • listen 80; 用于 HTTP 文件验证。
  • server_name 要包含根域名和 www 域名。
  • .well-known 路径要优先匹配,避免被跳转或代理到 WordPress。
  • 验证路径最好直接返回 200 OK。

八、测试并重载 Nginx

测试配置语法:

docker exec nginx nginx -t

如果看到:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

说明配置没有语法问题。

然后重载 Nginx:

docker exec nginx nginx -s reload

九、测试验证文件是否可以访问

分别测试根域名和 www 域名:

curl -i http://example.com/.well-known/pki-validation/fileauth.txt

curl -i http://www.example.com/.well-known/pki-validation/fileauth.txt

正常结果应该类似:

HTTP/1.1 200 OK
Server: nginx
Content-Type: text/plain

<FILE_AUTH_TOKEN>

如果服务器本机无法解析域名,也可以绕过 DNS,直接测试 Nginx 是否匹配正确:

curl -i -H "Host: example.com" http://127.0.0.1/.well-known/pki-validation/fileauth.txt

curl -i -H "Host: www.example.com" http://127.0.0.1/.well-known/pki-validation/fileauth.txt

如果本机测试返回 200 OK,说明 Nginx 配置和文件路径是正确的。


十、处理 DNS 解析问题

如果访问时出现:

Could not resolve host

或者:

Can't find example.com: No answer

说明是 DNS 解析问题,不是 Nginx 配置问题。

可以执行:

nslookup example.com
nslookup www.example.com

如果根域名没有解析,需要去域名解析控制台添加:

主机记录:@
记录类型:A
记录值:服务器公网 IP

www 域名可以添加:

主机记录:www
记录类型:A
记录值:服务器公网 IP

也可以使用 CNAME:

主机记录:www
记录类型:CNAME
记录值:example.com

DNS 生效后,再重新测试:

curl -i http://example.com/.well-known/pki-validation/fileauth.txt
curl -i http://www.example.com/.well-known/pki-validation/fileauth.txt

两个域名都返回 200 OK 后,就可以回 SSL 控制台点击验证。


十一、下载新证书

SSL 文件验证通过后,平台会签发新证书。

下载证书时,服务器类型选择:

Nginx

不要选择 Apache、Tomcat 或 IIS。

下载后一般会得到一个压缩包,解压后通常包含:

new_certificate.crt
new_certificate.key

或者:

new_certificate.pem
new_certificate.key

其中:

  • .crt 或 .pem 对应 ssl_certificate
  • .key 对应 ssl_certificate_key

注意:.key 是私钥文件,不能公开。


十二、上传并解压新证书

上传证书到服务器目录:

/home/data/nginx/ssl/

进入证书目录:

cd /home/data/nginx/ssl/

解压证书:

unzip new_certificate_NGINX.zip

查看文件:

ls -lah /home/data/nginx/ssl

示例:

old_certificate.crt
old_certificate.key
new_certificate.crt
new_certificate.key
new_certificate_NGINX.zip

十三、替换 Nginx 中的证书路径

再次备份配置:

cp /home/data/nginx/conf/conf.d/example.conf /home/data/nginx/conf/conf.d/example.conf.bak.$(date +%F-%H%M)

编辑配置:

vim /home/data/nginx/conf/conf.d/example.conf

找到旧证书路径:

ssl_certificate /home/data/nginx/ssl/old_certificate.crt;
ssl_certificate_key /home/data/nginx/ssl/old_certificate.key;

替换成新证书路径:

ssl_certificate /home/data/nginx/ssl/new_certificate.crt;
ssl_certificate_key /home/data/nginx/ssl/new_certificate.key;

如果证书文件是 .pem,则配置为:

ssl_certificate /home/data/nginx/ssl/new_certificate.pem;
ssl_certificate_key /home/data/nginx/ssl/new_certificate.key;

十四、测试并重载 Nginx

测试配置:

docker exec nginx nginx -t

如果成功,再重载:

docker exec nginx nginx -s reload

十五、验证新证书是否生效

使用 openssl 查看当前 HTTPS 证书:

echo | openssl s_client -servername www.example.com -connect www.example.com:443 2>/dev/null | openssl x509 -noout -dates -issuer -subject

重点看 notAfter:

notAfter=新的证书到期时间

如果到期时间已经变成新证书的时间,说明 Nginx 已经加载新证书。

再测试 HTTPS:

curl -I https://www.example.com

如果返回 200 OK 或 301 Moved Permanently,且没有证书过期错误,说明 HTTPS 已恢复正常。


十六、常见问题总结

1. 文件验证成功,为什么 HTTPS 还是不能访问?

因为文件验证只代表你证明了域名所有权,并不会自动替换服务器证书。必须下载新证书,并修改 Nginx 的 ssl_certificate 和 ssl_certificate_key 后,HTTPS 才会真正恢复。

2. 为什么要配置 80 端口?

很多 SSL 平台的文件验证是通过 HTTP 访问:

http://example.com/.well-known/pki-validation/fileauth.txt

如果 Nginx 没有监听 80,验证服务器就访问不到验证文件。

3. 为什么 .well-known 路径要单独配置?

如果所有请求都被代理到 WordPress 或直接跳转 HTTPS,而 HTTPS 证书又已经过期,就可能导致验证失败。单独配置 .well-known 可以让验证文件直接返回。

4. 如何确认 Nginx 真的加载了新证书?

不要只看配置文件,要用 openssl 查询线上证书:

echo | openssl s_client -servername www.example.com -connect www.example.com:443 2>/dev/null | openssl x509 -noout -dates -issuer -subject

如果 notAfter 还是旧日期,说明新证书没有真正生效。


十七、敏感信息脱敏建议

发布博客、截图或日志时,建议脱敏以下内容:

  • 真实域名:用 example.com 替代
  • 服务器公网 IP:用 x.x.x.x 替代
  • 证书文件名:用 old_certificate 和 new_certificate 替代
  • 验证文件内容:用 <FILE_AUTH_TOKEN> 替代
  • SSH 登录 IP:不要展示
  • Session ID:不要展示
  • .key 私钥内容:绝对不能公开

尤其注意:私钥文件 .key 是最敏感的内容,不要截图、不要上传到公开仓库、不要写入博客文章。


十八、总结

这次 SSL 证书续期的核心经验是:不要只关注证书申请页面,还要确认服务器上的 Nginx 是否真正加载了新证书。

完整链路可以总结为:

HTTP 文件验证成功
↓
SSL 平台签发新证书
↓
下载 Nginx 类型证书
↓
上传到服务器证书目录
↓
修改 Nginx ssl_certificate 配置
↓
nginx -t 检查配置
↓
reload Nginx
↓
openssl 验证新证书是否生效

最终结论:

SSL 文件验证成功 ≠ HTTPS 自动生效。只有 Nginx 正确加载新证书后,HTTPS 才会真正恢复正常。