本来,我要解决的问题是 Docker 容器中的 WordPress 在通过主机 Nginx 反向代理后启用 HTTPS 时,前台显示正常,但管理后台无法访问的问题。这个问题实际上与我接下来要记录的内容没有本质上的关联,只需要一个名为 SSL Insecure Content Fixer 的 WordPress 插件即可解决。

接下来要记录的内容是完全通过 Docker 容器实现 Nginx 对容器的反向代理,同时实现 Let's Encrypt 证书的自动获取。

前者需要通过 jwilder/nginx-proxy 镜像实现,后者需要结合 JrCs/docker-letsencrypt-nginx-proxy-companion 镜像来实现。这里以我的 WordPress 容器配置举例。

第一步 配置 nginx-proxy

我不太喜欢使用 docker-compose,通常,我会通过一个 shell 脚本管理容器的更新,例如,在创建这一步的 nginx-proxy 容器时,我会创建一个脚本文件 nginx-proxy.sh。脚本文件中第一行会拉取最新的镜像,第二行会删除现有的容器,第三行创建新的容器。

注意:如果容器中的应用不需要启用 https,则可以去掉 433 端口以及带有 $PWD 变量的三行,还有 --babel 那一行。应用容器只需要添加一个 -e VIRTUA_HOST=www.yourdomain.com 的环境变量设置绑定的域名即可。

#!/bin/bash

sudo docker pull jwilder/nginx-proxy

sudo docker rm -f nginx-proxy

sudo docker run -d --name nginx-proxy \
	-p 80:80 \
	-p 443:443 \
	-v $PWD/nginx/certs:/etc/nginx/certs:ro \
	-v $PWD/nginx/vhost.d:/etc/nginx/vhost.d \
	-v $PWD/nginx/html:/usr/share/nginx/html \
	-v /var/run/docker.sock:/tmp/docker.sock:ro \
	--label com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy \
	--restart always \
	jwilder/nginx-proxy

第二步 创建 Let's Encrypt 自动证书容器

这个脚本我命名为 lets.sh,因为与第一步的 nginx-proxy.sh 紧密相关,因此我把它们放到了相同的目录中。

#!/bin/bash

sudo docker pull rcs/letsencrypt-nginx-proxy-companion

sudo docker rm -f lets

sudo docker run -d --name lets \
	-v $PWD/nginx/certs:/etc/nginx/certs:rw \
	-v /var/run/docker.sock:/var/run/docker.sock:ro \
	--volumes-from nginx-proxy \
	--restart always \
	jrcs/letsencrypt-nginx-proxy-companion

第三步 创建应用

这里以 WordPress 为例,其中 mariadb 是我提前创建好的数据库容器(过程略)

使用 --expose 设置容器对外暴露的端口,VIRTUAL_HOST= 环境变量指定绑定到主机的域名,另外两个环境变量 LETSENCRYPT_HOST=LETSENCRYPT_EMAIL= 设置用于 Let's Encrypt 获取证书时必须提供的域名和邮箱。

#!/bin/bash

sudo docker pull wordpress

sudo docker rm -f new-getnas

sudo docker run -d --name new-getnas \
	-v $PWD/site:/var/www/html \
	--link mariadb:db \
	--expose 8888 \
	-e VIRTUAL_HOST=www.yourdomain.com,yourdomain.com \
	-e LETSENCRYPT_HOST=yourdomain.com,www.yourdomain.com \
	-e LETSENCRYPT_EMAIL=yourname@gmail.com \
	--restart always \
	wordpress

That's all!

参考