给 Docker 里的 WordPress 添加 HTTPS 支持

通过 docker 安装应用比较方便,但让 docker 里的应用支持 https 比较麻烦,最起码我在 wordpress 上确实踩坑了。

我的部署情况是这样的:服务器上的 nginx 提供对外访问以及 https 支持,docker 里还是 http。外部通过 http 访问时会被 nginx 重定向到 https。顺便贴一下 nginx 配置。因为配置里有坑。

location /
{
    proxy_pass http://127.0.0.1:1080/;
    proxy_set_header Host $http_host;
    charset utf-8;
    ###start####
    proxy_hide_header Access-Control-Allow-Origin;
    add_header Access-Control-Allow-Origin $http_origin;
    add_header Access-Control-Allow-Headers X-Requested-With;
    add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
    add_header Content-Security-Policy "upgrade-insecure-requeconnect-src *";
    ###end ###
}

首先,我们要在 wordpress 后台设置网站地址:

第一个“WordPress 地址”是后台地址,第二个“站点地址”是前台页面地址。第二个改成 https 没有大问题,一切正常,用户正常访问,后台正常写文章。小问题是,如果 WordPress 地址维持 http,那么页面上以及 REST API 里的媒体文件地址就是 http 的。一个 https 网站访问 http 链接是有问题的,某些版本的浏览器可能允许 img 之类的,但某些不允许。我就是遇到了不允许的才会考虑把后台也改成 https 的。我刚安装 wordpress 的时候改过一次,后台挂了,所以后来就维持后台 http 了。

后台地址改成 https 导致后台无法访问,根据 AI 的说法是 docker 内部识别不到 https 环境,于是还是用的 http 访问,但 http 会被重定向为 https(是外部 nginx 定向和还是 docker 内部定向的,我没问),于是循环重定向。

修改方法是,让外部 nginx 透传协议,内部 wp-config.php 开启 https 识别。

nginx 添加几行配置:

    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;

然后 wp-config.php 添加几行代码(/* That’s all, stop editing! Happy publishing. */ 后面):

// 让 WordPress 识别来自 nginx 反向代理的 https
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])
    && strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false) {
    $_SERVER['HTTPS'] = 'on';
    $_SERVER['SERVER_PORT'] = 443;
}

如此一来,docker 内的 wordpress 就可以识别 https 环境了,后台也可以打开了。

但是,还没完。当我写文章插入图片的时候,wordpress 提示什么“创建响应式图片失败……”。

根据 AI 的分析,我检查了 docker 内的图片程序,发现是有的。添加了 debug,结果也没报错。后来我打开浏览器控制台,发现上传图片的时候有个 CSP 报错。

dfe4b569-c0ea-49c6-8507-f596239c4f28:161
Connecting to ‘blob:https://templates.dowhat.net/bf217748-42f6-47bf-8528-9c7852516f3b‘ violates the following Content Security Policy directive: “connect-src “. Note that ‘‘ matches only URLs with network schemes (‘http’, ‘https’, ‘ws’, ‘wss’), or URLs whose scheme matches self‘s scheme. The scheme ‘blob:’ must be added explicitly. The action has been blocked.

我发给 AI 之后,AI 说这个小问题可以顺便解决,但图片上传失败还要接着查。

结果当我在 nginx 里把 blob 和 data 添加到 CSP 里之后,问题就解决了。

add_header Content-Security-Policy "upgrade-insecure-requests;connect-src * data: blob:";

查了一圈,原来浏览器 CSP 报错阻断了流程。