跳到主要内容
注册无需实名认证
安云主机 AnYun VPS

教程 · 建站与 Web

用 Caddy 自动申请证书:一段配置搞定 HTTPS

难度

入门

预计时长

15 分钟

步骤

6

最近修订

基准系统

Debian 12

要点

用 Caddy 自动申请证书:一段配置搞定 HTTPS

Caddy 会自动为 Caddyfile 里出现的域名申请并续期证书,一个静态站点只需要三行配置,反向代理只需要一行 reverse_proxy。代价是生态与中文资料量不如 Nginx,复杂重写规则的写法也完全不同;如果机器上已经有 Nginx 占着 80 与 443,两者不能同时监听。

前置条件

开始之前,先确认这些都具备

  • 一台已加固的服务器与 sudo 权限
  • 一个已解析到该服务器的域名(Caddy 需要它来自动签发证书)
  • 80 与 443 端口未被其他服务占用

操作步骤

6

  1. 步骤 01 / 06

    从官方 apt 仓库安装 #

    发行版自带的 Caddy 版本往往偏旧,官方仓库更新更及时。下面是官方文档给出的安装方式:写入签名密钥与源,再正常 apt install。

    Shell
    sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https curl
    
    curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' \
      | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
    
    curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' \
      | sudo tee /etc/apt/sources.list.d/caddy-stable.list
    
    sudo apt update && sudo apt install -y caddy
    caddy version
  2. 步骤 02 / 06

    确认 80 与 443 没有被占用 #

    Caddy 需要独占这两个端口才能完成自动签发。机器上已经有 Nginx 的话,先停掉它 —— 两个 Web 服务器抢同一个端口,后启动的那个会静默失败或反复重启。

    Shell
    sudo ss -tlnp | grep -E ':(80|443)\b'
    
    # 若被 Nginx 占用且确定不再使用
    sudo systemctl disable --now nginx
  3. 步骤 03 / 06

    写 Caddyfile #

    这就是全部配置:域名、根目录、开启文件服务,证书的申请与续期 Caddy 自己会办。encode 一行同时开启 zstd 与 gzip 压缩。

    Caddyfile
    # /etc/caddy/Caddyfile
    example.com, www.example.com {
        root * /var/www/example.com/html
        file_server
        encode zstd gzip
    
        header /assets/* Cache-Control "public, max-age=2592000, immutable"
    
        log {
            output file /var/log/caddy/example.com.log
        }
    }
  4. 步骤 04 / 06

    格式化、校验、重载 #

    caddy fmt 统一缩进,caddy validate 在重载前检查配置。Caddy 以 caddy 用户运行,站点目录必须对它可读,否则页面会是 403 而日志里只有一行权限错误。

    Shell
    sudo caddy fmt --overwrite /etc/caddy/Caddyfile
    sudo caddy validate --config /etc/caddy/Caddyfile
    
    sudo chown -R caddy:caddy /var/log/caddy
    sudo systemctl reload caddy
    
    curl -I https://example.com
    journalctl -u caddy -n 50 --no-pager
  5. 步骤 05 / 06

    反向代理只要一行 #

    把后端应用放在 127.0.0.1 上,Caddy 负责对外的 TLS 与转发。它默认会带上 X-Forwarded-For 与 X-Forwarded-Proto,WebSocket 也无需额外配置 —— 这是相对 Nginx 最省心的地方。

    Caddyfile
    api.example.com {
        reverse_proxy 127.0.0.1:3000
    }
  6. 步骤 06 / 06

    本地或内网测试用 tls internal #

    公网证书需要一个能被验证的域名。仅在内网或本地调试时,用 tls internal 让 Caddy 签一张本地信任的证书,避免为了测试去污染公网签发的频率配额。

    Caddyfile
    test.local {
        tls internal
        respond "ok"
    }

常见错误

这一步最容易踩的坑

下面每一条都对应一个真实会发生的故障。先读完再动手,比出问题之后再回来查要省时间。

  • 80 或 443 被 Nginx 占着。Caddy 会起不来,而错误信息藏在 journalctl 里,界面上什么都看不到。
  • 用 IP 直接访问期待自动 HTTPS。自动签发需要一个已解析的域名,纯 IP 场景请用 tls internal 或自备证书。
  • 站点目录 caddy 用户读不到,表现为 403。它不是以 root 运行的,属主别只想着 www-data。
  • 改完 Caddyfile 忘了 reload。Caddy 不会自动读取文件变化。
  • 把 Caddy 和 Nginx 混着用(一个管证书一个管站点)。可以做,但配置的复杂度立刻超过单用其中之一,除非有明确理由,否则别这么干。
  • 日志目录属主不对导致启动失败。用 file 输出日志时记得 chown。

这篇教程的边界

  • 命令以 Debian 12 为准。Ubuntu 与 Rocky Linux 的差异只在正文明确标注之处,未标注的部分请以你所用发行版的官方文档为准。
  • 示例中的 IP 来自文档保留段 203.0.113.0/24,域名为 example.com,端口为示意值。复制后必须替换成自己的值, 原样执行不会有任何效果。
  • 教程不能替代备份。任何会改动数据或线上流量的步骤,执行前先确认有一份验证过能恢复的备份。
  • 本站不提供任何用于绕过网络审查的配置或说明,这篇也不例外。

发现命令过时或有误,请发邮件到 [email protected]。 指出错误的邮件比沉默的旧文档有价值得多。

联系 工单
扫码
手机访问

扫码在手机上打开