# Xboard protocol fusion entrypoint.
#
# Caddy listens on a single public port and dispatches HTTP traffic to Octane
# while transparently upgrading WebSocket requests to the ws-server worker.
# This lets every external reverse proxy (nginx, Cloudflare, the user's own
# Caddy, ...) treat the panel as a single upstream and avoids exposing the
# 18076 WebSocket port directly.
{
	admin off
	auto_https off
	persist_config off
	log {
		output stdout
		format console
	}
	servers {
		trusted_proxies static 0.0.0.0/0 ::/0
	}
}

:{$CADDY_LISTEN_PORT:8002} {
	@ws path /ws
	reverse_proxy @ws 127.0.0.1:{$WS_PORT:18076}

	# Serve compiled frontend files directly instead of passing every asset
	# through Laravel/Octane. Hashed Vite assets are safe to cache forever.
	@immutable {
		path_regexp fingerprint `-[A-Za-z0-9_-]{8,}\.(?:js|css|woff2?|webp|png|jpe?g|svg|ico)$`
	}
	handle @immutable {
		root * /www/public
		header Cache-Control "public, max-age=31536000, immutable"
		file_server
	}

	@frontend_static path /theme/* /assets/* /storage/* /webp/*
	handle @frontend_static {
		root * /www/public
		header Cache-Control "public, max-age=300"
		file_server
	}

	handle {
		reverse_proxy 127.0.0.1:{$OCTANE_INTERNAL_PORT:18002} {
			header_up Host {host}
			# X-Forwarded-For is auto-appended with our remote_addr by Caddy.
			header_up X-Real-IP {remote_host}
		}
	}
}
