DevToolBox免费
博客

Caddy Server 完全指南 2026:自动 HTTPS、反向代理与现代 Web 服务器

28 分钟阅读作者 DevToolBox Team

TL;DR

Caddy 是一个基于 Go 的现代 Web 服务器,通过 Let's Encrypt 提供零配置自动 HTTPS。它是 Nginx 和 Apache 的替代品,配置语法(Caddyfile)极其简单。Caddy 自动处理 TLS 证书的获取、续期和 OCSP 装订。支持反向代理、负载均衡、静态文件服务、HTTP/3 和通过管理 API 进行动态配置。在 2026 年的大多数 Web 服务场景中,Caddy 以生产级可靠性提供了最佳开发者体验。

Key Takeaways

  • Caddy 自动从 Let's Encrypt 获取和续期 HTTPS 证书 — 无需 certbot、无需 cron、无需手动续期
  • Caddyfile 语法比 Nginx/Apache 配置简单得多:基本反向代理只需 3 行
  • Caddy 原生支持 HTTP/3 (QUIC)、按需 TLS、通配符证书和 ACME 协议
  • Caddy 管理 API 允许不重启或重载即可实时更改配置
  • Caddy 非常适合作为 Docker 反向代理,为容器化微服务提供自动 HTTPS
  • 从 Nginx 迁移到 Caddy 通常可减少 60-80% 的配置复杂度

Caddy 是一个用 Go 编写的开源 Web 服务器,作为 Nginx 和 Apache 的现代替代方案获得了广泛关注。其最突出的特性是自动 HTTPS:Caddy 无需任何配置即可从 Let's Encrypt(或 ZeroSSL)获取和续期 TLS 证书。在 2026 年,Caddy 为数百万站点提供服务,已成为想要生产级 Web 服务而不需要复杂传统服务器配置的开发者的首选。本指南涵盖从基础设置到高级生产部署模式的所有内容。

什么是 Caddy 以及为什么它很重要

Caddy 是一个强大的、可扩展的 Web 服务器平台。它由 Matt Holt 于 2015 年创建,已发展成为成熟的生产级服务器。Caddy v2 是一次完全重写,引入了模块化架构、JSON 配置系统和 Caddyfile 适配器。

Caddy 的独特之处在于其安全默认的理念。HTTPS 默认自动开启。HTTP 请求自动重定向到 HTTPS。OCSP 装订已启用。强制使用现代 TLS 版本。这意味着零配置的全新 Caddy 安装已经比大多数手动配置的 Nginx 或 Apache 更安全。

  • 通过 Let's Encrypt 和 ZeroSSL 零配置自动 HTTPS
  • 用 Go 编写 — 单一静态二进制文件,无依赖,跨平台
  • Caddyfile:比 Nginx 或 Apache 简单得多的人类可读配置
  • 默认启用原生 HTTP/3 (QUIC) 支持
  • 管理 API 实现无停机实时配置更改
  • 可扩展的模块系统 — 无需 fork 即可添加功能
  • 优雅重载、自动证书管理和 OCSP 装订

Caddy vs Nginx vs Apache vs Traefik

每个 Web 服务器都有适合不同用例的优势。此对比帮助您为项目选择合适的服务器。

特性CaddyNginxApacheTraefik
自动 HTTPS内置(零配置)手动(certbot)手动(certbot)内置(需配置)
配置语法Caddyfile(简单)nginx.conf(复杂)httpd.conf + .htaccessYAML/TOML/标签
原始性能非常好优秀良好良好
内存使用低 (~20MB)非常低 (~5MB)高 (~50-200MB)低 (~30MB)
HTTP/3 支持原生(默认开启)实验性不支持实验性
Docker 集成良好手动配置手动配置优秀(原生)
插件系统Go 模块C 模块(编译)动态模块Go 插件
学习曲线简单中等中等-困难中等
编写语言GoCCGo
许可证Apache 2.0BSD 2-ClauseApache 2.0MIT

安装

Caddy 以单一静态二进制文件分发,无需运行时依赖。

包管理器

# Debian / Ubuntu
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 caddy

# Fedora / RHEL
dnf copr enable @caddy/caddy && dnf install caddy

# macOS
brew install caddy

# Windows
choco install caddy

Docker

# Pull official Caddy image
docker pull caddy:latest

# Run with Caddyfile
docker run -d --name caddy \
  -p 80:80 -p 443:443 -p 443:443/udp \
  -v $PWD/Caddyfile:/etc/caddy/Caddyfile \
  -v caddy_data:/data \
  -v caddy_config:/config \
  caddy:latest

直接下载二进制文件

# Download from GitHub releases
curl -OL https://github.com/caddyserver/caddy/releases/latest/download/caddy_2.9.1_linux_amd64.tar.gz
tar xzf caddy_2.9.1_linux_amd64.tar.gz
sudo mv caddy /usr/bin/caddy
sudo chmod +x /usr/bin/caddy

# Verify installation
caddy version

使用 xcaddy 从源码构建

# Install xcaddy (Caddy build tool)
go install github.com/caddyserver/xcaddy/cmd/xcaddy@latest

# Build Caddy with custom plugins
xcaddy build \
  --with github.com/caddy-dns/cloudflare \
  --with github.com/mholt/caddy-ratelimit \
  --with github.com/caddyserver/transform-encoder

Caddyfile 基础

Caddyfile 是 Caddy 的人类友好配置格式,即使对于复杂设置也易于读写。

自动 HTTPS(默认行为)

在 Caddyfile 中指定域名时,Caddy 自动从 Let's Encrypt 获取 TLS 证书、将 HTTP 重定向到 HTTPS 并启用 OCSP 装订。无需额外配置。

# Minimal Caddyfile — automatic HTTPS!
# Just specify your domain and Caddy does the rest
example.com {
    respond "Hello, world!"
}

# What Caddy does automatically:
# 1. Obtains TLS certificate from Let's Encrypt
# 2. Redirects http://example.com → https://example.com
# 3. Enables OCSP stapling
# 4. Enforces modern TLS (1.2+)
# 5. Renews certificate before expiry

静态文件服务器

# Serve static files with compression and caching
example.com {
    root * /var/www/html
    encode gzip zstd
    file_server

    # Cache static assets for 1 year
    @static path *.css *.js *.png *.jpg *.svg *.woff2
    header @static Cache-Control "public, max-age=31536000, immutable"

    # Cache HTML for 1 hour
    @html path *.html
    header @html Cache-Control "public, max-age=3600"
}

重定向

# Redirect www to non-www
www.example.com {
    redir https://example.com{uri} permanent
}

# Redirect old paths
example.com {
    redir /old-page /new-page permanent
    redir /blog/old-slug /blog/new-slug 301
}

反向代理配置

Caddy 是优秀的反向代理,支持单后端、负载均衡、健康检查、WebSocket 代理和请求头操作。

单后端

# Simple reverse proxy — 3 lines!
app.example.com {
    reverse_proxy localhost:3000
}

# With header manipulation
api.example.com {
    reverse_proxy localhost:8080 {
        header_up X-Real-IP {remote_host}
        header_up X-Forwarded-Proto {scheme}
        header_down -Server
    }
}

负载均衡

# Load balancing across multiple backends
app.example.com {
    reverse_proxy {
        to localhost:3001
        to localhost:3002
        to localhost:3003

        lb_policy round_robin
        # Other policies: random, first, ip_hash,
        # uri_hash, least_conn, header
    }
}

健康检查

# Active health checks
app.example.com {
    reverse_proxy {
        to localhost:3001
        to localhost:3002

        health_uri /health
        health_interval 10s
        health_timeout 5s
        health_status 200

        # Passive health checks (circuit breaker)
        fail_duration 30s
        max_fails 3
        unhealthy_latency 500ms
    }
}

WebSocket 代理

# WebSocket proxying — Caddy handles upgrade automatically
ws.example.com {
    reverse_proxy localhost:8080
    # That's it! Caddy detects WebSocket upgrades
    # and handles them transparently.
}

# With path-based routing
example.com {
    reverse_proxy /ws/* localhost:8080
    reverse_proxy /api/* localhost:3000
    file_server
}

Nginx 等效对比

以下是相同反向代理配置在 Caddy 和 Nginx 中的对比。

# CADDY — Reverse proxy with HTTPS (3 lines)
app.example.com {
    reverse_proxy localhost:3000
}

# NGINX equivalent (~25 lines + certbot + cron)
# server { listen 80; server_name app.example.com;
#   return 301 https://$server_name$request_uri; }
# server { listen 443 ssl http2;
#   server_name app.example.com;
#   ssl_certificate /etc/letsencrypt/live/.../fullchain.pem;
#   ssl_certificate_key /etc/letsencrypt/live/.../privkey.pem;
#   location / {
#     proxy_pass http://localhost:3000;
#     proxy_set_header Host $host;
#     proxy_set_header X-Real-IP $remote_addr;
#     proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
#   }
# } + certbot setup + renewal cron job

自动 HTTPS 深入解析

Caddy 的自动 HTTPS 是其最引人注目的特性,它自动处理整个 TLS 生命周期。

  • 使用 ACME 协议从 Let's Encrypt(或 ZeroSSL)获取证书
  • 证书到期前自动续期(默认:到期前 30 天)
  • 自动将 HTTP 重定向到 HTTPS
  • 启用 OCSP 装订以加快 TLS 握手
  • 支持 ACME DNS 挑战以获取通配符证书
  • 按需 TLS:在 TLS 握手时获取证书,适用于动态域名

通配符证书

Caddy 通过 DNS 挑战支持通配符证书。您需要为您的域名注册商安装 DNS 提供商插件。

# Wildcard certificate with Cloudflare DNS
# Build Caddy with: xcaddy build --with github.com/caddy-dns/cloudflare

*.example.com {
    tls {
        dns cloudflare {env.CLOUDFLARE_API_TOKEN}
    }

    @app host app.example.com
    handle @app {
        reverse_proxy localhost:3000
    }

    @api host api.example.com
    handle @api {
        reverse_proxy localhost:8080
    }

    handle {
        respond "Unknown subdomain" 404
    }
}

按需 TLS

按需 TLS 在 TLS 握手期间获取证书。这对于客户域名事先未知的 SaaS 平台很有用。

# On-demand TLS for SaaS custom domains
{
    on_demand_tls {
        ask http://localhost:5555/check-domain
        interval 5m
        burst 10
    }
}

https:// {
    tls {
        on_demand
    }
    reverse_proxy localhost:3000
}

Docker 部署

Caddy 在 Docker 环境中表现出色。以下是常见的部署模式。

基本 Docker 设置

# Dockerfile for custom Caddy
FROM caddy:2-builder AS builder
RUN xcaddy build \
    --with github.com/caddy-dns/cloudflare \
    --with github.com/mholt/caddy-ratelimit

FROM caddy:2
COPY --from=builder /usr/bin/caddy /usr/bin/caddy
COPY Caddyfile /etc/caddy/Caddyfile

Docker Compose 多服务

# docker-compose.yml — Multi-service with Caddy
services:
  caddy:
    image: caddy:latest
    restart: unless-stopped
    ports: ["80:80", "443:443", "443:443/udp"]
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - caddy_data:/data
    networks: [web]
  app:
    build: ./app
    expose: ["3000"]
    networks: [web]
  api:
    build: ./api
    expose: ["8080"]
    networks: [web, backend]
  db:
    image: postgres:16-alpine
    volumes: [pgdata:/var/lib/postgresql/data]
    networks: [backend]
volumes: { caddy_data: {}, pgdata: {} }
networks: { web: {}, backend: {} }

# Caddyfile for the compose setup
app.example.com { reverse_proxy app:3000 }
api.example.com { reverse_proxy api:8080 }

PHP 和 WordPress 与 Caddy

Caddy 通过 php_fastcgi 指令提供一流的 PHP 支持,处理路径拆分、索引文件解析和 FastCGI 通信。

基本 PHP 设置

# Basic PHP with Caddy
example.com {
    root * /var/www/html
    encode gzip
    php_fastcgi unix//run/php/php8.3-fpm.sock
    file_server
}

WordPress 配置

# WordPress with Caddy — complete config
example.com {
    root * /var/www/wordpress
    encode gzip

    # PHP processing
    php_fastcgi unix//run/php/php8.3-fpm.sock

    # Static file serving
    file_server

    # Block access to sensitive files
    @blocked path /xmlrpc.php /wp-config.php
    respond @blocked 403

    # Cache static assets
    @static path *.css *.js *.png *.jpg *.gif *.ico *.svg *.woff2
    header @static Cache-Control "public, max-age=31536000"

    # Security headers
    header {
        X-Content-Type-Options nosniff
        X-Frame-Options SAMEORIGIN
        Referrer-Policy strict-origin-when-cross-origin
        -Server
    }
}

SPA 托管(React、Vue、Next.js)

Caddy 通过 try_files 指令优雅地处理单页应用的客户端路由回退。

# React / Vue SPA hosting
app.example.com {
    root * /var/www/app/dist
    encode gzip zstd

    # SPA client-side routing fallback
    try_files {path} /index.html
    file_server

    # Proxy API requests to backend
    reverse_proxy /api/* localhost:8080

    # Cache static assets aggressively
    @static path *.js *.css *.png *.svg *.woff2
    header @static Cache-Control "public, max-age=31536000, immutable"
}

# Next.js / Nuxt.js (SSR mode)
ssr.example.com {
    reverse_proxy localhost:3000
}

Caddy 作为 API 网关

Caddy 可以作为 API 网关,根据路径前缀将请求路由到不同的后端服务,并支持速率限制和 CORS 头。

# Caddy as API Gateway
api.example.com {
    # CORS headers
    header Access-Control-Allow-Origin "https://app.example.com"
    header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
    header Access-Control-Allow-Headers "Authorization, Content-Type"

    # Route to different microservices
    reverse_proxy /users/* user-service:3001
    reverse_proxy /orders/* order-service:3002
    reverse_proxy /payments/* payment-service:3003
    reverse_proxy /notifications/* notification-service:3004

    # Health check endpoint
    respond /health 200
}

HTTP/3 和 QUIC 支持

Caddy 原生支持 HTTP/3 (QUIC) 并默认启用。HTTP/3 使用 UDP 而非 TCP,提供更快的连接建立、在有损网络上更好的性能,并消除队头阻塞。无需额外配置。

# HTTP/3 is enabled by default in Caddy!
# Make sure to expose UDP port 443:
# docker run -p 443:443/udp ...

# To explicitly disable HTTP/3:
{
    servers {
        protocols h1 h2
        # Omitting h3 disables QUIC
    }
}

# Response headers will include:
# Alt-Svc: h3=":443"; ma=2592000

Caddy JSON 配置 vs Caddyfile

Caddy 有两个配置接口:Caddyfile(人类友好)和 JSON(机器友好)。Caddyfile 实际上是一个转换为 JSON 的适配器。JSON 配置提供对每个 Caddy 功能的完全控制。

# Convert Caddyfile to JSON (see what Caddy generates internally)
caddy adapt --config Caddyfile --pretty

# JSON config gives full control — ideal for programmatic configs
# { "apps": { "http": { "servers": { "srv0": {
#   "listen": [":443"],
#   "routes": [{ "match": [{"host": ["app.example.com"]}],
#     "handle": [{"handler": "reverse_proxy",
#       "upstreams": [{"dial": "localhost:3000"}]}] }]
# }}}}}

Caddy 管理 API

Caddy 在 localhost:2019 上暴露 REST API 用于实时配置管理。可以加载、修改和检查配置而无需重启服务器。

# Caddy Admin API (localhost:2019)

# Load new JSON config
curl localhost:2019/load -H "Content-Type: application/json" -d @caddy.json

# Load Caddyfile via adapter
curl localhost:2019/load -H "Content-Type: text/caddyfile" --data-binary @Caddyfile

# Get current config
curl localhost:2019/config/

# Graceful reload from CLI
caddy reload --config /etc/caddy/Caddyfile

速率限制和安全头

Caddy 提供内置安全功能,并可通过速率限制模块扩展。

# Security headers and rate limiting
example.com {
    header {
        Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
        X-Content-Type-Options nosniff
        X-Frame-Options DENY
        Referrer-Policy strict-origin-when-cross-origin
        Permissions-Policy "camera=(), microphone=(), geolocation=()"
        -Server
    }

    # Basic authentication
    basicauth /admin/* {
        admin $2a$14$hashed_password_here
    }

    # IP allowlist
    @blocked not remote_ip 10.0.0.0/8
    respond @blocked /internal/* 403

    reverse_proxy localhost:3000
}

日志和指标

Caddy 默认生成结构化 JSON 日志,易于用 jq、Loki 或 Elasticsearch 解析。还通过模块支持 Prometheus 指标。

# Structured JSON logging with rotation
example.com {
    log {
        output file /var/log/caddy/access.log {
            roll_size 100MiB
            roll_keep 10
        }
        format json
    }
    reverse_proxy localhost:3000
}
# Prometheus metrics: built-in at :2019/metrics

性能调优

Caddy 开箱即用性能良好,但可以针对高流量场景进行调优。

  • 使用 encode gzip zstd 启用静态文件压缩
  • 使用带 precompressed 的 file_server 提供预压缩文件
  • 通过 GOMAXPROCS 环境变量调整工作线程数
  • 启用 HTTP/3 以在移动和有损网络上获得更好性能
  • 使用 header 缓存指令处理静态资源
  • 适当配置连接保活超时
# Performance-optimized Caddyfile
example.com {
    root * /var/www/html

    # Enable compression (gzip + zstd)
    encode zstd gzip

    # Serve pre-compressed files if available
    file_server {
        precompressed zstd gzip br
    }

    # Aggressive caching for static assets
    @immutable path *.js *.css *.woff2 *.png *.jpg *.svg
    header @immutable {
        Cache-Control "public, max-age=31536000, immutable"
        Vary Accept-Encoding
    }

    # Keep-alive settings
    # (Caddy defaults are good for most cases)
}

Caddy 模块和插件

Caddy 拥有丰富的插件生态。插件是扩展 Caddy 功能的 Go 模块。使用 xcaddy 构建包含所需插件的自定义 Caddy 二进制文件。

# Popular Caddy modules (install with xcaddy)
xcaddy build \
  --with github.com/caddy-dns/cloudflare \   # DNS challenge (Cloudflare)
  --with github.com/caddy-dns/route53 \      # DNS challenge (AWS)
  --with github.com/mholt/caddy-ratelimit \  # Rate limiting
  --with github.com/caddyserver/cache-handler # HTTP caching

# Prometheus metrics — built-in since v2.7 (no plugin needed)
# List installed modules
caddy list-modules

从 Nginx 迁移到 Caddy

从 Nginx 迁移到 Caddy 通常会大大简化配置。以下是常见的 Nginx 模式及其 Caddy 等效配置。

# Migration cheat sheet: Nginx → Caddy
#
# server { listen 443 ssl; server_name X; }  →  X { }
# location / { proxy_pass http://...; }      →  reverse_proxy localhost:3000
# location ~ \.php$ { fastcgi_pass ...; }    →  php_fastcgi unix//run/php/php8.3-fpm.sock
# try_files $uri $uri/ /index.html           →  try_files {path} /index.html
# rewrite ^/old$ /new permanent               →  redir /old /new permanent
# add_header X-Frame-Options DENY             →  header X-Frame-Options DENY
# ssl_certificate + certbot + cron            →  (automatic — nothing needed)
# gzip on; gzip_types ...                     →  encode gzip zstd

生产部署最佳实践

  • 将 Caddy 作为 systemd 服务运行以实现自动重启和日志
  • 人工管理配置用 Caddyfile,自动化用 JSON
  • 将 Caddy 数据目录 (/data) 存储在持久存储上以保存证书
  • 设置访问和错误日志轮转
  • 使用 Prometheus 指标监控证书到期
  • 管理 API 端点仅在 localhost 上使用(默认)
  • 保持 Caddy 更新 — 安全补丁定期发布
  • 应用前用 caddy validate 测试配置更改
# Install as systemd service (package managers do this automatically)
sudo systemctl enable --now caddy

# Validate config before applying
caddy validate --config /etc/caddy/Caddyfile

# Graceful reload (no downtime)
sudo systemctl reload caddy

# Check status and logs
sudo systemctl status caddy
journalctl -u caddy --no-pager -f

常见问题和故障排除

  • 证书未获取:检查端口 80 和 443 是否可从互联网访问。Caddy 需要这些端口进行 ACME HTTP 挑战。
  • 端口 80/443 权限被拒绝:在 Linux 上运行 setcap 或使用 systemd socket 激活。
  • 证书过多:Let's Encrypt 有速率限制。测试时使用 staging 环境。
  • 配置不重载:使用 caddy reload 而不是重启。先检查 caddy validate。
  • 反向代理 502 错误:验证后端是否运行并可访问。
  • WebSocket 不工作:Caddy 自动处理 WebSocket 升级。检查后端是否需要特定头。
  • 内存使用高:检查是否有过度日志记录。内存使用随活动连接和证书数量而增长。
  • 证书签发慢:DNS 传播对于 DNS 挑战可能较慢。尽可能使用 HTTP 挑战。

常见问题解答

Caddy 是否可以用于生产环境?

是的。Caddy v2 自 2020 年起已可用于生产,被数千家公司使用。它处理自动 HTTPS、优雅重载,并经过了广泛的实战测试。

Caddy 与 Nginx 的性能对比如何?

对于大多数实际工作负载,Caddy 和 Nginx 性能相当。Nginx 在原始静态文件吞吐量上略有优势,但差异通常小于 10%,与后端处理时间相比可以忽略。

Caddy 能替代 Nginx 作为反向代理吗?

完全可以。Caddy 作为反向代理表现出色,支持自动 HTTPS、负载均衡、健康检查和 WebSocket。配置比 Nginx 简单得多。

Caddy 支持通配符证书吗?

支持。Caddy 通过 ACME DNS 挑战支持通配符证书。需要为您的注册商安装 DNS 提供商插件。

Caddy 如何处理证书续期?

Caddy 在证书到期前 30 天自动续期。如果续期失败,会以指数退避重试并记录警告。

可以将 Caddy 与 Docker 和 Kubernetes 一起使用吗?

可以。Caddy 有官方 Docker 镜像,在容器环境中表现良好。Docker Compose 模式中 Caddy 作为多服务入口点非常流行。

Caddy 是免费开源的吗?

是的。Caddy 使用 Apache 2.0 许可证,完全免费使用,包括商业用途。没有付费层或企业版。

如何从 Nginx 迁移到 Caddy?

首先将 nginx.conf 翻译为 Caddyfile。大多数 Nginx 指令都有直接的 Caddy 等效项但语法更简单。移除所有 SSL/TLS 配置。用 caddy validate 测试后切换 DNS。

𝕏 Twitterin LinkedIn
这篇文章有帮助吗?

保持更新

获取每周开发技巧和新工具通知。

无垃圾邮件,随时退订。

试试这些相关工具

{ }JSON Formatter🔄cURL to Code Converter

相关文章

Nginx 配置指南:从基础设置到生产部署

Nginx 完整配置指南。学习 server block、反向代理、SSL/TLS、负载均衡、缓存和安全头部配置。

Docker Compose 教程:从基础到生产就绪的技术栈

完整的 Docker Compose 教程:docker-compose.yml 语法、服务、网络、卷、环境变量、健康检查,以及 Node.js、Python、WordPress 的实际案例。

Coolify 完全指南 2026:自托管 PaaS — 不用 Vercel/Heroku 也能部署应用

掌握 Coolify 开源自托管平台:安装、应用部署、数据库管理、自定义域名、SSL、GitHub 集成、多服务器管理和生产最佳实践。