文档
一个 项目

常见的 Caddyfile 模式

此页面演示了一些完整且最小的 Caddyfile 配置,用于常见的用例。这些可以作为您自己的 Caddyfile 文档的有用起点。

这些不是直接使用的解决方案;您将不得不自定义您的域名、端口/套接字、目录路径等。它们旨在说明一些最常见的配置模式。

静态文件服务器

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

像往常一样,第一行是站点地址。 root 指令 指定站点根目录的路径(* 表示匹配所有请求,以便与 路径匹配器 区分)——如果您的站点不是当前工作目录,请更改路径。最后,我们启用 静态文件服务器

反向代理

代理所有请求

example.com {
	reverse_proxy localhost:5000
}

仅代理路径以 /api/ 开头的请求,并为所有其他请求提供静态文件

example.com {
	root * /var/www
	reverse_proxy /api/* localhost:5000
	file_server
}

这使用 请求匹配器 仅匹配以 /api/ 开头的请求,并将它们代理到后端。所有其他请求将从站点 root 使用 静态文件服务器 提供服务。这也取决于 reverse_proxy指令顺序 上比 file_server 更高。

这里有更多 reverse_proxy 示例

PHP

PHP-FPM

使用运行的 PHP FastCGI 服务,类似于以下内容适用于大多数现代 PHP 应用程序

example.com {
	root * /srv/public
	encode gzip
	php_fastcgi localhost:9000
	file_server
}

相应地自定义站点根目录;此示例假设您的 PHP 应用程序的 Web 根目录位于 public 目录中——对磁盘上存在的文件的请求将使用 file_server 提供服务,任何其他请求都将路由到 index.php 以供 PHP 应用程序处理。

您有时可以使用 Unix 套接字连接到 PHP-FPM

php_fastcgi unix//run/php/php8.2-fpm.sock

php_fastcgi 指令 实际上只是 几部分配置 的快捷方式。

FrankenPHP

或者,您可以使用 FrankenPHP,它是一个 Caddy 发行版,使用 CGO(Go 到 C 绑定)直接调用 PHP。这比使用 PHP-FPM 快 4 倍,如果您能使用工作模式,效果会更好。

{
    frankenphp
    order php_server before file_server
}

example.com {
	root * /srv/public
    encode zstd br gzip
    php_server
}

重定向 www. 子域名

添加 www. 子域名并进行 HTTP 重定向

example.com {
	redir https://www.{host}{uri}
}

www.example.com {
}

删除

www.example.com {
	redir https://example.com{uri}
}

example.com {
}

要一次删除多个域名;这使用 {labels.*} 占位符,它们是主机名的部分,从右边开始索引为 0(例如 0=com1=example-one2=www

www.example-one.com, www.example-two.com {
	redir https://{labels.1}.{labels.0}{uri}
}

example-one.com, example-two.com {
}

尾部斜杠

您通常不需要自己配置它;file_server 指令 会通过 HTTP 重定向自动添加或删除请求中的尾部斜杠,具体取决于请求的资源是目录还是文件。

但是,如果您需要,您仍然可以使用您的配置强制使用尾部斜杠。有两种方法可以做到:内部或外部。

内部强制

这使用 rewrite 指令。Caddy 将在内部重写 URI 以添加或删除尾部斜杠

example.com {
	rewrite /add     /add/
	rewrite /remove/ /remove
}

使用重写,带有和不带有尾部斜杠的请求将是相同的。

外部强制

这使用 redir 指令。Caddy 将要求浏览器更改 URI 以添加或删除尾部斜杠

example.com {
	redir /add     /add/
	redir /remove/ /remove
}

使用重定向,客户端将不得不重新发出请求,强制使用单个可接受的 URI 来访问资源。

通配符证书

如果您需要使用相同的通配符证书为多个子域名提供服务,最好的方法是使用类似于此的 Caddyfile,利用 handle 指令host 匹配器

*.example.com {
	tls {
		dns <provider_name> [<params...>]
	}

	@foo host foo.example.com
	handle @foo {
		respond "Foo!"
	}

	@bar host bar.example.com
	handle @bar {
		respond "Bar!"
	}

	# Fallback for otherwise unhandled domains
	handle {
		abort
	}
}

您必须启用 ACME DNS 挑战 才能让 Caddy 自动管理通配符证书。

单页应用程序 (SPA)

当网页执行自己的路由时,服务器可能会收到大量对服务器端不存在但只要提供单个索引文件就可以在客户端呈现的页面的请求。这样构建的 Web 应用程序被称为 SPA,即单页应用程序。

主要思想是让服务器“尝试文件”以查看请求的文件是否在服务器端存在,如果不存在,则回退到客户端执行路由的索引文件(通常使用客户端 JavaScript)。

典型的 SPA 配置通常如下所示

example.com {
	root * /srv
	encode gzip
	try_files {path} /index.html
	file_server
}

如果您的 SPA 与 API 或其他仅服务器端端点耦合,您将需要使用 handle 块来专门处理它们

example.com {
	encode gzip

	handle /api/* {
		reverse_proxy backend:8000
	}

	handle {
		root * /srv
		try_files {path} /index.html
		file_server
	}
}

Caddy 代理到另一个 Caddy

如果您有一个公开可访问的 Caddy 实例(我们称之为“front”),以及另一个在您的私有网络中的 Caddy 实例(我们称之为“back”)为您的实际应用程序提供服务,您可以使用 reverse_proxy 指令 传递请求。

前端实例

foo.example.com, bar.example.com {
	reverse_proxy 10.0.0.1:80
}

后端实例

{
	servers {
		trusted_proxies static private_ranges
	}
}

http://foo.example.com {
	reverse_proxy foo-app:8080
}

http://bar.example.com {
	reverse_proxy bar-app:9000
}
  • 此示例为两个不同的域名提供服务,将两者都代理到同一个后端 Caddy 实例,端口为 80。您的后端实例以两种不同的方式为两个域名提供服务,因此它使用两个独立的站点块进行配置。

  • 在后端,http:// 用于在端口 80 上接受 HTTP。前端实例终止 TLS,并且前端和后端之间的流量在私有网络上,因此无需重新加密它。

  • 如果您需要,可以在后端实例上使用不同的端口,例如 8080;只需将 :8080 附加到后端配置上的每个站点地址,或者将 http_port 全局选项 设置为 8080

  • 在后端,trusted_proxies 全局选项 用于告诉 Caddy 信任前端实例作为代理。这确保保留了真实客户端的 IP。

  • 更进一步,您可能有多个后端实例,您可以在它们之间进行 负载均衡。您可以使用前端实例上的 acme_server 设置 mTLS(双向 TLS),使其充当后端实例的 CA(如果前端和后端之间的流量跨越不受信任的网络,这很有用)。