wuee
反向代理 / Caddy / 2026.08

Caddy 多站点配置实战:静态站、路由与路径重写

Caddy v2.11.4 · 单配置文件托管多个域名

上一篇讲了 Caddy 怎么自动接 HTTPS,这篇聚焦一个 Caddyfile 里同时托管多个站点时的配置技巧:静态站、自定义错误页、按路径分流、子路径重写、多域名复用同一个后端。下面所有片段都来自本服务器的真实配置。

一、站点块:一个域名一段配置

Caddyfile 的基本单元是站点块(site block),域名写在开头,花括号里是这个站点的指令。多域名 + 多站点共享一个实例、一份配置:

wuee.cn {
	root * /var/www/wuee.cn
	file_server
}

napcat.wuee.cn {
	reverse_proxy 127.0.0.1:6099
}

astrbot.wuee.cn {
	reverse_proxy 127.0.0.1:6185
}

root * 里的 * 表示这个站点根路径下的所有请求都从这里找文件;file_server 提供静态文件服务。Caddy 启动时会自动为每个域名申请并续期证书,站点点名即可。

二、静态站 + 自定义错误页

静态站总会遇到不存在的路径,默认的 404 页面很丑。用 handle_errors 统一重写:

sntfct.cn {
	root * /var/www/sntfct.cn
	file_server

	handle_errors {
		rewrite * /404.html
		file_server
	}
}

效果:任何 4xx/5xx 错误都返回 /var/www/sntfct.cn/404.html,状态码保持原始错误码,页面内容统一。注意 handle_errors 块里的 file_server 是单独写的,因为它运行在错误处理阶段。

三、handle 块:静态站和 API 分流

同一个域名下,静态页面和一个后端 API 并存时,用 handle 按路径前缀分流。Caddy 的 handle 是互斥的——只执行第一个匹配的块:

sntfct.cn {
	root * /var/www/sntfct.cn
	file_server

	handle /api/* {
		reverse_proxy 127.0.0.1:9999
	}

	handle /jm/* {
		reverse_proxy 127.0.0.1:8088
	}

	handle_errors {
		rewrite * /404.html
		file_server
	}
}

请求 /api/stats 走 9999 端口的后端,/jm/xxx 走 8088,其他路径落回 file_server 静态服务。三段互不干扰,顺序无关紧要——handle 内部按最长匹配优先,不是按书写顺序。

四、路径重写:子路径应用的根路径访问

不少 Web 应用自带子路径(如 Genshin 面板的 WebUI 在 /app/),用户却希望直接访问域名根路径就打开界面。直接用 rewrite 把根路径改写:

gs.wuee.cn {
	rewrite / /app/
	reverse_proxy 127.0.0.1:8765
}

为什么是 rewrite 而不是简单反代:应用内部渲染的链接、跳转都基于 /app/ 前缀。如果根路径直接反代到应用,浏览器访问 /,应用 302 跳转到 /app/,跳转时 location 头携带的认证信息可能丢失,导致登录态异常。rewrite / /app/ 在转发前就把路径改好,后端收到的就是 /app/ 开头的完整路径,一切正常。

注意:这里 rewrite / /app/ 只匹配根路径。像 /app/xxx 这类路径本身已经在正确前缀下,不需要再处理。

五、多域名复用同一个后端

两个域名指向同一个服务时,不用复制配置,在一个站点块里写多个域名即可(证书会为每个域名单独申请):

gs.wuee.cn,
gs.sntfct.cn {
	rewrite / /app/
	reverse_proxy 127.0.0.1:8765
}

或者用通配符统一管理一组子域名(证书申请需要 DNS 支持通配符验证):

*.wuee.cn {
	# 按子域名分发到不同后端
	@gs  host gs.wuee.cn
	handle @gs {
		rewrite / /app/
		reverse_proxy 127.0.0.1:8765
	}
	# ...
}

六、改配置后的热加载

Caddy 的杀手锏之一:修改 Caddyfile 后不用重启进程,reload 即可零中断生效(证书、路由全部热更新):

# 系统级 Caddy
sudo systemctl reload caddy

# 容器化 Caddy
docker exec maibot-caddy caddy reload --config /etc/caddy/Caddyfile

七、常见坑

延伸阅读:用 Caddy 让所有服务自动接入 HTTPS · Ubuntu 24.04 服务器初始化与 Docker 部署实战
← 返回首页