Caddy 是一款用 Go 语言编写的现代 Web 服务器,以配置极其简单和自动化 HTTPS 为核心特色。与 Nginx 或 Apache 相比,Caddy 最大的优势在于默认开启 HTTPS,它会自动从 Let’s Encrypt 申请并续签 SSL/TLS 证书,让网站一键拥有“小绿锁”。
一、安装与基本管理
1.1 各平台安装方式
方式一:使用 APT 包管理器(推荐 Ubuntu/Debian)
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
方式二:使用 YUM/DNF 包管理器(推荐 CentOS/RHEL)
sudo yum install yum-plugin-copr
sudo yum copr enable @caddy/caddy
sudo yum install caddy
sudo dnf install 'dnf-command(copr)'
sudo dnf copr enable @caddy/caddy
sudo dnf install caddy
方式三:官方一键安装脚本(通用 Linux)
curl -fsSL https://get.caddyserver.com | bash -s personal
方式四:macOS(使用 Homebrew)
brew install caddy
方式五:Windows
- 访问 https://caddyserver.com/download 选择 Windows 版本下载
- 解压到
C:\Caddy 目录 - 在命令行中运行
caddy run(推荐新建一个配置文件 Caddyfile 放在同目录下)
1.2 服务管理命令(systemd)
sudo systemctl start caddy
sudo systemctl stop caddy
sudo systemctl restart caddy
sudo systemctl reload caddy
sudo systemctl status caddy
sudo systemctl enable caddy
sudo journalctl -u caddy -f
1.3 手动运行(开发测试)
caddy run
caddy run --config Caddyfile
caddy start
caddy stop
二、核心概念
2.1 配置文件结构(Caddyfile)
Caddyfile 是 Caddy 的默认配置文件,语法非常简洁,没有花括号和分号,采用类似缩进的层级结构。
典型的目录结构(Debian/Ubuntu):
/etc/caddy/
├── Caddyfile # 主配置文件
├── sites/ # 站点配置目录(可单独存放多个站点配置)
│ ├── example.conf
│ └── api.conf
├── data/ # 证书和持久化数据存储目录
└── logs/ # 日志目录
2.2 基本配置示例
# 最简单的配置:监听 80 端口,提供静态文件服务
localhost:8080 {
root * /var/www/html
file_server
}
# 带 HTTPS 的配置(自动申请证书)
example.com {
root * /var/www/example
file_server
}
# 反向代理配置
api.example.com {
reverse_proxy localhost:3000
}
2.3 核心指令
| 指令 | 说明 | 示例 |
|---|
root | 设置网站根目录 | root * /var/www/html |
file_server | 启用静态文件服务 | file_server |
reverse_proxy | 反向代理到后端服务 | reverse_proxy localhost:3000 |
tls | 自定义 TLS/SSL 配置 | tls /path/to/cert.pem /path/to/key.pem |
redir | URL 重定向 | redir /old /new 301 |
rewrite | 内部 URL 重写 | rewrite /api/* /index.php?{query} |
header | 设置响应头 | header Cache-Control max-age=31536000 |
log | 配置访问日志 | log /var/log/caddy/access.log |
注意:root 指令中的 * 表示匹配所有请求路径,这是 Caddy 的推荐写法,明确指定该站点块处理的路径范围。
三、静态文件服务器
3.1 最简单的静态站点
example.com {
root * /var/www/example
file_server
}
3.2 自定义首页文件
example.com {
root * /var/www/example
file_server {
index index.html index.htm default.html
}
}
3.3 启用目录浏览
example.com {
root * /var/www/files
file_server browse
}
3.4 隐藏特定文件
example.com {
root * /var/www/example
file_server {
hide .git .env *.conf
}
}
四、反向代理配置
4.1 基本反向代理
反向代理是 Caddy 最常用的功能之一,可以将请求转发给后端服务,同时自动处理 HTTPS。
api.example.com {
reverse_proxy localhost:3000
}
4.2 带请求头传递
api.example.com {
reverse_proxy localhost:3000 {
header_up Host {host}
header_up X-Real-IP {remote_host}
header_up X-Forwarded-For {remote_host}
header_up X-Forwarded-Proto {scheme}
}
}
4.3 负载均衡
api.example.com {
reverse_proxy localhost:3000 localhost:3001 localhost:3002 {
lb_policy round_robin
health_uri /health
health_interval 30s
}
}
4.4 负载均衡算法
| 算法 | 说明 |
|---|
round_robin | 轮询分配(默认) |
least_conn | 分配给连接数最少的后端 |
random | 随机选择 |
first | 选择第一个可用后端 |
ip_hash | 根据客户端 IP 哈希分配(会话保持) |
4.5 后端健康检查
api.example.com {
reverse_proxy localhost:3000 localhost:3001 {
health_uri /health
health_interval 30s
health_timeout 5s
health_port 8080
}
}
4.6 WebSocket 代理
ws.example.com {
reverse_proxy localhost:3000 {
header_up Upgrade {http.request.header.Upgrade}
header_up Connection {http.request.header.Connection}
}
}
4.7 代理 Node.js 应用
node.example.com {
reverse_proxy localhost:3000
}
4.8 代理 Python 应用(Gunicorn)
python.example.com {
reverse_proxy localhost:8000
}
4.9 代理 PHP-FPM
php.example.com {
root * /var/www/php-app
php_fastcgi localhost:9000
file_server
}
五、HTTPS 与 SSL/TLS 配置
5.1 自动 HTTPS(默认开启)
Caddy 默认自动为所有域名申请 HTTPS 证书,无需任何额外配置。
example.com {
root * /var/www/example
file_server
}
5.2 自定义证书
example.com {
tls /etc/ssl/example.crt /etc/ssl/example.key
root * /var/www/example
file_server
}
5.3 使用内部证书(开发环境)
example.com {
tls internal
root * /var/www/example
file_server
}
5.4 禁用 HTTPS(仅开发测试)
example.com {
tls internal
# 或使用 http 前缀
}
# 或监听 HTTP 端口
example.com:80 {
root * /var/www/example
file_server
}
5.5 ACME 配置(Let’s Encrypt)
{
# 使用 Let's Encrypt 的 ACME 服务器(默认)
acme_ca https://acme-v02.api.letsencrypt.org/directory
# 使用测试环境(避免速率限制)
# acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
# 设置邮箱(用于证书过期通知)
email admin@example.com
}
example.com {
root * /var/www/example
file_server
}
5.6 HTTP 自动跳转 HTTPS
Caddy 默认会自动将 HTTP 请求重定向到 HTTPS:
example.com {
root * /var/www/example
file_server
}
# 手动配置 HTTP 跳转
http://example.com {
redir https://{host}{uri} 301
}
六、性能优化
6.1 Gzip 压缩
example.com {
encode gzip zstd
root * /var/www/example
file_server
}
6.2 静态文件缓存
example.com {
root * /var/www/example
header Cache-Control "public, immutable"
# 对不同文件类型设置不同缓存时间
@static {
file
path *.css *.js *.png *.jpg *.jpeg *.gif *.ico *.svg *.webp
}
header @static Cache-Control "public, max-age=31536000, immutable"
file_server
}
6.3 启用 ETag
example.com {
root * /var/www/example
header ETag {file.ETag}
file_server
}
6.4 限制请求大小
example.com {
# 限制请求体大小为 10MB
request_body {
max_size 10MB
}
reverse_proxy localhost:3000
}
6.5 速率限制
example.com {
rate_limit {
zone dynamic {
key {remote_host}
events 100
window 1m
}
}
reverse_proxy localhost:3000
}
七、日志管理
7.1 访问日志配置
example.com {
log {
output file /var/log/caddy/access.log
format json
}
root * /var/www/example
file_server
}
7.2 自定义日志格式
example.com {
log {
output file /var/log/caddy/access.log
format filter {
wrap console
fields {
common_log {common_log}
duration {duration}
request {request}
status {status}
size {size}
}
}
}
root * /var/www/example
file_server
}
7.3 特定路径不记录日志
example.com {
log {
exclude /health /favicon.ico
output file /var/log/caddy/access.log
}
root * /var/www/example
file_server
}
7.4 错误日志
{
log {
output file /var/log/caddy/error.log
level ERROR
}
}
example.com {
root * /var/www/example
file_server
}
八、安全配置
8.1 安全头部
example.com {
header {
# 防止 XSS 攻击
X-XSS-Protection "1; mode=block"
# 防止 MIME 类型嗅探
X-Content-Type-Options "nosniff"
# 防止点击劫持
X-Frame-Options "SAMEORIGIN"
# HSTS(强制 HTTPS)
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
# 引用来源策略
Referrer-Policy "strict-origin-when-cross-origin"
# 跨域资源分享
Access-Control-Allow-Origin "*"
}
root * /var/www/example
file_server
}
8.2 IP 访问限制
example.com {
@allowed {
remote_ip 192.168.1.0/24 10.0.0.1
}
handle @allowed {
reverse_proxy localhost:3000
}
handle {
abort
}
root * /var/www/example
file_server
}
8.3 密码保护(基本认证)
example.com {
basicauth {
admin $2a$14$5cVnQRncx2V8.0NqVfK3YeGfV8zUkFzSGz5HhXQZxZxZxZxZxZxZx
}
root * /var/www/private
file_server
}
生成密码哈希:
caddy hash-password --plaintext "your-password"
8.4 限制请求方法
example.com {
@post {
method POST
}
handle @post {
reverse_proxy localhost:3000
}
handle {
abort
}
root * /var/www/example
file_server
}
8.5 防止目录遍历
example.com {
file_server {
hide .git .env .htaccess *.sql *.log
}
}
九、URL 处理
9.1 重定向(Redir)
example.com {
# 永久重定向
redir /old-page /new-page 301
# 临时重定向
redir /temporary /new-page 302
# 正则匹配重定向
redir /products/(.*) /shop/$1 301
# 路径前缀重定向
redir /blog/* /news/{uri} 301
}
9.2 重写(Rewrite)
example.com {
# 将 /api 路径重写到 /v2/api
rewrite /api/* /v2/api{path}
# SPA 路由处理(所有请求返回 index.html)
rewrite * /index.html
# 条件重写
@blog {
path /blog/*
}
rewrite @blog /posts/{path}
root * /var/www/example
file_server
}
9.3 路径操作
example.com {
# 添加路径前缀
handle_path /api/* {
rewrite * /v2{path}
reverse_proxy localhost:3000
}
# 移除路径前缀
handle_path /old/* {
rewrite * {path}
reverse_proxy localhost:3000
}
}
9.4 自定义错误页面
example.com {
handle_errors {
@404 {
status 404
}
handle @404 {
rewrite * /404.html
file_server
}
handle {
file_server {
root /var/www/errors
}
}
}
root * /var/www/example
file_server
}
十、多站点配置
10.1 同一端口配置多个站点(基于域名)
site1.com {
root * /var/www/site1
file_server
}
site2.com {
root * /var/www/site2
file_server
}
10.2 同一域名配置多个站点(基于路径)
example.com {
handle /app1/* {
root * /var/www/app1
file_server
}
handle /app2/* {
root * /var/www/app2
file_server
}
handle {
root * /var/www/default
file_server
}
}
10.3 多配置文件管理
# /etc/caddy/Caddyfile 主文件
import sites/*.conf
# /etc/caddy/sites/example.conf
example.com {
root * /var/www/example
file_server
}
十一、与 Docker 配合使用
11.1 使用官方镜像
docker run -d \
-p 80:80 -p 443:443 \
-v $PWD/Caddyfile:/etc/caddy/Caddyfile \
-v $PWD/data:/data \
-v $PWD/html:/usr/share/caddy \
--name caddy \
caddy:alpine
11.2 Docker Compose 示例
version: '3.8'
services:
caddy:
image: caddy:alpine
container_name: caddy-proxy
ports:
- "80:80"
- "443:443"
- "443:443/udp"
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile:ro
- ./data:/data
- ./config:/config
- ./html:/usr/share/caddy:ro
restart: unless-stopped
app:
image: node:18-alpine
container_name: app-server
working_dir: /app
volumes:
- ./app:/app
command: node server.js
expose:
- "3000"
11.3 在容器中生成配置文件
docker run --rm -it caddy:alpine caddy run --config /dev/stdin <<EOF
example.com {
reverse_proxy host.docker.internal:3000
}
EOF
十二、调试与故障排查
12.1 测试配置文件
caddy validate --config Caddyfile
caddy validate --config Caddyfile --show
12.2 查看日志
sudo journalctl -u caddy -f
sudo journalctl -u caddy -n 100
sudo journalctl -u caddy -p err
12.3 调试模式运行
caddy run --config Caddyfile --debug
caddy run --config Caddyfile --debug --log-format console
12.4 常用诊断命令
ps aux | grep caddy
sudo netstat -tlnp | grep caddy
caddy list-tls
caddy list-certs
caddy renew
十三、进阶功能
13.1 HTTP/3 支持
Caddy 默认支持 HTTP/3(基于 QUIC 协议),只需确保端口 443 的 UDP 也对外开放即可。
{
servers {
protocol {
experimental_http3
}
}
}
example.com {
root * /var/www/example
file_server
}
13.2 使用环境变量
{
env MY_APP_PORT 3000
}
api.example.com {
reverse_proxy localhost:{$MY_APP_PORT}
}
或从 .env 文件加载:
APP_PORT=3000
api.example.com {
reverse_proxy localhost:{$APP_PORT}
}
13.3 请求体处理
example.com {
# 读取请求体
@post {
method POST
}
handle @post {
header Content-Type "application/json"
respond `{"message": "Received"}` 200
}
}
13.4 响应模板
example.com {
root * /var/www/example
file_server
# 动态响应
handle /info {
respond `{"host": "{host}", "remote": "{remote_host}", "time": "{now}"}` 200
header Content-Type "application/json"
}
}
13.5 WebSocket 升级
ws.example.com {
reverse_proxy localhost:3000 {
header_up Upgrade {http.request.header.Upgrade}
header_up Connection {http.request.header.Connection}
}
}
13.6 文件上传
upload.example.com {
root * /var/www/uploads
file_server {
browse
}
# 限制上传大小 100MB
request_body {
max_size 100MB
}
}
十四、常用命令速查
caddy run
caddy run --config Caddyfile
caddy start
caddy stop
caddy reload
caddy validate --config Caddyfile
caddy version
caddy help
caddy list-certs
caddy renew
caddy hash-password --plaintext "password"
十五、常见问题与解决
| 问题 | 解决方法 |
|---|
| 证书申请失败 | 检查域名 DNS 是否正确;检查防火墙是否开放 80/443 端口;尝试使用 acme_ca 测试环境 |
| 端口 80/443 被占用 | 停止其他 Web 服务器(如 Nginx/Apache);修改监听端口 |
| 反向代理 502 错误 | 检查后端服务是否运行;检查代理地址是否正确 |
| 静态文件 404 | 检查 root 路径是否正确;检查文件权限 |
| HTTPS 证书过期 | Caddy 会自动续签,或手动运行 caddy renew |
| 无法绑定特权端口(<1024) | 使用 sudo 运行;或使用 setcap 授权 |
| 日志文件过大 | 配置 logrotate;或使用 systemd 日志管理 |
| 内存占用过高 | 减少同时连接数;使用 request_body 限制大小 |
| 与 Let’s Encrypt 速率限制冲突 | 使用测试环境;或等待速率限制重置 |
十六、配置模板
16.1 静态站点模板
example.com {
# 启用 Gzip 压缩
encode gzip zstd
# 设置根目录
root * /var/www/example
# 安全头部
header {
X-XSS-Protection "1; mode=block"
X-Content-Type-Options "nosniff"
X-Frame-Options "SAMEORIGIN"
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
Referrer-Policy "strict-origin-when-cross-origin"
}
# 静态文件缓存
@static {
file
path *.css *.js *.png *.jpg *.jpeg *.gif *.ico *.svg *.webp *.woff *.woff2
}
header @static Cache-Control "public, max-age=31536000, immutable"
# 文件服务
file_server
# 日志
log {
output file /var/log/caddy/example.com.access.log
}
}
16.2 反向代理模板
api.example.com {
# 启用 Gzip 压缩
encode gzip zstd
# 反向代理
reverse_proxy localhost:3000 localhost:3001 localhost:3002 {
# 负载均衡策略
lb_policy round_robin
# 健康检查
health_uri /health
health_interval 30s
health_timeout 5s
# 请求头传递
header_up Host {http.request.host}
header_up X-Real-IP {http.request.remote_host}
header_up X-Forwarded-For {http.request.remote_host}
header_up X-Forwarded-Proto {http.request.scheme}
}
# 日志
log {
output file /var/log/caddy/api.example.com.access.log
}
}
16.3 API 服务模板
api.example.com {
# 启用压缩
encode gzip zstd
# 安全头部
header {
Access-Control-Allow-Origin "*"
Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS"
Access-Control-Allow-Headers "Content-Type, Authorization"
X-Content-Type-Options "nosniff"
}
# 处理预检请求
@options {
method OPTIONS
}
handle @options {
respond "" 204
}
# API 代理
handle /v1/* {
reverse_proxy localhost:3000 {
header_up Host {http.request.host}
header_up X-Real-IP {http.request.remote_host}
header_up Authorization {http.request.header.Authorization}
}
}
# API 文档
handle /docs/* {
root * /var/www/api-docs
file_server
}
# 限制请求速率
rate_limit {
zone api {
key {http.request.remote_host}
events 100
window 1m
}
}
# 日志
log {
output file /var/log/caddy/api.example.com.access.log
format json
}
}
16.4 SPA 应用模板
app.example.com {
root * /var/www/spa/dist
# 所有请求返回 index.html(SPA 路由支持)
route {
try_files {path} /index.html
}
# 静态资源缓存
@static {
file
path *.css *.js *.png *.jpg *.jpeg *.gif *.ico *.svg *.webp
}
header @static Cache-Control "public, max-age=31536000, immutable"
file_server
}
16.5 WordPress 模板
blog.example.com {
root * /var/www/wordpress
# PHP-FPM 处理
php_fastcgi localhost:9000
# 静态文件缓存
@static {
file
path *.css *.js *.png *.jpg *.jpeg *.gif *.ico *.svg *.webp
}
header @static Cache-Control "public, max-age=31536000, immutable"
file_server
}
十七、资源与参考
- 官方文档: https://caddyserver.com/docs/
- Caddyfile 语法: https://caddyserver.com/docs/caddyfile
- 指令参考: https://caddyserver.com/docs/caddyfile/directives
- GitHub 仓库: https://github.com/caddyserver/caddy
- Caddy 社区论坛: https://caddy.community/
- 模块列表: https://caddyserver.com/download
十八、Caddy vs Nginx 对比
| 特性 | Caddy | Nginx |
|---|
| 配置复杂度 | 简单直观 | 复杂,学习曲线陡峭 |
| 自动 HTTPS | 默认开启 | 需要额外配置 |
| 证书管理 | 自动申请和续签 | 手动或借助第三方工具 |
| 配置文件语法 | 类似 HCL/JSON,简洁 | 自定义,块状结构 |
| 动态重载 | 支持 | 支持(reload) |
| 性能 | 中等(Go 实现) | 极高(C 实现) |
| 模块化 | 基于插件,易于扩展 | 编译时静态模块 |
| 日志格式 | 灵活,支持 JSON | 自定义格式 |
| WebSocket 支持 | 原生支持 | 需配置 upgrade 头 |
| HTTP/3 | 原生支持 | 需单独编译模块 |
| 适用场景 | 中小型项目、API 网关、开发测试 | 大型高并发、复杂路由、CDN |
结语
Caddy 是一款非常适合现代 Web 开发的服务器,其自动 HTTPS、简单配置和丰富功能让开发者能够快速部署安全可靠的服务。无论是静态网站、反向代理还是 API 网关,Caddy 都能以最少的配置完成工作。
建议从最简单的静态站点开始,逐步探索反向代理、负载均衡等高级功能。Caddy 的官方文档非常完善,遇到问题时可以随时查阅。
祝使用愉快!🚀