通过 Docker 部署 Nginx 配置反向代理,并通过 Certbot 获取免费 SSL 证书

上次部署博客还是在腾讯云的「轻量应用服务器」,并使用了附带「宝塔」面板的镜像。因此,诸如部署 Wordpress、配置 Nginx 反向代理、申请 SSL 证书等操作都是通过腾讯云的 GUI 或者宝塔的 WebUI 完成的。这次换用了 Hexo 框架,并且出于某种「依赖洁癖」,选择使用容器化的 Docker Nginx,而不是直接部署 Nginx,于是一下子就不知道该怎么从头配置了。这里记录一下折腾的过程,也希望能帮到其他人。
Ngixn 反向代理(Reverse Proxy)以及 SSL 证书的作用就不多赘述了,这里主要讲一下该怎么通过 Certbot 从 Let’s Encrypt 获取 SSL 证书,以及怎么配置 Nginx 的 Config 文件实现反向代理。
另外,本站目前已经迁移到 Cloudflare Pages(白折腾了),后续或许会再写一篇关于在 Cloudflare Pages 搭建 Hexo 博客的文章。
通过 Docker 部署 Nginx,并通过 Certbot 获取 SSL 证书
本部分主要参考了 Minders Blog 的这篇文章 。这里假定你对 Docker Compose 有一定的了解。
首先创建一个用于存放 Nginx 相关配置、证书等文件的文件夹,并在文件夹下创建如下的 docker-compose.yml:
1 | version: '3' |
这里大概解释一下这个文件描述的配置:
- 将宿主机的 80、443 端口绑定到 Nginx 容器的 80、443 端口,用于处理 HTTP 与 HTTPS 请求。
- 将当前目录下的
./nginx/conf文件夹挂载到 Nginx 容器内的配置文件夹,用于存储 Nginx 配置文件。所有这些挂载的文件夹如果不存在,docker compose都会自动创建。 - 将当前目录下的
./certbot/www同时挂载到 Nginx 容器及 Certbot 容器。这个目录是用于 SSL 验证的。CA 颁发证书给你的前提,是你能证明这个域名确实属于你。因此,一般会通过下发给你特定文件,并要求你将文件放入服务器特定位置,再由 CA 读取文件来完成身份验证。这里使用的 Certbot 容器就是为了简化这一验证步骤,自动化地完成上述验证流程。因此,需要一个共享文件夹,来完成验证文件到 Nginx 服务器的传递。 - 将当前目录下的
./certbot/conf/同时挂载到 Nginx 容器及 Certbot 容器。这个目录将会用于存储 Certbot 申请的证书。
如果你按照我接下来的步骤遇到了什么问题,也可以访问开头提到的 Minders Blog 一步一步构建 docker-compose.yml,但是按照我的理解,直接采用最终版就可以了。
Step 1:初次启动
在根目录(也就是docker-compose.yml 所在的位置)通过 docker compose up -d 启动容器。第一次启动时,会首先从网络下拉 Nginx 与 Certbot 容器的镜像,耐心等待启动完成即可。启动完成后,上述三个文件夹应该被自动创建好了。
Step 2:修改 Nginx 配置文件
在 ./nginx/conf 这个路径下创建一个配置文件,例如 nginx.conf,并填入以下内容:
1 | server { |
别忘记把所有的 example.org 替换为你自己的域名。
- 这个文件定义了一个
server,监听在 IPv4 和 IPv6 的 80 端口,对应的域名是example.org。 - 后面两条
location比较重要。- 第一条定义了当访问
http://example.org/.well-known/acme-challenge/时,应该展示/var/www/certbot中的内容,这是用于 CA 验证。 - 第二条定义了其余所有位置的访问,都应该被 301 重定向到
https://example.org,并保留末尾的$request_uri。
- 第一条定义了当访问
这样,用户通过 HTTP 协议访问你的域名时,就会被重定向到 HTTPS 站点。当然,目前我们还没有配置 Nginx 的 HTTPS 服务器,所以重定向后只能访问到默认界面。
如果你要申请的证书不是指向你的 Apex Domain(不带任何次级域名),那你可以先暂停在这里继续读下去,后面会讲次级域名 SSL 证书的申请。
Step 3:申请 SSL 证书
通过 docker compose restart 重启两个容器。此时,Nginx 的配置应该已经生效了。接着运行
1 | docker compose run --rm certbot certonly --webroot --webroot-path /var/www/certbot/ --dry-run -d example.org |
模拟颁发证书的流程。别忘了将 example.org 换成你自己的域名,并且确保DNS解析正常,通过域名能正常访问到你的 Nginx 服务器。Certbot 可能会询问你的信息,用于在 Let’s Encrypt 注册,正常填写即可。如果最后看到 successful,说明模拟过程没有问题,就可以去掉 --dry-run 参数,真正完成证书颁发流程了。
1 | docker compose run --rm certbot certonly --webroot --webroot-path /var/www/certbot/ -d example.org |
配置 Nginx 反向代理
在上一步中申请到域名证书后,我们就可以继续修改 Nginx 的配置文件,配置反向代理了:
1 | server { |
讲一下新增的部分。
新增的
server,监听在 IPv4 和 IPv6 的 443 端口,并且开启了 SSL 与 HTTP2,对应的域名是example.org。后面两条
ssl_certificate指向你上一步申请到的 SSL 证书。注意,路径中的example.org也要替换为你的真实域名。如果不确定的话,可以docker exec -it <container> bash进入 Nginx 容器确认一下路径。后面一条
location实现了反响代理的部分。将<local IP>与<local port>替换为你本地运行的 HTTP 服务,当用户通过https://example.org访问你的网站时,实际访问到的是反向代理的页面,并且通过 SSL 加密。注意:因为 docker 创建了虚拟子网,因此宿主机上的服务并不能直接通过 127.0.0.1 访问。
- 可以通过
ip a指令检查宿主机的所有网络界面,并找到宿主机在 docker 子网中的 IP,例如172.17.0.1/16。 - 如果不需要隔离容器与宿主机网络,可以去掉
docker-compose.yml中ports的部分,并将网络模式设置为host,这里不多赘述,别忘记通过docker compose up -d重新创建容器。然后就可以通过127.0.0.1直接访问宿主机服务。 - 如果要暴露 80(HTTP)、443(HTTPS)以外的端口,同样要修改
docker-compose.yml中ports的部分,并通过docker compose up -d重新创建容器。
- 可以通过
通过 docker compose restart 重启 Nginx 容器后,即可实现通过 SSL 反向代理本地服务。
提示
如果使用 Cloudflare CDN 为博客加速,需要在 SSL/TLS 选项中将加密模式选中为 Full (strict),在 Flexible 模式下,Cloudflare 会试图访问你的 HTTP 站点,导致循环重定向,最终用户浏览器会报「重定向过多」错误。
为子域名申请证书及配置反向代理
通常我们会将站点的子域名指向不同的服务,并通过 Nginx 统一反向代理,例如 overleaf.example.org 指向本地部署的 Overleaf、qb.example.org 指向 qBitTorrent 的 WebUI 等。想为子域名申请 SSL 证书,和上面的流程基本一致。首先修改 nginx.conf,继续加入对应子域名的服务器:
1 | # ...... |
如果你在这里配置的子域名是 www,并且希望子域名和 Apex Domain 都指向你的主服务(例如博客),可以在 301 重定向的部分直接指向你的 https://example.org。
重复上述的申请证书流程,就能申请到对应子域名 <subdomain>.example.org 的证书了。然后继续添加 HTTPS 服务器:
1 | # ...... |
如果是 www 子域名,可以 301 重定向到你的主域名。如果是其他服务,可以反向代理到本地的其他服务。别忘记 docker compose restart 应用配置修改。
证书续签
Let’s Encrypt 颁发的证书有效期比较短,别忘记及时续签。通过 docker compose run --rm certbot renew 命令,即可通过 Certbot 自动续签全部证书。同样可以加上 --dry-run 参数模拟续签流程。
- 标题: 通过 Docker 部署 Nginx 配置反向代理,并通过 Certbot 获取免费 SSL 证书
- 作者: Limonene
- 创建于 : 2024-01-09 00:37:21
- 更新于 : 2024-01-23 19:57:29
- 链接: https://limonene.top/2024-01-08/通过-Docker-部署-Nginx-配置反向代理,并通过-Certbot-获取免费-SSL-证书/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。