使用 Caddy 代替 Nginx

提醒:本文最后更新于 2321 天前,文中所描述的信息可能已发生改变,请谨慎使用。

Caddy 是一款由 Go 编写的 Web Server 工具,在折腾 Drone 的时候,我最终就是使用的它提供 Web 服务。回到标题,为什么要用 Caddy 替换掉 Nginx 呢?最主要的原因是 Caddy 能让网站自动支持 HTTPS。同样是使用 Let’s Encrypt,换成 Nginx 我们就必须手工操作,并且还需要设置三个月更新证书的计划任务。而且默认还支持 http/2,很多事情都不需要我们再配置了。另外它的配置文件也比 Nginx 的要简单很多,几十行的 Nginx 配置文件 Caddy 仅需要几行就可以搞定了。

安装 Caddy

Caddy 提供了一键安装命令生成功能,访问 https://caddyserver.com/download 选择对应的平台,插件可默认为空,最后选择对应的协议后下方即会生成一键安装命令,例如:

$ curl https://getcaddy.com | bash -s personal

安装后执行 which caddy 你会发现 Caddy 已经安装到了 /usr/local/bin/caddy 位置。

caddy命令生成

$ echo 'localhost:8000' >> Caddyfile
$ caddy

执行如上命令在浏览器中访问 http://localhost:8000 发现 Caddy 启动了一个简单的 HTTP 服务器。

后台启动

首先我们为 Caddy 创建一个配置目录,这里以 /etc/caddy 为例。同时我们还需要生成一个目录用来给 Caddy 放置网站证书。

$ sudo mkdir /etc/caddy
$ sudo mkdir /etc/caddy/conf
$ echo 'import ./conf/*' >> /etc/caddy/Caddyfile
$ sudo mkdir /etc/ssl/caddy

从官方仓库中下载 caddy 的 systemctl 守护脚本并对其挂载启动。

$ sudo curl -s https://raw.githubusercontent.com/mholt/caddy/master/dist/init/linux-systemd/caddy.service -o /etc/systemd/system/caddy.service
$ sudo systemctl daemon-reload
$ sudo systemctl enable caddy
$ sudo systemctl start caddy

这样我们就完成 caddy 后台启动任务,可以使用 status 命令查看 caddy 的状态:

$ sudo systemctl status caddy

Caddyfile

Caddyfile 是 Caddy 的配置文件,刚才我们写入了一条 import ./conf/* 命令,表示将 /etc/caddy/conf/ 下的所有文件都导入到配置文件中。下面我就以几个大家常见的需求列举一下如何编写 Caddfile 配置。

静态资源

和 Nginx 一样,Caddy 也有一个 root 配置。静态资源的访问只要设置到对应的 root 即可。同时我们也为资源配置了 gzip 压缩功能。

$ sudo cat << EOF > /etc/caddy/conf/static.example.com
static.example.com {
    gzip
    root    /var/www/static.example.com
}
EOF
$ sudo systemctl restart caddy

反向代理

反向代理请求到另外的端口算是我们比较常见的需求了,通过 proxy 指令我们可以非常简单的做到。以 ThinkJS 的配置为例,我们在静态资源配置的基础之上,增加了 proxy 指令将请求反向代理到了 http://127.0.0.1:8360 端口。由于反向代理后丢失了原始请求的 HOST,我们使用 transparent 指令增加 X-* 头。最后我们使用 except 指令排除了 /static 的请求,因为这些请求是静态资源的不需要反代。

$ sudo cat << EOF > /etc/caddy/conf/thinkjs.example.com
thinkjs.example.com {
    gzip
    root /var/www/thinkjs.example.com/www
    proxy / http://127.0.0.1:8360 {
        transparent
        except static
    }
}
$ sudo systemctl restart caddy

我们可以对比下 ThinkJS Nginx 的配置文件,以下还仅仅只是 HTTP 的配置,没有加上 HTTPS 以及 HTTP/2 的配置。所以 Caddy 的简单性不言而喻。

server {
    listen 80;
    server_name example.com www.example.com;
    root <%= ROOT_PATH %>;
    set $node_port 8360;

    index index.js index.html index.htm;
    if ( -f $request_filename/index.html ){
        rewrite (.*) $1/index.html break;
    }
    if ( !-f $request_filename ){
        rewrite (.*) /index.js;
    }
    location = /index.js {
        proxy_http_version 1.1;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-NginX-Proxy true;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_pass http://127.0.0.1:$node_port$request_uri;
        proxy_redirect off;
    }

    location ~ /static/ {
        etag         on;
        expires      max;
    }
}

Websocket

Caddy 配置 WebSocket 也非常简单,使用 websocket 指令即可。

$ sudo cat << EOF > /etc/caddy/conf/thinkjs.example.com
ws.example.com {
    gzip
    root /var/www/ws.example.com/www
    proxy / http://127.0.0.1:8360 {
        websocket
        transparent
        except static
    }
}
$ sudo systemctl restart caddy

更多的配置指令可以上 https://caddyserver.com/docs 官方文档查看,也可以上 https://github.com/caddyserver/examples 仓库中查看各种程序对应的 Caddy 配置。

总结

最近使用下来之后觉得 Caddy 真是太方便了,不用操心 SSL 证书过期的事情,也不用愁看不懂配置文件了,简单几行就能搞定大部分的功能。对于没有什么特别功能的个人网站来说真是再适合不过了,希望大家也可以试试 Caddy 这款小清新 HTTP Server。

参考资料:

Avatar
怡红公子 擅长前端和 Node.js 服务端方向。热爱开源时常在 Github 上活跃,也是博客爱好者,喜欢将所学内容总结成文章分享给他人。

12 评论

萌新 Safari12.1 Mac OS 10.14.6
2019-08-22 06:43:12 回复

这教程已经不行了,caddy.service起不来

公子 Chrome76.0 Mac OS 10.14.6
2019-08-24 01:20:41 回复

@萌新 怎么启不起来了,我稍微看了下那个 service 文件,好像没什么问题诶。

萌新 Safari12.1 Mac OS 10.14.6
2019-08-24 02:53:24 回复

@公子 搞定了,应该是/etc/systemd/system/caddy.service改了不少东西,用户跟群组的默认权限问题,还有ReadWritePaths=/etc/ssl/caddy兼容性问题。

公子 Chrome76.0 Mac OS 10.14.6
2019-08-24 03:29:23 回复

@萌新 优秀,给你点赞呢!

迷茫 Chrome63.0 Windows 7
2018-12-06 10:32:08 回复

博主,请问怎么卸载。。

公子 Chrome70.0 Mac OS 10.14.2
2018-12-06 11:17:58 回复

@迷茫 直接 which caddy 找到对应的执行文件删除掉就好了

candura Chrome55.0 Windows 7
2018-10-09 03:17:59 回复

看了很多文章,提到Caddy的优势都是配置简单,可以方便的全站HTTPS。
可是没看到有比较Caddy和Nginx在性能和内存占用上的对比呢……不知道这方面Caddy是否比Nginx更适合超小内存的VPS。

公子 Chrome70.0 Mac OS 10.14.1
2018-10-31 12:24:13 回复

@candura确实不多,内存占用上我觉得 Caddy 应该比 Nginx 会废点,具体你可以试一下。

Zvonimir Chrome67.0 Windows 10
2018-07-30 13:58:24 回复

这个caddy的rewrite规则我一直都没怎么搞明白。

公子 Chrome67.0 Mac OS 10.13.4
2018-07-31 01:54:35 回复

@Zvonimir唔,其实 nginx 的 rewrite 也挺复杂的…所以 rewrite 这个东西应该就是比较复杂(大雾

Zvonimir Chrome67.0 Windows 10
2018-07-31 02:03:10 回复

@公子 主要nginx资料比较多,还相对好理解一些。caddy嘛,现在例子还比较欠缺,虽然知道一些简单的用法,但是想完全把nginx实现的内容改过去还是有点难。

公子 Chrome67.0 Mac OS 10.13.4
2018-07-31 02:04:52 回复

@Zvonimir 同意,用 Caddy 的人还是少了点,目前我主要的站也还是 Nginx,新的站才用的 Caddy。