文章目录
  1. 1. 前言
  2. 2. 一般情况
  3. 3. 反向代理的情况
  4. 4. 总结
  5. 5. 附录

前言

wordpress是应用很广泛的CMS系统。无论是用作博客或者是安装自定义的主题来建站,用起来都是很简单,而且自定义主题的开发也容易上手。近期因工作需要开发一个wordpress的主题来建站,发现wordpress代码比较老,需要兼容的情况很多。API一致性很差,经常做同一个功能有多个相似的api,而且名字看起来差不多,但参数却差别很大。这些都还算好的,遇到一个比较大的问题是,wordpress里必须配置主站的域名(也就是在wp-admin需要配置的url),而且mysql的数据里充斥着hard code的url。这给数据迁移和反向代理带来了很大的不便。这次是由于安全的原因,我只能把wordpress假设在反代后面,就这么一个小小的改变,我发现wordpress死活水土不服。

下面记录下配置的要点,方便以后查看。我使用的服务器是nginx,反向代理的服务器也是nginx。

一般情况

一般情况我们架设wordpress 的结构是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
                    HTTP请求
+
|
+--------------------------------------------+
| | |
| +-----------------v----------------+ |
| | | |
| | Nginx | |
| | | |
| +-----------------+----------------+ |
| | |
| +-----------------v----------------+ |
| | | |
| | wordpress | |
| | | |
| | | |
| | | |
| | | |
| +-----------------+----------------+ |
| | |
| +-----------------v----------------+ |
| | mysql | |
| | | |
| +----------------------------------+ |
| |
| |
+--------------------------------------------+

而配置域名方面也比较简单,主要是两处

  1. nginx 的配置 nginx.conf
1
server_name www.example.com
  1. wordpress wp-admin中的设置

wordpress域名设置

其实这第二步就稍显多余,为什么wordpress不能都使用相对路径?如果大家多次修改后wp-admin进不去,可参见附录直接修改数据库。

反向代理的情况

这个时候wordpress的架构是这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
                    HTTP请求
+
|
|
|
+--------------------------------------------+
| | |
| +-----------------+---------------+ |
| | Nginx Reverse Proxy | |
| | | |
| +-----------------+---------------+ |
| | |
+--------------------------------------------+
|
|
|
|
+--------------------------------------------+
| | |
| +-----------------v----------------+ |
| | | |
| | Nginx | |
| | | |
| +-----------------+----------------+ |
| | |
| +-----------------v----------------+ |
| | | |
| | wordpress | |
| | | |
| | | |
| | | |
| | | |
| +-----------------+----------------+ |
| | |
| +-----------------v----------------+ |
| | mysql | |
| | | |
| +----------------------------------+ |
| |
| |
+--------------------------------------------+

理论上我不就是在外面加了个反向代理,我就把两个nginx的配置改下应该就可以了吧?

  1. Nginx Reverse Proxy
1
2
3
4
5
6
7
8
9
10
server_name www.example.com

location / {
proxy_pass http://<Wordpress-Server-IP>:<Port>

#Proxy Settings
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
  1. wordpress 服务器的Nginx 配置
1
2
listen <Port>
server_name localhost

可惜只是理论上应该这样。只配置了这两个,wordpress 是仍然不能工作的。经过反复调试,不是反向代理服务器返回500错误,就是wordpress的redirect不正常。

经过多次搜索研究,还要配置下面两步

  1. 清理mysql的数据

    把hard code的数据url 给改成过来,确保不存在域名不正确的url。比如: localhost:<Port>/xxx 这样的url在数据库, 都需要改成 www.example.com/xxx。大家可以使用Search-Replace-DB这个工具,来替换数据库。

  2. 改PHP代码手动设置反向代理的HOST,因为wordpress的核心开发者说:让wordpress支持反向代理不是他们的责任

    核心思想就是要让 PHP代码知道反向代理转发的域名是什么,然后强制地在每个页面里动态设置。

第一步 Nginx Reverse Proxy 配置改为

1
2
3
4
5
6
7
8
9
10
11
server_name www.example.com

location / {
proxy_pass http://<Wordpress-Server-IP>:<Port>

#Proxy Settings
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

加了X-Forwarded-For

第二步 修改wp-config.php的代码,添加如下部分

1
2
3
if ( ! empty( $_SERVER['HTTP_X_FORWARDED_HOST'] ) ) {
$_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
}

修改了以上的内容,wordpress 的反向代理才能真正工作起来。

总结

综上所述:让wordpress支持反向代理一共有五步

  1. 反向代理服务器需要配置域名,并且需要配置X-Forwarded-For
1
2
3
4
5
6
7
8
9
10
11
server_name www.example.com

location / {
proxy_pass http://<Wordpress-Server-IP>:<Port>

#Proxy Settings
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
  1. wordpress的服务器,配置server_name 为localhost 和端口号。
1
2
listen <Port>
server_name localhost
  1. wordpress 的wp-admin里要设置成域名,而不是localhost或者wordpress server的IP。

wordpress域名设置

  1. 要在wp-config.php修改里 HTTP_HOST
1
2
3
if ( ! empty( $_SERVER['HTTP_X_FORWARDED_HOST'] ) ) {
$_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
}
  1. 【可选的】用Search-Replace-DB来检查替换数据库,确保数据库里不存在域名不正确的url。

附录

在wp-admin进不去的情况下,操作 wp_options 数据库表, 来更新wordpress的域名

1
2
3
4
5
msyql -u xxx -p # 连接数据库。
> use wordpress; # 使用数据库
> update wp_options SET option_value='http://www.example.com' WHERE option_name='home';
> update wp_options SET option_value='http://www.example.com' WHERE option_name='siteurl';
> quit
文章目录
  1. 1. 前言
  2. 2. 一般情况
  3. 3. 反向代理的情况
  4. 4. 总结
  5. 5. 附录