使用 Certbot 在 Docker 环境中与 Nginx 配合,来自动申请和续期 SSL/TLS 证书,通常需要一些额外的配置,因为 Docker 容器与宿主机环境有所不同。不过,通过合适的设置,可以成功实现。
以下是如何在 Docker 环境中使用 Certbot 和 Nginx 来自动获取和续期 SSL 证书的步骤。
1. 创建 Docker 网络
首先,需要为 Nginx 和 Certbot 容器创建一个 Docker 网络,确保它们能够相互通信。
docker network create nginx-certbot
2. 创建 Nginx 容器
假设你已经有一个 Nginx 配置文件,它能够处理 HTTP 请求并提供 Web 服务。你需要将这个配置挂载到 Nginx 容器中。
首先,创建一个目录来存放 Nginx 配置和网站内容:
mkdir -p ~/nginx/html ~/nginx/conf.d
将你的 Nginx 配置文件放入 ~/nginx/conf.d
目录下,确保配置能够处理 HTTP 请求。例如,你可以创建一个名为 default.conf
的文件:
server {
listen 80;
server_name yourdomain.com; # 将 this 替换为你的域名
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
# ACME challenge for Certbot
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
}
然后,使用下面的命令启动 Nginx 容器:
docker run -d \
--name nginx \
--network nginx-certbot \
-v ~/nginx/html:/usr/share/nginx/html \
-v ~/nginx/conf.d:/etc/nginx/conf.d \
-v ~/nginx/certbot:/var/www/certbot \
-p 80:80 \
nginx
此命令将 Nginx 容器与 nginx-certbot
网络连接,并将 Nginx 配置和网站内容挂载到容器中。同时,使用了 /.well-known/acme-challenge/
路径来处理 Certbot 的域名验证请求。
3. 创建 Certbot 容器
接下来,启动 Certbot 容器以申请证书。你需要将 Certbot 与 Nginx 容器连接起来,以便 Certbot 可以在 HTTP 挑战过程中与 Nginx 通信。
docker run -it --rm \
--name certbot \
--network nginx-certbot \
-v ~/nginx/certbot:/var/www/certbot \
-v ~/nginx/certbot/etc/letsencrypt:/etc/letsencrypt \
certbot/certbot certonly \
--webroot \
--webroot-path=/var/www/certbot \
--email your-email@example.com \
--agree-tos \
--no-eff-email \
-d yourdomain.com
这条命令会执行以下操作:
- 使用 certbot/certbot
镜像运行 Certbot。
- --webroot
指定验证方法,并通过 --webroot-path=/var/www/certbot
告诉 Certbot 找到需要验证的文件。
- -d yourdomain.com
指定要为其申请证书的域名。
- --email your-email@example.com
设置联系邮箱。
- --agree-tos
和 --no-eff-email
分别同意 Let's Encrypt 的服务条款并拒绝接收推广邮件。
证书将被保存在宿主机上的 ~/nginx/certbot/etc/letsencrypt
目录中。
4. 配置 Nginx 使用 SSL 证书
完成证书申请后,更新你的 Nginx 配置以使用生成的 SSL 证书。在 ~/nginx/conf.d/default.conf
中,修改配置文件以启用 HTTPS:
server {
listen 80;
server_name yourdomain.com;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
# HTTP 301 redirect to HTTPS
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
配置说明:
- 第一部分将 HTTP 请求重定向到 HTTPS。
- 第二部分启用了 HTTPS,并指定了由 Certbot 获取的证书路径(/etc/letsencrypt/live/yourdomain.com/
)。
然后,重载 Nginx 配置:
docker exec nginx nginx -s reload
5. 自动续期证书
为了自动续期证书,创建一个定时任务(如 Cron 任务)来定期运行 Certbot 续期命令。在 Docker 中,可以通过运行一个新的容器来自动续期:
docker run -d \
--name certbot-renewal \
--network nginx-certbot \
-v ~/nginx/certbot/etc/letsencrypt:/etc/letsencrypt \
-v ~/nginx/certbot:/var/www/certbot \
certbot/certbot renew --quiet && docker exec nginx nginx -s reload
这将定期检查证书的到期日期,如果证书即将过期,Certbot 会自动续期证书并重载 Nginx 配置。
你可以使用 cron
或 systemd
来定期运行这个容器(例如,每天运行一次):
0 0,12 * * * docker run -d --rm --name certbot-renewal --network nginx-certbot -v ~/nginx/certbot/etc/letsencrypt:/etc/letsencrypt -v ~/nginx/certbot:/var/www/certbot certbot/certbot renew --quiet && docker exec nginx nginx -s reload
总结
使用 Docker 容器和 Nginx 配合 Certbot 获取和自动续期 SSL 证书的流程如下:
1. 使用 docker network create
创建一个共享网络。
2. 启动 Nginx 容器,配置 HTTP 请求处理和 .well-known/acme-challenge/
目录。
3. 启动 Certbot 容器,使用 certonly
命令获取证书。
4. 更新 Nginx 配置以启用 HTTPS,重载 Nginx。
5. 配置定时任务(如 cron)来自动续期证书。
这种方法使得在 Docker 环境中管理 HTTPS 变得更加自动化和灵活。