网站通过 certbot 生成免费的 SSL 证书
一、安装依赖
安装 Certbot 和 Nginx 插件
# 对于Ubuntu/Debian系统
sudo apt update
sudo apt install certbot python3-certbot-nginx
# 对于CentOS/RHEL系统
sudo yum install epel-release
sudo yum install certbot python3-certbot-nginx
二、生成证书
# 1、切换到项目目录
cd /home/ubuntu/Code/nofx
# 2、生成证书
sudo certbot certonly --manual --preferred-challenges dns -d tradingbit.ai -d www.tradingbit.ai
示例:
## 生成SSL证书(2025/06/16 17:40)
ubuntu@AwesomeStrategy-Freqtrade:~/stamp-website$ sudo certbot certonly --manual --preferred-challenges dns -d stamp-src20.com -d www.stamp-src20.com
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Requesting a certificate for stamp-src20.com and www.stamp-src20.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name:
_acme-challenge.www.stamp-src20.com.
with the following value:
o13IitbvB9HO9qDO37kBln1epuIvQBfSJqU1r-6mzfY
Before continuing, verify the TXT record has been deployed. Depending on the DNS
provider, this may take some time, from a few seconds to multiple minutes. You can
check if it has finished deploying with aid of online tools, such as the Google
Admin Toolbox: https://toolbox.googleapps.com/apps/dig/#TXT/_acme-challenge.www.stamp-src20.com.
Look for one or more bolded line(s) below the line ';ANSWER'. It should show the
value(s) you've just added.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/stamp-src20.com/fullchain.pem
Key is saved at: /etc/letsencrypt/live/stamp-src20.com/privkey.pem
This certificate expires on 2025-09-14.
These files will be updated when the certificate renews.
NEXT STEPS:
- This certificate will not be renewed automatically. Autorenewal of --manual certificates requires the use of an authentication hook script (--manual-auth-hook) but one was not provided. To renew this certificate, repeat this same certbot command before the certificate's expiry date.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
* Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
* Donating to EFF: https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# 查看
sudo cd /etc/letsencrypt/live/stamp-src20.com
docker run -d \
-p 80:80 \
-p 443:443 \
-v /etc/letsencrypt:/etc/letsencrypt \ # 挂载宿主机证书目录
-v /var/www/certbot:/var/www/certbot \ # 挂载验证文件目录
--restart unless-stopped \ # 自动重启
--name stamp-website \
stamp-website
# 在宿主机创建目录并设置权限
sudo mkdir -p /var/www/certbot/.well-known/acme-challenge
sudo chmod -R 755
/var/www/certbot
# 验证目录结构
ls -la /var/www/certbot/.well-known/acme-challenge
## 证书自动续期
以下是针对 Docker 容器与宿主机共享 Certbot 证书的优化方案,确保自动续期和证书同步:
---
### **1. 修改后的 Dockerfile**
```dockerfile
# 使用Node.js作为构建环境
FROM node:18-alpine AS builder
WORKDIR /app
# 复制package文件
COPY package*.json ./
COPY pnpm-lock.yaml ./
# 安装pnpm并安装依赖
RUN npm install -g pnpm
RUN pnpm install
# 复制源代码
COPY . .
# 构建应用
RUN pnpm run build
# 使用Nginx作为生产环境
FROM nginx:alpine
# 创建必要的目录(无需复制证书,通过挂载实现)
RUN mkdir -p /var/www/certbot && \
mkdir -p /etc/letsencrypt/live/stamp-src20.com
# 复制构建文件和Nginx配置
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
# 暴露端口
EXPOSE 80 443
# 启动Nginx
CMD ["nginx", "-g", "daemon off;"]
关键修改:
- 移除
COPY证书的指令(改为运行时挂载) - 保留目录创建命令(确保挂载点存在)
2. 容器运行命令优化
sudo docker run -d \
-p 80:80 \
-p 443:443 \
-v /etc/letsencrypt:/etc/letsencrypt \ # 挂载宿主机证书目录
-v /var/www/certbot:/var/www/certbot \ # 挂载验证文件目录
--restart unless-stopped \ # 自动重启
--name stamp-website \
stamp-website
| 挂载说明: | 宿主机路径 | 容器路径 | 用途 |
|---|---|---|---|
/etc/letsencrypt |
/etc/letsencrypt |
证书自动同步 | |
/var/www/certbot |
/var/www/certbot |
Certbot 验证文件 |
3. 证书自动续期方案
(1)在宿主机设置续期脚本
创建 /usr/local/bin/renew_cert.sh:
#!/bin/bash
# 续期证书
certbot renew --quiet --force-renewal
# 重启容器使新证书生效
docker restart stamp-website
赋予执行权限:
sudo chmod +x /usr/local/bin/renew_cert.sh
(2)添加 cron 任务
(sudo crontab -l 2>/dev/null; echo "0 3 * * * /usr/local/bin/renew_cert.sh") | sudo crontab -
4. Nginx 配置验证
您的 nginx.conf 配置完全正确,但需确保:
- 证书路径与挂载路径一致:
ssl_certificate /etc/letsencrypt/live/stamp-src20.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/stamp-src20.com/privkey.pem; - 验证文件目录存在:
location ^~ /.well-known/acme-challenge/ { root /var/www/certbot; default_type "text/plain"; }
5. 验证流程
-
检查挂载是否生效:
docker exec stamp-website ls /etc/letsencrypt/live/stamp-src20.com # 应显示 fullchain.pem 和 privkey.pem -
测试证书续期:
sudo /usr/local/bin/renew_cert.sh docker logs stamp-website | grep "SSL" -
检查 HTTPS 访问:
curl -vk https://stamp-src20.com
6. 关键注意事项
-
权限问题:
- 确保容器用户(通常为
nginx)有证书文件的读取权限:sudo chmod -R 755 /etc/letsencrypt/{live,archive}
- 确保容器用户(通常为
-
证书符号链接:
- Certbot 使用符号链接管理证书,挂载时需保持链接结构:
ls -l /etc/letsencrypt/live/stamp-src20.com # 应显示: # lrwxrwxrwx 1 root root 42 Jan 1 00:00 fullchain.pem -> ../../archive/stamp-src20.com/fullchain1.pem
- Certbot 使用符号链接管理证书,挂载时需保持链接结构:
-
备份建议:
# 定期备份证书 sudo cp -r /etc/letsencrypt /backup/letsencrypt_$(date +%Y%m%d)
架构示意图
graph TD
A[宿主机] -->|挂载| B[Docker容器]
A --> C[/etc/letsencrypt]
A --> D[/var/www/certbot]
B --> E[Nginx]
E -->|读取| C
E -->|验证文件| D
F[Certbot] -->|续期| C
F -->|验证| D
按此方案配置后,证书可自动续期并实时同步到容器,无需手动干预。
为者常成,行者常至
自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)