Hello World!

花费了点时间把Wordpress搭建起来了。虽然最终实现的方案并不复杂,但过程中也确实踩了许多坑。

目前,访问本站是这样一个途径:

  1. 首先discolor.com由Cloudflare解析到我家里的宽带公网IP上,这个IP的实际承载设备是家里的Openwrt路由器。
  2. 路由器上设置80和443端口转发到我的CentOS虚拟机上。
  3. CentOS上host了一个nginx,这个nginx的 “/” location 做一个 proxy_pass 到Wordpress
  4. WordPress host在一个ubuntu 20.04虚拟机内部的docker container里,它所链接的MySQL数据库也是以docker方式在同一个虚拟机中运行。

使用的docker镜像都是官方默认最新的stable variant,但过程中遇到了以下一些问题:

WordPress连接不上数据库

MySQL的root密码是docker run -e MYSQL_ROOT_PASSWORD设置的,但是用这个密码怎么都无法让Wordpress连上MySQL。原因是MySQL中可以有多个root账户对应不同的host。在我的情况里有一个’root’@’localhost’,还有一个’root’@’%’。而docker run的参数设定的应该是root@localhost的密码,而’root’@’%’的密码则不知道是啥玩意,好在密码可以直接在数据库中修改。

首先进入MySQL的docker container内部:

docker ps找出MySQL的id

docker exec -it containerid bash

mysql -uroot -p

输入之前docker run时设定的密码可以进入数据库内部

首先选定数据库:

use mysql;

在此保险起见把两个账号的密码都在数据库中用以下命令写成需要的密码后就可以让Wordpress连接了:

ALTER USER 'root'@'localhost' IDENTIFIED BY 'MyN3wP4ssw0rd'; 
ALTER USER 'root'@'%' IDENTIFIED BY 'MyN3wP4ssw0rd'; 
flush privileges;

再用Wordpress连接数据库即可。另外因为MySQL和Wordpress在不同的container内部,而不是同一台虚拟机中,所以数据库地址写localhost是不行的。使用ip加端口号则可以正常连接。

Nginx反代的各种问题

由于网站是由nginx来处理https加密,而nginx与Wordpress的通信其实是http,所以需要一系列设置来让它正常运转。

nginx的 “/” location中需要加入以下参数/header:

location / {

    proxy_pass http://xxx.xxx.xxx.xxx:xx;

    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;

    proxy_set_header   X-Forwarded-Host $server_name;

    proxy_set_header   X-Forwarded-Proto $scheme;

}

记得重启nginx:systemctl restart nginx

另外这个nginx的https加密是之前就弄好的,这里不做详细描述。

WordPress的wp-config.php中也需要添加一些参数

先进入Wordpress的container内部:

docker ps找出Wordpress的id

docker exec -it containerid bash

正常就会进入存放wp-config.php的文件夹,使用vi进行编辑:

vi wp-config.php

如果没有vi则可以apt upgrade后apt install vi

在下面这两行注释文字中间插入代码

/* Add any custom values between this line and the "stop editing" line. */

if ($_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')
$_SERVER['HTTPS']='on';

if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) {
$_SERVER['HTTP_HOST'] = $_SERVER['HTTP_X_FORWARDED_HOST'];
}

/* That's all, stop editing! Happy publishing. */

回到docker的宿主机进行一个docker restart containerid

siteurl & home

需要让Wordpress知道自己是以什么url被访问,这样它好在跳转时返回正确的url。

如果这步做错了把Wordpress整烂了进不了后台,可以进MySQL手动把它改回原来的值。

进入MySQL的步骤同上不再赘述,记得选中wordpress的数据库,我的就叫wordpress所以需要执行:

use wordpress;

然后执行下面的sql语句,将加黑部分换成需要设置的值:

UPDATE wp_options SET option_value = ‘https://discolor.com‘ WHERE option_name IN (‘siteurl’, ‘home’);

这样可以不通过网站后台实现对这两个值的修改。

New post & New page 页面无法加载、白屏

把https设好之后发现网站大部分页面都正常了,但是new post和new page页面无法正常加载。F12看console发现大量content security policy报错,主要是font-src 和 img-src 的policy未设定,而fallback到default-src只允许self和unsafe-inline。这个unsafe-inline正常也是不允许,我添加这一项是因为chrome需要这一项才能正确加载我的favicon。

根据每一条报错,修改了nginx conf里的csp header部分:

add_header Content-Security-Policy “default-src ‘self’ ‘unsafe-inline’ ‘unsafe-eval’; font-src ‘self’ data: ; img-src ‘self’ secure.gravatar.com data: ;” always;

根据我的理解, 这个add page/post界面有大量js脚本,需要允许’unsafe-eval’。font-src和img-src都有使用一个data:类型的内容,所以需要加入允许清单。另外头像是通过secure.gravatar.com来加载,所以也需要在img-src中允许。

其他页面、元素出现csp报错再根据情况增加policy白名单,或者直接不要发这劳什子header。

参考了这个系列的youtube视频,虽然跟他的实现方式有很大区别但是依然帮助我解决了一些问题,尤其是nginx反代的部分:

https://www.youtube.com/watch?v=5YkkqjwRqN4
https://www.youtube.com/watch?v=y0VgnNbCneU
https://www.youtube.com/watch?v=SLejN0yC8sM
https://www.youtube.com/watch?v=T7flzYEtMGA

Share