给网站加上 HTTPS访问,这个过程的核心,是配置SSL域名证书,如何免费使用域名证书呢?本文通过使用 Certbot 工具从 Let's Encrypt 自动申请一个 免费且有效期为90天 的 SSL 证书,并配置到期自动更新,通过这种方式完成个人搭建网站的https访问,并面试无限期使用SSL域名证书。
为了让过程更清晰,将准备两个方案。方案一 最直接,易于理解;方案二则能完美融入现有的 Docker 环境,自动化程度更高。可以根据自己的偏好来选择。
📝 准备条件
在开始之前,请先确认以下几点,这是申请证书成功的基础:
- 域名解析正确:确保域名例如 `example.com 已经解析到了服务器的公网 IP。
- 端口已放行 :确保服务器安全组(防火墙)的 80 (HTTP) 和 443 (HTTPS) 端口都已对外开放。
- Nginx 正常运行 : Nginx 容器
nginx-gateway正在运行,并能通过 80 端口访问到网站。
🧩 方案一:在宿主机上直接使用 Certbot(推荐新手)
这个方案最直观,Certbot 会直接与 Nginx 容器协作,自动完成证书申请和配置。
1. 进入服务器并安装 Certbot
在服务器终端,执行以下命令安装 Certbot 及其 Nginx 插件:
bash
sudo apt update
sudo apt install certbot python3-certbot-nginx -y
2. 暂停 Nginx 容器并开放端口
Certbot 在申请证书时需要占用 80 和 443 端口进行验证。为了让它在宿主机上工作,我们需要暂停 Nginx 容器:
bash
cd ~/deploy
docker stop nginx-gateway
3. 执行 Certbot 命令申请证书
现在,运行以下命令,Certbot 会自动为域名申请证书并尝试配置 Nginx。
bash
sudo certbot --nginx -d example.com
--nginx:告诉 Certbot 自动修改 Nginx 配置。-d example.com:指定要申请证书的域名。
命令执行过程中,Certbot 会询问邮箱地址(用于接收续期提醒等)并要求同意服务条款。按照提示操作即可。
4. 重启 Nginx 容器并挂载证书
证书申请成功后,会保存在宿主机的 /etc/letsencrypt/live/example.com/ 目录下。为了让 Nginx 容器能读取到证书,我们需要在 docker-compose.yml 中将这个目录挂载进去,并启用 443 端口的映射。
编辑 ~/deploy/docker-compose.yml,修改 nginx 服务部分:
yaml
nginx:
image: nginx:alpine
container_name: nginx-gateway
ports:
- "80:80"
- "443:443" # 新增:映射 443 端口
volumes:
- ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro
- /etc/letsencrypt:/etc/letsencrypt:ro # 新增:挂载证书目录
# ... 其他配置保持不变
保存后,重新创建并启动 Nginx 容器:
bash
docker compose up -d nginx
🐳 方案二:使用 Docker 化的 Certbot
这个方案更符合 Docker 部署方式。它创建一个独立的 Certbot 容器来完成证书的申请和续期。
1. 修改 docker-compose.yml 添加 Certbot 服务
在 ~/deploy/docker-compose.yml 的 services 部分,添加一个新的 certbot 服务:
yaml
certbot:
image: certbot/certbot
container_name: certbot
volumes:
- ./data/certbot/www:/var/www/certbot # 用于域名验证的临时目录
- ./data/certbot/conf:/etc/letsencrypt # 证书存储目录
entrypoint: /bin/sh -c "trap exit TERM; while :; do sleep 12h & wait $${!}; certbot renew --webroot -w /var/www/certbot --post-hook 'nginx -s reload' || true; done"
restart: unless-stopped
2. 创建证书存储和验证目录
bash
mkdir -p ~/deploy/data/certbot/{www,conf}
3. 修改 Nginx 配置以支持证书验证
为了让 Certbot 能验证域名的所有权,Nginx 需要为 /.well-known/acme-challenge/ 路径提供访问。
编辑 ~/deploy/nginx/nginx.conf,在 server 块中添加以下 location 配置:
nginx
server {
listen 80;
server_name example.com;
# 新增:用于 Certbot 域名验证
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
# ... 原有的 location 配置保持不变 ...
}
同时,确保 Nginx 容器的 volumes 中挂载了证书验证目录。修改 docker-compose.yml 中 nginx 服务的 volumes 部分:
yaml
volumes:
- ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf:ro
- ./data/certbot/www:/var/www/certbot:ro # 新增:挂载验证目录
4. 重启 Nginx 容器使配置生效
bash
docker compose restart nginx
5. 运行 Certbot 容器申请证书
现在,运行一个一次性命令来申请证书:
bash
docker compose run --rm certbot certonly --webroot -w /var/www/certbot -d example.com --email your-email@example.com --agree-tos --no-eff-email
certonly:只获取证书,不自动配置。--webroot -w /var/www/certbot:指定验证文件存放的目录。- 将
your-email@example.com替换为真实邮箱。
成功后,证书会保存在 ./data/certbot/conf/live/example.com/ 目录下。
6. 修改 Nginx 配置以启用 HTTPS
现在,我们需要修改 Nginx 配置来使用这个证书。编辑 ~/deploy/nginx/nginx.conf,在文件最前面添加一个新的 server 块来处理 HTTPS 流量。
nginx
# 新增:HTTPS server 块
server {
listen 443 ssl;
server_name example.com;
# 证书路径 (映射到容器内的路径)
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
# SSL 安全配置 (建议添加)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
# 这里复制原来的所有 location 配置 (/, /couplets, /shici 等)
# ... 包括 /api 代理等 ...
location / {
proxy_pass http://nextjs-app:5000;
# ... proxy_set_header 等 ...
}
location /couplets {
# ... 配置 ...
}
# ...
}
# 修改原有的 HTTP server 块,强制跳转到 HTTPS
server {
listen 80;
server_name example.com;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
# 其他所有请求重定向到 HTTPS
location / {
return 301 https://$host$request_uri;
}
}
7. 重启 Nginx
bash
docker compose restart nginx
🔄 证书自动续期
Let's Encrypt 证书有效期为 90 天,但不用担心,我们可以设置自动续期。
-
方案一续期 :Certbot 会自动创建一个 systemd 定时任务。可以用
sudo systemctl status certbot.timer查看其状态。也可以手动测试续期:sudo certbot renew --dry-run。 -
方案二续期 :在
docker-compose.yml中定义的 Certbot 服务会每12小时自动检查一次 证书有效期,并在需要时自动续期。可以通过docker logs certbot查看其运行日志。
✅ 验证与故障排查
- 验证 HTTPS :在浏览器中访问
https://example.com,地址栏应显示安全锁标志。 - 排查问题 :
- 证书申请失败:检查域名解析是否正确,以及服务器的 80 和 443 端口是否已对外开放。
- 重定向循环 (Too many redirects):检查 Nginx 配置,确保 HTTP 跳转 HTTPS 的规则没有与后端的重定向规则冲突。
- 证书路径错误 :仔细核对
ssl_certificate和ssl_certificate_key的路径是否与证书实际存放路径一致。