本文档记录了为域名配置Let’s Encrypt SSL证书和Nginx反向代理的完整过程。

目录


1. 环境要求

1.1 基本要求

  • 操作系统: Ubuntu 20.04+ / Debian 10+ 或其他Linux发行版
  • 域名: 已注册的域名,并可以管理DNS记录
  • 服务器: 具有公网IP的云服务器
  • 权限: sudo或root权限
  • 端口:
    • 80端口(HTTP)- 用于证书验证和HTTP到HTTPS重定向
    • 443端口(HTTPS)- 用于SSL/TLS加密连接

1.2 后端服务说明

本指南适用于任何后端服务,例如:

  • Web框架: Express、Django、Flask、Spring Boot、FastAPI等
  • 前端应用: React、Vue、Angular构建后的静态文件
  • 其他服务: 任何监听在本地端口的HTTP服务

示例场景:

  • example.com - 前端静态网站(React/Vue等)
  • api.example.com - 后端API服务(任意端口,如8080)
  • admin.example.com - 管理后台(任意端口,如3000)

2. 快速开始:选择证书申请方案

2.1 三种方案对比

方案 验证方式 自动续期 通配符支持 适用场景 推荐度
方案A DNS手动验证 子域名较多或不确定 ⭐⭐
方案B HTTP自动验证 子域名固定且较少 ⭐⭐⭐⭐
方案C DNS API自动 需要通配符+自动续期 ⭐⭐⭐⭐⭐

2.2 安装Certbot

所有方案都需要先安装Certbot:

sudo apt update
sudo apt install certbot

2.3 如何选择

选择方案B(推荐新手)

  • 只使用2-3个固定子域名
  • 希望配置简单、自动续期
  • 不介意新增子域名时重新申请证书

选择方案C(推荐长期使用)

  • 需要使用多个子域名或通配符
  • 希望一次配置、永久自动续期
  • DNS服务商支持API(如Cloudflare、阿里云等)

选择方案A(不推荐)

  • DNS服务商不支持API
  • 可以接受每90天手动续期一次

3. 方案A:通配符证书(手动DNS验证)

⚠️ 注意: 此方案无法自动续期,每90天需要手动操作一次

3.1 申请证书

sudo certbot certonly --manual --preferred-challenges dns \
  -d "*.example.com" \
  -d "example.com"

3.2 添加DNS TXT记录

Certbot会提示添加TXT记录:

  • 类型: TXT
  • 名称: _acme-challenge
  • : Certbot提供的验证字符串(每次都不同)
  • TTL: 600

3.3 验证DNS传播

# 检查DNS记录是否生效
dig TXT _acme-challenge.example.com @8.8.8.8

确认记录存在后,回到Certbot窗口按回车继续验证。

3.4 验证配置

# 查看证书配置(应显示 authenticator = manual)
sudo cat /etc/letsencrypt/renewal/example.com.conf | grep authenticator

# 测试续期(会失败,这是正常的)
sudo certbot renew --dry-run

💡 提示: 如需自动续期,请考虑迁移到方案C

完成后跳转到: 第7章 Nginx配置


4. 方案B:指定域名(HTTP自动验证)

推荐: 配置简单,可自动续期

4.1 安装Nginx插件

sudo apt install python3-certbot-nginx

4.2 申请证书

# 列出所有需要证书的域名
sudo certbot certonly --nginx \
  -d example.com \
  -d www.example.com \
  -d api.example.com \
  -d admin.example.com

4.3 启用自动续期

# 启用自动续期服务
sudo systemctl enable certbot.timer
sudo systemctl start certbot.timer

# 验证自动续期服务状态
sudo systemctl status certbot.timer

4.4 验证配置

# 查看证书配置(应显示 authenticator = nginx)
sudo cat /etc/letsencrypt/renewal/example.com.conf | grep authenticator

# 测试自动续期(应该成功)
sudo certbot renew --dry-run

预期结果: “Congratulations, all simulated renewals succeeded”

完成后跳转到: 第7章 Nginx配置


5. 方案C:通配符证书(DNS API自动验证)

最佳方案: 支持通配符,可自动续期

5.1 为什么选择Cloudflare

  • ✅ 完全免费
  • ✅ 有成熟的Certbot插件
  • ✅ 支持通配符证书自动续期
  • ✅ 额外提供CDN、DDoS防护等功能
  • ✅ 全球节点,DNS解析速度快

💡 其他DNS服务商: 阿里云、腾讯云、AWS Route53等也支持,但需要安装对应插件

5.2 迁移DNS到Cloudflare

步骤1:注册并添加域名

  1. 访问 https://dash.cloudflare.com/sign-up 注册免费账号
  2. 登录后点击"添加站点"
  3. 输入您的域名(如 example.com
  4. 选择 Free Plan(免费计划)

步骤2:复制DNS记录

  • Cloudflare会自动扫描现有DNS记录
  • 检查扫描结果,确认所有重要记录都已导入
  • 如有遗漏(如A记录、CNAME记录等),手动添加

步骤3:修改Nameservers

  1. Cloudflare会显示两个Nameserver地址,例如:
    • ava.ns.cloudflare.com
    • ben.ns.cloudflare.com
  2. 登录您原DNS服务商的控制面板(如Spaceship、NameSilo、GoDaddy等)
  3. 找到域名的 Nameservers 设置
  4. 替换为Cloudflare提供的Nameserver地址
  5. 保存更改

步骤4:等待DNS生效

  • Nameserver更改通常需要 2-24小时 生效
  • 可以在Cloudflare后台查看激活状态
  • 收到激活邮件后即可继续下一步

验证DNS是否已迁移成功:

dig NS example.com

5.3 获取Cloudflare API Token

步骤1:创建API Token

  1. 登录Cloudflare后台
  2. 点击右上角头像 → My Profile
  3. 左侧菜单选择 API Tokens
  4. 点击 Create Token

步骤2:配置Token权限

选择模板 “Edit zone DNS” 或自定义权限:

  • Permissions: Zone - DNS - Edit
  • Zone Resources: Include - Specific zone - example.com

点击 Continue to summaryCreate Token

步骤3:保存Token

  • 复制生成的Token(只显示一次
  • 格式类似:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

5.4 在服务器上配置Cloudflare插件

步骤1:安装插件

# 安装Cloudflare DNS插件
sudo apt update
sudo apt install python3-certbot-dns-cloudflare

# 验证安装
dpkg -l | grep certbot

步骤2:创建凭据文件

# 创建凭据文件目录
sudo mkdir -p /etc/letsencrypt/cloudflare

# 创建凭据文件
sudo nano /etc/letsencrypt/cloudflare/credentials.ini

在文件中添加以下内容(替换成您的实际Token):

# Cloudflare API token
dns_cloudflare_api_token = YOUR_CLOUDFLARE_API_TOKEN_HERE

设置安全权限:

# 设置为仅root可读
sudo chmod 600 /etc/letsencrypt/cloudflare/credentials.ini

步骤3:申请证书

如果已有旧证书,建议先备份:

# 备份现有证书(可选)
sudo cp -r /etc/letsencrypt /etc/letsencrypt.backup-$(date +%Y%m%d)

# 删除旧证书(如果存在)
sudo certbot delete --cert-name example.com

使用Cloudflare DNS API申请通配符证书:

sudo certbot certonly \
  --dns-cloudflare \
  --dns-cloudflare-credentials /etc/letsencrypt/cloudflare/credentials.ini \
  --dns-cloudflare-propagation-seconds 60 \
  -d "*.example.com" \
  -d "example.com"

步骤4:启用自动续期

# 启用自动续期服务
sudo systemctl enable certbot.timer
sudo systemctl start certbot.timer

# 查看下次续期时间
sudo systemctl list-timers certbot.timer

步骤5:验证配置

# 查看证书配置(应显示 authenticator = dns-cloudflare)
sudo cat /etc/letsencrypt/renewal/example.com.conf | grep authenticator

# 测试自动续期(应该成功)
sudo certbot renew --dry-run

预期结果: “Congratulations, all simulated renewals succeeded”

5.5 常见问题

Q: DNS迁移会影响现有服务吗? A: 不会。只要正确复制了所有DNS记录,服务不会中断。

Q: 必须使用Cloudflare吗? A: 不是。如果您的DNS服务商支持API,可以使用对应插件:

  • 阿里云:python3-certbot-dns-aliyun
  • 腾讯云:certbot-dns-dnspod
  • AWS Route53:python3-certbot-dns-route53

Q: API Token会过期吗? A: Cloudflare的API Token默认不会过期,除非手动设置或撤销。

完成后跳转到: 第7章 Nginx配置


6. DNS记录配置

6.1 添加A记录

确保域名解析到您的服务器IP:

类型 名称 TTL
A @ 服务器公网IP 600
A www 服务器公网IP 600
A api 服务器公网IP 600
A admin 服务器公网IP 600

💡 提示: 如果使用了Cloudflare,建议开启CDN(橙色云朵图标)

6.2 验证DNS解析

# 验证主域名
dig example.com

# 验证子域名
dig api.example.com
dig admin.example.com

7. Nginx配置

7.1 安装Nginx

sudo apt update
sudo apt install nginx
sudo systemctl enable nginx
sudo systemctl start nginx

7.2 配置示例

场景说明

假设您有以下服务:

  • 前端应用 (example.com) - 静态文件位于 /var/www/frontend
  • 后端API (api.example.com) - 运行在 http://127.0.0.1:8080
  • 管理后台 (admin.example.com) - 运行在 http://127.0.0.1:3000

创建配置文件

sudo nano /etc/nginx/conf.d/example.conf

完整配置内容

# HTTP 重定向到 HTTPS
server {
    listen 80;
    server_name example.com www.example.com api.example.com admin.example.com;
    return 301 https://$server_name$request_uri;
}

# 主站 - 前端静态文件
server {
    listen 443 ssl http2;
    server_name example.com www.example.com;

    # SSL 证书配置
    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_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;

    # 前端静态文件
    root /var/www/frontend;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
    }
}

# API服务 - 反向代理到后端
server {
    listen 443 ssl http2;
    server_name api.example.com;

    # SSL 证书配置
    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_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;

    location / {
        # 代理到后端服务(可以是任意技术栈:Spring Boot、Express、Django等)
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_redirect off;

        # 超时设置
        proxy_connect_timeout 60s;
        proxy_send_timeout 60s;
        proxy_read_timeout 60s;
    }
}

# 管理后台 - 反向代理到本地服务
server {
    listen 443 ssl http2;
    server_name admin.example.com;

    # SSL 证书配置
    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_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;

    location / {
        # 代理到管理后台服务
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_redirect off;
    }
}

7.3 配置说明

根据您的实际情况修改:

配置项 说明 示例
server_name 域名或子域名 api.example.com
ssl_certificate 证书路径(通配符和指定域名路径相同) /etc/letsencrypt/live/example.com/fullchain.pem
root 静态文件目录 /var/www/frontend
proxy_pass 后端服务地址 http://127.0.0.1:8080

💡 通配符证书路径: 即使使用 *.example.com,证书路径仍然是 /etc/letsencrypt/live/example.com/

7.4 测试和加载配置

# 测试配置语法
sudo nginx -t

# 重新加载配置(首次配置建议用restart)
sudo systemctl restart nginx

# 检查Nginx状态
sudo systemctl status nginx

7.5 conf.d目录说明

  • 自动生效: /etc/nginx/conf.d/ 目录下的 .conf 文件会自动被包含
  • 无需符号链接: 不同于 sites-available/sites-enabled 模式
  • 标准做法: 大多数Linux发行版的推荐配置方式

8. 测试和验证

8.1 检查后端服务状态

# 检查后端服务是否运行(替换为实际端口)
sudo ss -tlnp | grep :8080
sudo ss -tlnp | grep :3000

# 检查Nginx状态
sudo systemctl status nginx

# 查看Nginx日志
sudo tail -f /var/log/nginx/error.log
sudo tail -f /var/log/nginx/access.log

8.2 测试访问

在浏览器中访问:

8.3 验证SSL证书

# 查看所有证书及到期时间
sudo certbot certificates

# 验证服务器实际返回的证书
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates

# 验证子域名证书
echo | openssl s_client -connect api.example.com:443 -servername api.example.com 2>/dev/null | openssl x509 -noout -dates

8.4 验证自动续期配置

# 查看证书的authenticator类型
sudo cat /etc/letsencrypt/renewal/example.com.conf | grep authenticator

# 测试自动续期
sudo certbot renew --dry-run

预期结果

  • authenticator = nginxdns-cloudflare → 可自动续期
  • authenticator = manual → 无法自动续期(需每90天手动操作)

9. 常见问题

9.1 证书自动续期失败

问题: certbot renew 提示 “The manual plugin is not working”

原因: 使用手动DNS验证(--manual)申请的证书无法自动续期

解决方案:

  1. 重新手动申请(每90天一次):

    sudo certbot certonly --manual --preferred-challenges dns \
      -d "*.example.com" -d "example.com"
    
  2. 迁移到方案C(推荐):参考 第5章

  3. 改用方案B(如果不需要通配符):

    sudo certbot delete --cert-name example.com
    sudo certbot certonly --nginx -d example.com -d api.example.com
    

9.2 证书更新后浏览器仍显示过期

问题: 证书文件已更新,但浏览器提示不安全

解决方案:

  1. 重启Nginx(而不是reload):

    sudo systemctl restart nginx
    
  2. 验证服务器返回的证书:

    echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates
    
  3. 清除浏览器缓存:

    • 使用无痕模式测试
    • 或清除"缓存的图片和文件"以及"SSL状态"

9.3 DNS验证失败

问题: “Incorrect TXT record” 错误

解决方案:

  1. 确保使用Certbot当前显示的验证码(每次都不同)
  2. 删除旧的TXT记录,添加新的验证码
  3. 等待DNS传播(2-10分钟)
  4. 验证DNS记录: dig TXT _acme-challenge.example.com @8.8.8.8

9.4 Nginx 502 Bad Gateway

问题: 访问域名返回502错误

解决方案:

  1. 检查后端服务是否运行: sudo ss -tlnp | grep :端口号
  2. 检查proxy_pass地址是否正确
  3. 查看Nginx错误日志: sudo tail -f /var/log/nginx/error.log
  4. 检查防火墙是否阻止了Nginx访问后端端口

9.5 证书路径错误

问题: Nginx启动失败,提示证书文件不存在

解决方案:

# 查找证书实际位置
sudo find /etc/letsencrypt -name "fullchain.pem"

# 查看所有证书
sudo certbot certificates

# 检查证书文件权限
sudo ls -l /etc/letsencrypt/live/example.com/

10. 证书续期和维护

10.1 检查证书状态

# 查看所有证书及到期时间
sudo certbot certificates

# 查看证书文件的有效期
sudo openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -noout -dates

10.2 自动续期(方案B和C)

证书会在到期前30天自动续期:

# 查看续期定时任务状态
sudo systemctl status certbot.timer

# 查看下次续期时间
sudo systemctl list-timers certbot.timer

# 手动测试续期
sudo certbot renew --dry-run

10.3 手动续期(方案A)

使用手动DNS验证的证书需要每90天手动续期:

# 重新申请证书
sudo certbot certonly --manual --preferred-challenges dns \
  -d "*.example.com" \
  -d "example.com"

操作步骤:

  1. 运行上述命令
  2. 按照提示在DNS控制台添加新的TXT记录
  3. 等待DNS生效:dig TXT _acme-challenge.example.com @8.8.8.8
  4. 在Certbot中按回车继续
  5. 重启Nginx:sudo systemctl restart nginx

💡 建议: 设置日历提醒,在到期前10天手动续期

10.4 续期后验证

# 验证证书文件的有效期
sudo openssl x509 -in /etc/letsencrypt/live/example.com/cert.pem -noout -dates

# 验证服务器返回的证书
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates

注意:

  • 证书更新后必须重启Nginx: sudo systemctl restart nginx
  • 浏览器可能缓存旧证书,建议使用无痕模式测试

10.5 配置备份

# 备份Nginx配置
sudo cp /etc/nginx/conf.d/example.conf ~/nginx-backup-$(date +%Y%m%d).conf

# 备份证书(迁移服务器时有用)
sudo cp -r /etc/letsencrypt ~/letsencrypt-backup-$(date +%Y%m%d)

10.6 修改配置的标准流程

# 1. 备份配置
sudo cp /etc/nginx/conf.d/example.conf /etc/nginx/conf.d/example.conf.backup

# 2. 编辑配置
sudo nano /etc/nginx/conf.d/example.conf

# 3. 测试语法
sudo nginx -t

# 4. 重新加载
sudo systemctl reload nginx

# 5. 检查状态
sudo systemctl status nginx

11. 安全建议

11.1 防火墙配置

# 安装UFW防火墙
sudo apt install ufw

# 允许SSH(避免锁死自己)
sudo ufw allow ssh

# 允许HTTP和HTTPS
sudo ufw allow 'Nginx Full'

# 启用防火墙
sudo ufw enable

# 查看防火墙状态
sudo ufw status

11.2 增强SSL安全性

在Nginx配置中添加额外的安全头:

# 在server块中添加
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;

11.3 定期维护

  1. 更新系统和软件包:

    sudo apt update
    sudo apt upgrade
    
  2. 监控证书到期时间:

    sudo certbot certificates
    
  3. 检查Nginx日志:

    sudo tail -f /var/log/nginx/error.log
    sudo tail -f /var/log/nginx/access.log
    
  4. 定期测试SSL配置:

11.4 其他建议

  • 使用强密码策略
  • 定期更新Nginx和Certbot
  • 监控服务器资源使用情况
  • 定期备份配置文件和证书
  • 考虑使用fail2ban防止暴力破解

12. 与Caddy对比

12.1 Caddy简介

Caddy是一个现代化的Web服务器,以自动HTTPS极简配置著称。如果您正在选择Web服务器,本章节帮助您了解两者的区别。

12.2 核心差异对比

特性 Nginx + Certbot Caddy
安装复杂度 需安装nginx和certbot 仅需安装caddy
HTTPS配置 手动申请和配置证书 ✅ 完全自动
证书续期 需配置systemd timer ✅ 完全自动
配置复杂度 较复杂(约70行) ✅ 极简(3行)
HTTP/2 需手动配置 ✅ 默认启用
HTTP/3 需额外编译 ✅ 内置支持
性能 ✅ 优秀 ✅ 优秀
生态系统 ✅ 成熟丰富 较新
社区资源 ✅ 非常丰富 逐渐增长
灵活性 ✅ 极高 中等
特殊模块 ✅ 丰富(lua等) 有限

12.3 配置复杂度对比

实现同样功能:HTTPS反向代理

Nginx配置(约70行):

# HTTP 重定向到 HTTPS
server {
    listen 80;
    server_name api.example.com;
    return 301 https://$server_name$request_uri;
}

# HTTPS配置
server {
    listen 443 ssl http2;
    server_name api.example.com;

    # SSL 证书配置
    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_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_redirect off;
    }
}

额外步骤:

# 1. 申请证书
sudo certbot certonly --nginx -d api.example.com

# 2. 配置自动续期
sudo systemctl enable certbot.timer
sudo systemctl start certbot.timer

# 3. 测试续期
sudo certbot renew --dry-run

Caddy配置(3行):

api.example.com {
    reverse_proxy http://127.0.0.1:8080
}

✅ Caddy自动处理:HTTP重定向、HTTPS证书申请、证书续期、HTTP/2、安全配置、请求头转发等

12.4 证书管理对比

Nginx + Certbot流程

# 初次申请
sudo apt install certbot python3-certbot-nginx
sudo certbot certonly --nginx -d example.com

# 配置nginx引用证书
sudo nano /etc/nginx/conf.d/example.conf
# 添加 ssl_certificate 和 ssl_certificate_key

# 启用自动续期
sudo systemctl enable certbot.timer

# 定期验证
sudo certbot renew --dry-run
sudo certbot certificates

# 续期后需要重新加载nginx
sudo systemctl reload nginx

Caddy流程

# 安装caddy
sudo apt install caddy

# 编辑配置文件
sudo nano /etc/caddy/Caddyfile
# 添加域名和配置

# 启动caddy
sudo systemctl start caddy

# 完成!证书自动申请和续期

12.5 适用场景建议

选择Nginx的理由

✅ 推荐使用Nginx:

  • 需要精细控制和高度自定义
  • 已有复杂的Nginx配置
  • 需要特定的Nginx模块(如lua-nginx-module)
  • 超大规模部署,需要极致性能调优
  • 团队已熟悉Nginx,不愿意学习新工具
  • 需要丰富的社区资源和第三方模块
  • 企业级应用,需要长期验证的稳定方案

典型场景:

  • 大型电商网站
  • 复杂的微服务网关
  • 需要高度定制的CDN节点
  • 使用OpenResty(Nginx + Lua)的应用

选择Caddy的理由

✅ 推荐使用Caddy:

  • 新项目,从零开始
  • 追求简单配置和快速部署
  • 厌倦手动管理SSL证书
  • 小型到中型网站
  • 个人项目或初创公司
  • 希望减少运维负担
  • 需要快速原型开发

典型场景:

  • 个人博客和小型网站
  • 创业公司MVP产品
  • 微服务API网关
  • 开发环境和测试环境
  • SaaS应用的简单代理层

12.6 迁移建议

从Nginx迁移到Caddy

如果您觉得Nginx的证书管理太繁琐,可以考虑迁移:

# 1. 安装Caddy
sudo apt install caddy

# 2. 转换配置
# Nginx的 proxy_pass → Caddy的 reverse_proxy
# Nginx的 root → Caddy的 root * 和 file_server

# 3. 停止Nginx
sudo systemctl stop nginx
sudo systemctl disable nginx

# 4. 启动Caddy
sudo systemctl start caddy

# 5. Caddy会自动申请新证书

注意事项:

  • Caddy会重新申请证书(不能直接复用Nginx的证书)
  • 复杂的Nginx配置可能无法直接转换
  • 需要测试所有功能是否正常

从Caddy迁移到Nginx

如果需要更高级的控制和定制:

# 1. 安装Nginx和Certbot
sudo apt install nginx certbot python3-certbot-nginx

# 2. 转换配置
# Caddy的 reverse_proxy → Nginx的 proxy_pass
# Caddy的 root * 和 file_server → Nginx的 root 和 location

# 3. 申请证书
sudo certbot certonly --nginx -d example.com

# 4. 停止Caddy
sudo systemctl stop caddy
sudo systemctl disable caddy

# 5. 启动Nginx
sudo systemctl start nginx

12.7 混合使用方案

某些场景下可以同时使用两者:

场景1:Nginx作为主服务器,Caddy处理特定服务

  • Nginx处理主站(端口443)
  • Caddy处理其他子域名(不同端口)
  • 使用不同的公网IP或端口映射

场景2:Caddy作为边缘代理,Nginx作为后端

# Caddy配置
api.example.com {
    reverse_proxy http://localhost:8080
}
# Nginx配置(监听8080)
server {
    listen 8080;
    server_name _;

    location / {
        # 实际应用处理
    }
}

12.8 性能对比

两者性能都非常优秀,在大多数场景下差异不明显:

测试项 Nginx Caddy
静态文件 ⚡ 极快 ⚡ 快
反向代理 ⚡ 极快 ⚡ 快
内存占用 ✅ 低 ✅ 中等
并发连接 ✅ 极高 ✅ 高

💡 结论: 对于99%的应用场景,性能差异可以忽略不计。选择应基于功能需求和运维便利性。

12.9 学习曲线对比

复杂度
  ↑
  │                    ╱
  │                  ╱ Nginx
  │                ╱
  │              ╱
  │            ╱
  │    Caddy ╱
  │        ╱
  │      ╱
  └──────────────────→ 功能深度
  • Caddy: 入门简单,但高级功能相对有限
  • Nginx: 入门门槛较高,但功能极其丰富

12.10 总结建议

您的情况 推荐方案
新项目,追求简单 ⭐ Caddy
小型网站,个人项目 ⭐ Caddy
已有Nginx配置 ⭐ Nginx
需要高度定制 ⭐ Nginx
厌倦证书管理 ⭐ Caddy
企业级大型应用 ⭐ Nginx
快速原型开发 ⭐ Caddy
需要特殊模块 ⭐ Nginx

参考Caddy文档: 如果您对Caddy感兴趣,可以查看本站的 Caddy自动HTTPS配置指南 获取完整的Caddy配置教程。


附录

A. 查看所有加载的Nginx配置

# 查看所有配置文件
sudo nginx -T

# 检查conf.d目录
ls -la /etc/nginx/conf.d/

B. 常用命令速查

# Certbot
sudo certbot certificates                    # 查看所有证书
sudo certbot renew                           # 手动续期
sudo certbot renew --dry-run                # 测试续期
sudo certbot delete --cert-name example.com # 删除证书

# Nginx
sudo nginx -t                                # 测试配置
sudo systemctl restart nginx                 # 重启
sudo systemctl reload nginx                  # 重新加载配置
sudo systemctl status nginx                  # 查看状态

# DNS
dig example.com                              # 查询A记录
dig TXT _acme-challenge.example.com         # 查询TXT记录
dig NS example.com                           # 查询Nameserver

# 端口和服务
sudo ss -tlnp | grep :80                    # 检查80端口
sudo ss -tlnp | grep :443                   # 检查443端口
sudo ss -tlnp | grep :8080                  # 检查后端端口

C. 故障排查流程

  1. 检查后端服务: sudo ss -tlnp | grep :端口号
  2. 检查Nginx状态: sudo systemctl status nginx
  3. 查看错误日志: sudo tail -f /var/log/nginx/error.log
  4. 测试配置语法: sudo nginx -t
  5. 验证DNS解析: dig 域名
  6. 验证证书: sudo certbot certificates

文档版本: v2.1 最后更新: 2025-11-07 适用版本: Ubuntu 20.04+, Nginx 1.18+, Certbot 1.21+