{ email {$CADDY_EMAIL} on_demand_tls { ask http://backend:8080/api/distribution/check-domain } } # 反代到后端时,用 Caddy 实测到的对端地址覆盖 X-Real-IP, # 防止客户端伪造 X-Forwarded-For 影响限流、审计和支付下单的 client_ip。 (backend_proxy) { header_up X-Real-IP {remote_host} } # 公开 API 反代片段:主站与选号网共用。 (public_api) { @api_sse { path /api/chats/events /api/admin/chats/events } handle @api_sse { reverse_proxy backend:8080 { flush_interval -1 import backend_proxy } } handle /api/* { request_body { max_size 11MB } reverse_proxy backend:8080 { import backend_proxy } } handle /r/* { reverse_proxy backend:8080 { import backend_proxy } } @health path /health /health/ready handle @health { reverse_proxy backend:8080 { import backend_proxy } } } # 前台商城静态资源与安全头配置(主站与所有分销站点共享): # 前端通过 window.location.hostname 自动向 /api/distribution/site-info 请求分销配置。 (storefront) { encode zstd gzip header { Strict-Transport-Security "max-age=31536000" X-Content-Type-Options "nosniff" X-Frame-Options "DENY" Referrer-Policy "strict-origin-when-cross-origin" Permissions-Policy "camera=(), microphone=(), geolocation=()" Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' https: data: blob:; font-src 'self' data:; connect-src 'self'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'; form-action 'self'" } import public_api # 平台校验文件(如 /e82f...txt)在 /m/<文件名>.txt 下也要能取到真实内容。 # /m 是前端路由前缀,未命中静态文件时 try_files 会回退到 index.html, # 导致 /m/*.txt 返回 HTML;这里显式改写回根目录的同名文件。 @mobile_verify_txt path_regexp ^/m/([^/]+\.txt)$ handle @mobile_verify_txt { rewrite * /{re.mobile_verify_txt.1} root * /srv/dist file_server } # 主站后台隐藏入口:storefront 片段同时服务主站和所有分销站点域名, # 这里统一 404,仅主站域名在下方主站 block 用 @main_admin 放行。 @platform_admin path {$ADMIN_BASE_PATH:/manage-7x9k2p} {$ADMIN_BASE_PATH:/manage-7x9k2p}/* handle @platform_admin { respond 404 } # 生产后台页面使用构建时配置的隐藏入口,旧 /admin 入口直接返回 404。 @legacy_admin path /admin /admin/* handle @legacy_admin { respond 404 } # 其余流量返回主站/分销前台前端静态资源。 handle { root * /srv/dist try_files {path} /index.html file_server } } # 主站与过渡子域名共享同一套配置:域名迁移期间新旧域名同时可访问, # 避免 DNS 缓存未生效导致部分用户打不开。迁移完成后可移除 h5.{$CADDY_DOMAIN}。 {$CADDY_DOMAIN}, h5.{$CADDY_DOMAIN} { # 主站后台隐藏入口只在本域名提供静态资源;分销站点域名由 storefront 片段统一 404。 @main_admin path {$ADMIN_BASE_PATH:/manage-7x9k2p} {$ADMIN_BASE_PATH:/manage-7x9k2p}/* handle @main_admin { root * /srv/dist try_files {path} /index.html file_server } import storefront } # 分销管理后台使用独立 React + Ant Design 静态资源,API 与主站复用 backend。 distribution.{$CADDY_DOMAIN} { encode zstd gzip import public_api handle { root * /srv/distribution-admin try_files {path} /index.html file_server } } # 选号网(hfb_show):仅当 CADDY_SHOW_DOMAIN 有值时由部署脚本启用 conf.d/show.caddy。 # 未配置时 conf.d 为空,不影响主站。 import /etc/caddy/conf.d/*.caddy # Beszel 自带登录与权限控制;单独子域避免与业务站点的 CSP、路由相互影响。 monitor.{$CADDY_DOMAIN} { encode zstd gzip request_body { max_size 10MB } reverse_proxy beszel:8090 { transport http { read_timeout 360s } } } # gitea 自托管代码库 gitea.hao858.com { reverse_proxy gitea:3000 } # 分销站点动态域名入口: # 支持任意二级域名及分销商独立域名,首次访问时通过 on_demand_tls 触发后端白名单校验并自动签发 SSL 证书。 https:// { tls { on_demand } import storefront }