Docker环境下Nginx HTTPS配置:Let’s Encrypt证书申请与部署
- 软件安装
- 2024-03-27
- 60热度
- 0评论
随着互联网的不断发展,网络安全问题日益凸显,HTTPS作为一种安全的网络通信协议,逐渐成为了网站标配。目前市面上有很多SSL供应商,如阿里、腾讯、DigiCert等。
选择Let's Encrypt作为SSL证书提供商,主要是因为其免费、易用、受信任的特点。Let's Encrypt打破了传统证书市场的垄断,使得任何网站都能轻松获得免费的SSL证书,降低了运营成本。同时,其提供的自动化工具简化了证书申请、安装和续期的过程,提高了效率。
本文将详细介绍如何在Docker环境下为Nginx部署Let's Encrypt证书,配置HTTPS。为了使教程更简单,本文使用 Docker-Compose进行操作。
一、准备工作
在开始之前,你需要了解一些情况:
1、请确保已经安装了Docker及Docker-Compose运行环境(可以参考此文章);
2、此外,你还需要一个域名(这里假定域名为example.xyz),并将该域名的DNS解析指向你的服务器IP地址;
3、使用非root 用户操作文章中的内容,并创建docker-compose 文件夹及docker-compose.yml;
4、确保防火墙允许80及443端口通过,如果使用了云服务,需要在安全组中开放对应端口访问权限;
二、搭建Nginx服务
利用vim编辑docker-compose.yml 文件,并配置如下内容:
version: '3.1'
services:
webserver:
image: nginx:1.22.1
ports:
- 80:80
- 443:443
restart: always
volumes:
- ./nginx/conf/:/etc/nginx/conf.d/:ro
- ./certbot/www:/var/www/certbot/:ro
- ./nginx/logs/:/var/log/nginx/:rw
关键信息解析,定义了一个webserver服务,镜像为nginx-1.22.1;
ports:
表示定义了容器和宿主机之间的端口映射:- 80:80
将宿主机的80端口映射到容器的80端口,这通常是HTTP服务的默认端口。- 443:443
将宿主机的443端口映射到容器的443端口,这通常是HTTPS服务的默认端口。
restart: always
表示容器的重启策略。always意味着无论容器退出时状态如何,Docker都会尝试重新启动它。-
volumes:
定义了容器和宿主机之间的卷映射,用于共享文件或目录。- ./nginx/conf/:/etc/nginx/conf.d/:ro
表示配置文件的映射,当前目录下加载nginx的配置;- ./certbot/www:/var/www/certbot/:ro
表示证书访问地址,用于后续证书的生成和验证;- ./nginx/logs/:/var/log/nginx/:rw
表示映射nginx的日志文件,会将容器中的日志写入到主机挂载目录;
请注意,我在卷声明的末尾添加了一个
:ro
。 表示“只读”。容器将永远无权将文件更新到此文件夹中。这没什么大不了的,但这非常的有用。它可以避免浪费宝贵的几个小时的调试时间。将以下配置文件添加到本地文件夹中(./nginx/conf/),文件名为my.conf。不要忘记使用您自己的域名进行更新。
server {
listen 80;
listen [::]:80;
server_name example.xyz www.example.xyz;
server_tokens off;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
}
这里的配置非常简单,以一个特殊的块,/.well-known/acme-challenge/
用于后续let's encrypt证书的验证;
可以进入docker-compose 文件夹,执行以下命令,nginx服务即可访问:
docker-compose up -d
二、搭建Certbot服务
以certbot为客户端,采用webroot的方式生成ssl证书,并完成验证。
为此,我们需要使用 certbot 的 docker 映像,并将其作为服务添加到我们的 Docker-Compose 文件中(完整版本)。
version: '3.1'
services:
webserver:
image: nginx:latest
ports:
- 80:80
- 443:443
restart: always
volumes:
- ./nginx/conf/:/etc/nginx/conf.d/:ro
- ./certbot/www:/var/www/certbot/:ro
- ./certbot/conf/:/etc/nginx/ssl/:ro
- ./nginx/logs/:/var/log/nginx/:rw
certbot:
image: certbot/certbot:latest
volumes:
- ./certbot/www/:/var/www/certbot/:rw
- ./certbot/conf/:/etc/letsencrypt/:rw
执行docker-compose up -d 命令,
我们现在有两个服务,一个用于 nginx,一个用于 Certbot。您可能已经注意到他们声明了相同的卷。这是为了让他们一起交流。
您现在可以通过运行以下命令(注意替换为自己的域名)来测试一切是否正常。您应该会收到一条成功消息,例如“试运行成功”。
docker-compose run --rm certbot certonly --webroot --webroot-path /var/www/certbot/ --dry-run -d example.xyz -d www.example.xyz
如果以上命令运行成功,去掉--dry-run
重新运行。在./certbot/conf
可以看到已生成的证书文件夹。
既然我们有了这些证书,剩下的就是nginx上的配置了(完整版本):
server {
listen 80;
listen [::]:80;
server_name example.xyz www.example.xyz;
server_tokens off;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://example.xyz$request_uri;
}
}
server {
listen 443 default_server ssl http2;
listen [::]:443 ssl http2;
server_name example.org;
ssl_certificate /etc/nginx/ssl/live/example.xyz/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/live/example.xyz/privkey.pem;
location / {
# ...
}
}
现在重新加载 nginx 服务器,你的Nginx服务器已经可以通过HTTPS访问了。
三、证书续订
Certbot 和 Let's Encrypt 可能会遇到的一个小问题是证书只能持续 3 个月,为了Https的可用性,您将需要定期更新您使用的证书。
由于我们有这个 Docker 环境,因此更新 Let's Encrypt 证书比以往任何时候都更容易!执行以下命令即可:
docker compose run --rm certbot renew
也可以通过定时任务执行, 在docker-compose 下增加 文件,内容如下:
#!/bin/bash
# 对应的docker-compose 目录
cd /path/to/docker-compose
# 执行 certbot renew
docker-compose run --rm certbot renew
# 检查 certbot 是否成功生成了新的证书
if [[ $? -eq 0 ]]; then
echo "Certbot renewed certificates successfully."
# 重新加载 Nginx 以应用新的 SSL 证书
docker-compose exec webserver nginx -s reload
else
echo "Certbot did not renew any certificates."
fi
保存此脚本为 renew_certificates.sh
并赋予执行权限:
chmod +x renew_certificates.sh
设置cron定时任务,例如每月的第一天凌晨执行此脚本
crontab -e
输入 对应的数字 ,选择 /usr/bin/vim.basic 模式,进入vim。如果选择错误,可以按照说明退出后,执行select-editor 进行重新选择。
然后在打开的编辑器中添加一行:
0 0 1 * * /path/to/docker-compose/renew_certificates.sh >/dev/null 2>&1
这行的意思是在每个月的第一天凌晨0点0分执行 /path/to/renew_certificates.sh 脚本,并将输出重定向到/dev/null以避免邮件通知。
请根据实际情况替换 /path/to/ 为实际脚本存放路径。
注意:这里的例子假设你已经有一个使用Docker Compose管理的包含certbot和nginx容器的服务。docker-compose exec nginx nginx -s reload 命令用于在Nginx容器内部执行nginx -s reload来加载新的SSL证书。如果您的部署结构不同,可能需要相应调整命令。
四、总结
执行以上脚本如果修改目录,一定要注意不同目录的对应关系。否则可能会出现不同错误。