Caddy 服务器实战:自动 HTTPS 与反向代理配置完全指南

提起网站服务器,绝大多数人第一个想到的是Nginx,第二个是Apache。但最近几年,一个叫Caddy的Web服务器在独立开发者圈子里越来越火,它的最大卖点就一句话:配置里写个域名,HTTPS证书自动申请、自动续期,什么都不用管。对于不想在证书和配置上耗费精力的个人站长来说,Caddy可能是比Nginx更省心的选择。这篇文章就带你从安装开始,把Caddy的常用配置完整过一遍。

一、Caddy 是个什么样的服务器

Caddy是用Go语言写的开源Web服务器,和Nginx一样可以托管静态文件、运行PHP、做反向代理,但设计理念完全不同:Nginx的配置文件是过程式的,指令多、学习曲线陡;而Caddy使用一种叫Caddyfile的声明式配置,语法非常简洁,几行就能描述一个完整的站点。Caddy最核心的特性是自动HTTPS:只要站点配置里写了域名,它会自动通过ACME协议向Let’s Encrypt或ZeroSSL申请证书、自动续期、自动把HTTP流量跳转到HTTPS,全程不需要手动执行任何命令,也没有certbot renew定时任务那一套。此外Caddy默认启用一些安全相关的响应头,开箱即用的安全性比默认状态的Nginx好不少。当然,它也有不足:模块生态和中文教程远不如Nginx丰富,四层TCP/UDP代理等高级场景支持有限。所以Caddy更适合"网站数量不多、想省心"的个人站长,而不是需要复杂流量治理的大规模场景。

二、安装与启动

Caddy官方提供了各Linux发行版的软件源,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

安装完成后,Caddy会自动注册成systemd服务并开机自启,直接查看状态:

systemctl status caddy

caddy version

配置文件默认在/etc/caddy/Caddyfile,网站文件默认目录是/usr/share/caddy。如果只是临时体验,也可以下载官方编译好的静态二进制文件,放到/usr/local/bin就能用,升级时直接替换文件即可。

三、Caddyfile 入门:托管第一个 PHP 站点

Caddyfile的语法核心是"站点地址加一对花括号",里面写这个站点要做什么。下面是一个典型的PHP站点配置,以Typecho或WordPress这类博客程序为例:

blog.example.com {

root * /var/www/blog
encode gzip zstd
php_fastcgi unix//run/php/php8.2-fpm.sock
file_server

}

逐行解释一下:第一行是站点域名,Caddy看到这个域名就会自动去申请证书;root指定网站文件根目录,星号表示这个规则匹配所有路径;encode开启压缩,gzip和zstd两种算法都支持,浏览器支持哪个就用哪个;php_fastcgi把PHP请求转发给本机的PHP-FPM,后面跟的是FPM的Unix套接字地址,注意双斜杠是Unix套接字的标准写法;file_server负责伺服静态文件。特别要说明的是,php_fastcgi内部已经内置了try_files逻辑,默认会依次尝试原始路径、目录下的index.php、根目录的index.php,所以博客的伪静态链接不用额外配置就能正常工作,这一点比Nginx的rewrite规则省心太多。配置保存后执行下面的命令让改动生效:

caddy validate --config /etc/caddy/Caddyfile
systemctl reload caddy

第一条命令先校验配置语法,没问题再重载,这是避免把配置改坏导致网站挂掉的好习惯。

四、自动 HTTPS 是怎么工作的

Caddy的自动HTTPS值得单独讲一讲,因为这是它和Nginx体验差距最大的地方。原理上,Caddy内置了ACME协议的客户端,配置里出现域名后,它会自动向证书颁发机构申请证书,默认同时使用Let’s Encrypt和ZeroSSL两个机构,申请成功后证书会自动续期,续期时间到之前Caddy会静默完成替换,站长完全无感。申请过程中,Caddy默认监听80端口做HTTP校验,或者用443端口的TLS扩展校验,所以服务器防火墙必须放行80和443两个端口。同时,访问HTTP地址时Caddy会自动301跳转到HTTPS,全站加密是默认行为而不是可选项。

如果你只是想在本机或者内网测试,没有公网域名,可以在站点配置里加一行tls internal,让Caddy使用自带的本地CA签发证书,浏览器会提示证书不受信任,但用来调试HTTPS相关功能完全够用。国内用户要注意两点:一是如果服务器在境内,域名需要完成ICP备案才能正常使用80和443端口对外提供服务;二是申请证书时Caddy需要能访问ACME服务器,网络环境如果屏蔽了相关域名,证书会申请失败,这种情况可以手动指定备用的证书申请渠道。

五、反向代理:给各种自建服务当网关

个人服务器上通常不止跑一个网站,还有各种自建服务,比如博客、导航页、API服务、内网工具,它们各自监听不同的端口。Caddy做反向代理非常顺手,一行配置就能把某个域名或路径转发到本机的任意端口:

api.example.com {

reverse_proxy 127.0.0.1:8080

}

tools.example.com {

reverse_proxy 127.0.0.1:9000

}

上面的配置把api.example.com的请求全部转发给本机8080端口的服务,tools.example.com转发给9000端口,HTTPS证书同样是自动处理。如果想把多个服务放在同一个域名下,用路径来区分,可以配合handle指令:

example.com {

handle /api/* {
    reverse_proxy 127.0.0.1:3000
}
handle {
    root * /var/www/app
    file_server
}

}

这样example.com/api/开头的请求进3000端口的应用,其余请求伺服静态文件。Docker用户可以把Caddy和容器配合使用:容器把端口映射到本机,Caddy反代本机端口即可,也可以让Caddy直接反代Docker内网地址,比如reverse_proxy app:8080,前提是Caddy和容器在同一个Docker网络里。转发时Caddy会自动设置X-Forwarded-For等标准请求头,后端程序拿到的客户端IP是真实的,不需要像Nginx那样手动配置一堆header。

六、常用功能速查

下面整理几个个人站长最常用的Caddy配置片段,方便直接抄作业。访问日志默认是输出到标准错误并由systemd收集,想自己定义格式和位置,可以加全局配置:

{

log {
    output file /var/log/caddy/access.log
    format console
}

}

给静态资源设置长缓存,让浏览器和CDN少回源:

static.example.com {

root * /srv/photos
encode gzip
header /assets/* Cache-Control "public, max-age=31536000, immutable"
file_server browse

}

file_server后面的browse参数表示允许目录列表浏览,适合做文件分享站。给管理后台加密码保护,用basicauth指令,密码需要先用caddy hash-password生成哈希:

admin.example.com {

basicauth {
    admin $2a$14$生成的密码哈希值
}
reverse_proxy 127.0.0.1:8080

}

多个站点就写在同一个Caddyfile里,每个域名一块,互不影响,维护起来一目了然。想查看当前生效的配置,用caddy adapt命令可以把Caddyfile转换成JSON格式,方便理解每条指令背后的实际配置。

七、要不要从 Nginx 换到 Caddy

很多站长看完上面的介绍会纠结:我要不要把手上的Nginx换成Caddy?笔者的建议是分情况。如果你的网站只有一两个域名,主要诉求是托管博客、反代几个自建服务,厌倦了手动维护证书,那换到Caddy的收益非常明显,迁移成本也不高,静态文件和PHP站点的配置翻译过来通常只有Nginx的几分之一。但如果你的服务器上运行着大量依赖Nginx特性的复杂配置,比如多层location匹配、复杂的rewrite规则、四层TCP代理,或者团队里所有人都只会Nginx,那就不建议为了尝鲜而折腾,毕竟工具没有绝对的好坏,只有合不合适。也可以采用折中方案:新服务、新站点用Caddy,老站点保持Nginx不动,两台服务器或者两个端口各管一摊,平稳过渡。

八、常见问题与排错

问:配置了域名但证书一直申请失败怎么办?答:先确认80和443端口在防火墙里放行了,再用caddy diagnose命令检查,常见原因是端口被占、域名解析没生效、或者服务器无法访问ACME服务器。

问:PHP站点打开是空白或者直接下载PHP文件?答:检查php_fastcgi后面的FPM套接字路径,和php-fpm.conf里的listen配置是否一致,Debian系常见路径是/run/php/php8.2-fpm.sock,注意安装的PHP版本要匹配。

问:Caddyfile改动后怎么生效,会中断服务吗?答:用systemctl reload caddy是平滑重载,正在处理的请求不会中断;如果配置写错了也不用慌,reload失败时Caddy会继续跑旧配置。

作为Web服务器家族里的后来者,Caddy用"自动HTTPS"这一个杀手级特性就足以让无数站长省下大量重复劳动,再加上简洁到近乎直觉的配置语法,它特别适合作为个人站长的第二台服务器软件。与其在证书续期和rewrite规则里反复折腾,不如把精力省下来好好写内容——这大概才是工具存在的意义。

九、总结

本文从安装、静态站点、PHP运行、自动HTTPS、反向代理到常用技巧,完整介绍了Caddy的日常用法。Caddy的核心理念是把繁琐的事情交给程序,把简单留给用户,如果你的服务器配置里还有一大段手动管理证书的脚本,不妨抽个周末试试Caddy,感受一下"写完配置就能用"的畅快。

Last modification:September 4th, 2026 at 08:01 am

Leave a Comment