过去很长一段时间,我对 Web Server 的默认选择几乎没有犹豫过:

上服务器,装 Nginx。

这已经变成了一种肌肉记忆。

买一台 VPS,部署一个博客、一个 API 服务、一个管理后台,基本流程都是:

sudo apt install nginx
sudo vim /etc/nginx/sites-available/xxx
sudo ln -s /etc/nginx/sites-available/xxx /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

如果要上 HTTPS,还要继续:

sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com

然后再确认:

  • 证书是否申请成功
  • HTTP 是否跳转到 HTTPS
  • 证书是否自动续期
  • Nginx 配置是否 reload 成功
  • WebSocket 是否正常
  • 反向代理 Header 是否正确

这一套流程太熟悉了,以至于我很少怀疑它是不是还值得继续这样做。

直到最近频繁使用 AI Coding 工具,我才意识到一个问题:

不是 Nginx 不好,而是很多场景下,我们可能已经不需要那么复杂的 Nginx 了。

这也是我开始关注 Caddy 的原因。


Caddy 是什么?

Caddy 是一个现代化的 Web Server,也可以作为反向代理、静态文件服务器和 HTTPS 网关使用。

它最大的特点只有一句话:

默认自动 HTTPS。

这听起来很简单,但实际影响非常大。

过去我们使用 Nginx 时,HTTPS 往往需要额外引入 Certbot,配置证书路径,处理续期任务,还要小心 reload。

而 Caddy 把这件事变成了默认能力。

只要域名已经正确解析到服务器,Caddy 就可以自动申请、安装、续期 TLS 证书。

这意味着,很多原本属于”运维配置”的工作,可以直接消失。


一个最直观的对比

假设我要部署一个静态博客,域名是 example.com,静态文件目录是 /var/www/blog

如果使用 Nginx,大概需要这样写:

server {
    listen 80;
    server_name example.com www.example.com;

    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    root /var/www/blog;
    index index.html;

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

这段配置不算复杂,但你会发现真正和业务相关的内容其实只有:

root /var/www/blog;

剩下大量内容都是 HTTPS、证书、跳转和 Nginx 语法。

如果换成 Caddy:

example.com {
    root * /var/www/blog
    file_server
}

就结束了。

HTTPS 自动申请,HTTP 自动跳转 HTTPS,证书自动续期。

这就是 Caddy 最打动我的地方。

它不是让你多学一个复杂工具,而是帮你删掉了大量本来就不应该反复手写的配置。


反向代理也更简单

后端开发经常会部署一些本地服务,比如 localhost:3000localhost:8080localhost:9000

如果用 Nginx 配一个反向代理,常见写法是:

server {
    listen 80;
    server_name api.example.com;

    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-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

这还只是 HTTP。如果加上 HTTPS,还要继续补证书配置。

而 Caddy 中,只需要:

api.example.com {
    reverse_proxy localhost:3000
}

对很多中小项目来说,这个差异非常明显。

尤其是现在很多项目都是:

  • 一个前端站点
  • 一个后端 API
  • 一个管理后台
  • 一个文档站
  • 一个 AI 服务
  • 一个 Docker 容器服务

这些服务大多数并不需要复杂的 Nginx 配置。它们真正需要的是:快速、安全、稳定地暴露到公网。Caddy 刚好非常适合这个场景。


为什么 AI Coding 时代,Caddy 更有吸引力?

我觉得 Caddy 的流行和 AI Coding 有很强关系。

以前我们写配置,是靠经验。现在我们越来越依赖 AI 辅助生成部署脚本、Docker Compose、Nginx 配置、CI/CD 配置。

但这也带来一个问题:

配置越复杂,AI 越容易生成看起来正确、实际有坑的内容。

比如 Nginx 里常见的问题:

  • proxy_set_header 漏写
  • WebSocket 不通
  • HTTP 到 HTTPS 跳转异常
  • try_files 写错导致 SPA 刷新 404
  • SSL 配置过时
  • 多域名配置重复
  • 证书续期后没有 reload
  • gzip、缓存、跨域配置混在一起难以维护

这些问题不是 Nginx 本身不行,而是它给了我们太多可配置空间。

而 Caddy 的思路更像是:

默认帮你选择一套现代、安全、可工作的配置。你只需要声明自己要什么。

例如:

blog.example.com {
    root * /var/www/blog
    file_server
}

api.example.com {
    reverse_proxy localhost:8080
}

这就很符合 AI Coding 时代的开发方式:

  • 配置越少,出错越少
  • 默认安全,减少人为遗漏
  • 语义清晰,方便 AI 生成和维护
  • 单文件配置,适合小团队和个人项目
  • HTTPS 自动化,降低部署门槛

Nginx 真的过时了吗?

严格来说,Nginx 并没有过时。它依然是非常优秀的 Web Server。

在很多复杂场景里,Nginx 仍然非常强:

  • 大流量入口
  • 复杂 Rewrite
  • 高级缓存策略
  • OpenResty / Lua 扩展
  • 企业已有运维体系
  • 多层网关架构
  • 极致性能调优
  • 历史系统兼容

所以我不会说”Nginx 已死”。

更准确的说法应该是:

对很多个人项目、中小项目和 AI 项目来说,默认选择 Nginx 这件事,已经不再是最优解。

以前我们默认用 Nginx,是因为它成熟、稳定、资料多。

但现在,如果只是部署一个博客、一个 API、一个管理后台、一个 AI 工具服务,Caddy 的维护成本明显更低。


我更推荐的选择方式

个人博客

推荐 Caddy。配置少、HTTPS 自动、静态文件服务简单、不需要手动维护证书,非常适合 VPS + GitHub Actions 部署。

example.com {
    root * /var/www/blog
    file_server
}

普通后端 API

推荐 Caddy。例如 Go、Node.js、Java 服务,只需要反向代理:

api.example.com {
    reverse_proxy localhost:8080
}

Docker Compose 小项目

推荐 Caddy。比如一个前端、一个后端、一个管理后台:

example.com {
    reverse_proxy frontend:3000
}

api.example.com {
    reverse_proxy backend:8080
}

admin.example.com {
    reverse_proxy admin:9000
}

配合 Docker 网络会非常舒服。

企业复杂网关

可以继续用 Nginx。尤其是已经有成熟 Nginx 运维体系时,不一定需要为了追新而迁移。


对我个人博客的启发

我的个人博客本身是一个静态站点。它的部署诉求非常简单:

  • GitHub 提交代码
  • CI/CD 构建
  • rsync 到 VPS
  • Web Server 提供静态文件访问
  • 域名支持 HTTPS

这种场景下,Nginx 当然能做。但 Caddy 可能更自然。

以前的部署链路是:

GitHub Actions

构建静态文件

rsync 到 VPS

Nginx 指向 /var/www/blog

Certbot 维护 HTTPS

如果换成 Caddy:

GitHub Actions

构建静态文件

rsync 到 VPS

Caddy 指向 /var/www/blog

HTTPS 自动维护

少了一大块证书和 HTTPS 维护工作。


一个适合个人博客的 Caddyfile

假设博客部署目录是 /var/www/myblog,域名是 xiaojun.ukwww.xiaojun.uk,那么 Caddyfile 可以这样写:

xiaojun.uk, www.xiaojun.uk {
    root * /var/www/myblog
    file_server
    encode gzip zstd
}

如果希望 www 跳转到主域名,可以写成:

www.xiaojun.uk {
    redir https://xiaojun.uk{uri}
}

xiaojun.uk {
    root * /var/www/myblog
    file_server
    encode gzip zstd
}

比 Nginx 清爽很多。


Caddy 的真正价值:不是快,而是省心

很多人在比较 Caddy 和 Nginx 时,第一反应是性能。

但我觉得对大多数个人项目来说,性能不是核心矛盾。真正的核心矛盾是:维护成本

一个个人博客、一个小型 API、一个 AI 工具站点,流量通常远远没到需要极致优化的程度。

真正麻烦的是:

  • 证书过期
  • 配置写错
  • 新服务上线要复制一堆配置
  • 迁移服务器时重新配置
  • AI 生成配置后不确定是否可靠
  • 半年后自己都看不懂当时写了什么

Caddy 解决的正是这些问题。

它让 Web Server 配置回到非常朴素的一件事:

这个域名,对应这个服务。

app.example.com {
    reverse_proxy localhost:3000
}

这就够了。


什么时候不建议换 Caddy?

虽然我很喜欢 Caddy,但也不是所有场景都要换。下面这些情况,可以继续使用 Nginx:

  1. 公司已有成熟 Nginx 运维体系
  2. 线上服务依赖复杂 Nginx Rewrite
  3. 使用 OpenResty / Lua 做了大量网关逻辑
  4. 需要非常细粒度的缓存、限流和流量控制
  5. 迁移成本高于收益
  6. 团队成员都熟悉 Nginx,不熟悉 Caddy

技术选型不是为了追新,而是为了降低整体复杂度。如果你的 Nginx 已经稳定运行,并且没有维护痛点,不换也完全可以。

但如果你正在搭一个新项目,尤其是个人项目,我会认真建议:先试试 Caddy


我的结论

这次重新看 Caddy,我最大的感受是:

不是 Nginx 不行了,而是很多项目已经不需要 Nginx 那么重的配置模型了。

Nginx 代表的是上一代非常成熟的服务器配置方式。Caddy 更像是现代开发体验下的新选择:

  • HTTPS 默认开启
  • 配置极简
  • 反向代理简单
  • 更适合个人项目
  • 更适合 AI Coding 生成和维护
  • 更适合快速部署

过去我们花很多时间学习”如何正确配置服务器”。而现在,越来越多工具的方向是”尽量减少需要配置服务器的地方”。

Caddy 的价值就在这里。它不是为了替代所有 Nginx 场景,而是让很多原本需要 Nginx 的简单场景,变得不再复杂。

对个人博客、Side Project、AI 工具站点来说,这可能就是更好的默认选择。


如果你现在也在用 VPS 部署博客、API、AI 工具或者各种小服务,可以试试 Caddy。

也许你会和我一样有一种感觉:原来 Web Server 配置,可以这么简单。