Caddy server

Caddy 是一个使用 Go 编写的高性能 HTTP 服务器软件。与 Nginx 相似,它主要作为静态网站服务器或反向代理运行。

优点

  • 高性能
  • 简洁的配置文件
  • 全自动 HTTPS (Let's Encrypt)

安装

Caddy 官方为 Linux, Windows, FreeBSD 提供预编译二进制,为主流发行版提供软件包。(见 官方安装文档

Debian/Ubuntu:

sudo apt install -y debian-keyring debian-archive-keyring apt-transport-https
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

Arch Linux:

sudo pacman -S caddy

启动服务

启动 Caddy 服务:

sudo systemctl start caddy

(或者改用 enable --now 同时将服务设置为自动启动)

配置文件

本文使用 Caddyfile 作为配置方法,Caddy 还支持 APIconfig adapter 等配置。

Caddyfile 的路径在 /etc/caddy/Caddyfile(如果使用默认 systemd 服务配置),修改 Caddyfile 文件后,可以通过 systemctl 加载新的配置:

sudo systemctl reload caddy

常用配置

静态网站

网站 yuuza.net,提供 /srv/mysite 作为静态内容

yuuza.net {
    root * /srv/mysite
    file_server
}

Caddy 将会自动为 yuuza.net 申请 TLS 证书。申请成功的前提是,在公网上访问 yuuza.net 到达的服务器就是 Caddy 所在服务器(即域名解析正确,并且 IP 能从公网访问)。并且会自动将 80 端口上的 HTTP 请求跳转到 HTTPS。

多域名(虚拟主机)

Caddy 支持服务多个域名

yuuza.net {
    root * /srv/mysite
    file_server
}

blog.yuuza.net {
    root * /srv/myblog
    file_server
}

反向代理

将请求反向代理到 127.0.0.1:5000

api.yuuza.net {
    reverse_proxy 127.0.0.1:5000
}

按路径分流

/api/* 反向代理到 127.0.0.1:5000,对其它路径上的请求提供 /srv/mysite 里的文件

yuuza.net {
    reverse_proxy /api/* 127.0.0.1:5000
    
    root * /srv/mysite
    file_server
}

路径修改

使用上面的配置文件时,https://yuuza.net/api/myip 将会被反代到 127.0.0.1:5000 端口上的 /api/myip。如果需要将它反代到 /myip,就要去除路径开头的 /api

yuuza.net {
    handle /api/* {
        uri strip_prefix /api
        # 以上两行等效于 handle_path /api/* {
        reverse_proxy * 127.0.0.1:5000
    }
    
    root * /srv/mysite
    file_server
}

支持前端 History 路由

如果前端是一个 SPA 并使用 History 路由(URL 路径作为路由),服务端需要对任意 URL 返回 index.innerHTML

yuuza.net {
    handle_path /api/* {
        reverse_proxy * 127.0.0.1:5000
    }
    
    root * /srv/mysite
    try_files {path} /index.html
    file_server
}
yuuza.net {
    @dev {
        header x-version dev
    }

    handle @dev {
        root * /srv/mysite-dev
        file_server
    }

    root * /srv/mysite
    file_server
}

客户端携带 x-version: dev HTTP 头时,访问到 /srv/mysite-dev(测试环境),否则访问到 /srv/mysite(正式环境)

缓存头设置

Caddyfile

yuuza.net {
    header {
        Cache-Control "public, max-age=31536000, immutable"
    }
    handle_errors {
        header -Cache-Control
    }
    # ...
}

设置 Cache-Control 缓存头,并通过 handle_errors 在发生错误时取消缓存头,避免缓存错误响应。