此举是为了将原先部署在443端口的WordPress网站使用反向代理的方式重新部署。部署反代的过程踩了不少的坑,主要还是因为WordPress作为动态博客框架所具有的特殊机制。(说起这个就要后悔当时为啥没搞个静态博客了)


首先介绍一下环境,我的WordPress网站运行在docker容器下,由Apache服务启动,原先的配置是docker容器内的Apache配置了SSL证书,并将容器443端口映射至宿主机。

为了在宿主机上用Nginx做反代,首先要对容器内的服务进行一些修改。两次SSL肯定是不划算的,因此首先要将容器内的Apache服务停用https,然后我们修改容器的端口绑定为0.0.0.0:8000->80/tcp(这个8000随便选一个宿主机的空闲端口即可,后面Nginx配置反代时会用到)。注意:这个时候WordPress数据库内站点的地址仍然是https的地址,为了站点的优雅,这里的地址不要改动。

接下来,配置Nginx,首先要确保安装的Nginx支持SSL(可通过nginx -V查看是否有SSL相关的模块)。

server{
  listen 80;
  listen 443 ssl;
  server_name blog.fyz666.xyz;
  index  index.php index.html index.htm;
  ssl_certificate /etc/letsencrypt/live/fyz666.xyz/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/fyz666.xyz/privkey.pem;
  if ($scheme = http){
    return 301 https://$host$request_uri;
  }
  location / {
    proxy_pass  http://127.0.0.1:8000/;
    proxy_set_header Host $host:$server_port;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Host $http_host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Powered-By the-internet;
    add_header Content-Security-Policy upgrade-insecure-requests;
  }
}

以上配置是针对我自己的域名、网站服务情况。在运行该配置的Nginx前,需要确认80、443端口是空闲的。

  • 首先,声明监听的两个端口,其中443端口开启SSL。
  • 然后我们指定前面使用Let’s Encrypt生成的SSL证书,对于Nginx,我们只需要fullchain与privkey两个文件。
  • 接下来做一个301跳转,将http跳转到https。
  • 最后的location配置,则是反向代理的核心。

首先,我们的反向代理的是将整个站点反代到443端口的根路径,因此location指定为/。然后是在proxy_pass字段指定位于localhost上的8000端口(这个端口是前面docker容器在宿主机上的映射),接下来必不可少的一条配置是proxy_set_header Host $host:$server_port;而这里有一个小坑。

如果我们代理的是个静态的Web网站,只需要这样即可:proxy_set_header Host $host;,但对于WordPress,我们必须带上$server_port进行转发。这是因为WordPress会将该地址与数据库内的站点地址进行比较,若不同,则会进行301跳转。这里若Nginx转发时不带上443这个端口,在反代后面的WordPress看来,转发至它的端口则是8000,与数据库内的443端口不一致,它会强制将访问转发到443端口,重新交给Nginx处理,而Nginx又会重新反代到8000端口,可见这样操作会引发无限的重定向!

另一条重要的配置是add_header Content-Security-Policy upgrade-insecure-requests;它是为了让WordPress能访问到其静态文件。

但仅仅配置了Nginx是不够的,因为WordPress自身并不支持反向代理,我们还需要修改一下WordPress的源代码。

打开WordPress网站根路径下的wp-config.php文件,找到包含ABSPATH的这段代码,在它前面添加三行:

//添加下面三行代码
if ( ! empty( $_SERVER['HTTP_X_FORWARDED_HOST'] ) ) {
    $_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
}
/** Absolute path to the WordPress directory. */
if ( ! defined( 'ABSPATH' ) ) {
	define( 'ABSPATH', __DIR__ . '/' );
}

这样配置下来,反向代理的WordPress网站已经可以正常运作了。