Subdomain-only gateway routing; drop path prefixes
Collapse the two proxy shapes (path_prefix + host) to a single checkbox: a service is either port-only, or exposed at <service-name>.<gateway.domain>. Path routes and their prefix-stripping foot-guns are gone; the subdomain is always the service name (rename the service to change it). - Schema: CaddySpec is just `enable` (presence = expose). service_proxy_targets returns (expose, port, base_url); Deployment carries `subdomain` (was proxy_path/proxy_host). Registry/deploy/mesh/CLI updated in lockstep. - Generator: compute_routes emits one host route per exposed service/frontend (address = name). acme mode = one *.<domain> site with a reverse_proxy matcher per service + a file_server matcher per frontend; the :<port> site redirects to the dashboard. off mode = a HTTP control plane on :<port> (dashboard at / + /api → castle-api); other services are port-only. - Dashboard/API: castle-app and castle-api are ordinary subdomains. The dashboard derives the API base at runtime (castle-api.<domain> on a subdomain, else /api) and calls it cross-origin — castle-api already allows CORS *. Frontends build with VITE_BASE=/ (served at their subdomain root). - CLI: `service create` drops --path/--host; --no-proxy makes it port-only. - Docs/tests reworked for the model; docs use generic placeholders only (no personal host/domain/IP details).
This commit is contained in:
@@ -1,4 +1,22 @@
|
||||
const BASE_URL = import.meta.env.VITE_API_BASE_URL ?? "/api"
|
||||
// Resolve the castle-api base URL. The gateway serves each service at its own
|
||||
// subdomain (<name>.<domain>), so when the dashboard runs at castle-app.<domain>
|
||||
// the API lives at castle-api.<domain> — a cross-origin call (castle-api allows
|
||||
// CORS *). When served at a bare host (dev, or the off-mode :9000 gateway), the
|
||||
// API is reachable same-origin at /api.
|
||||
function resolveApiBase(): string {
|
||||
const configured = import.meta.env.VITE_API_BASE_URL
|
||||
if (configured) return configured
|
||||
if (typeof window !== "undefined") {
|
||||
const { protocol, hostname } = window.location
|
||||
const labels = hostname.split(".")
|
||||
if (labels.length > 2) {
|
||||
return `${protocol}//castle-api.${labels.slice(1).join(".")}`
|
||||
}
|
||||
}
|
||||
return "/api"
|
||||
}
|
||||
|
||||
const BASE_URL = resolveApiBase()
|
||||
|
||||
class ApiError extends Error {
|
||||
status: number
|
||||
|
||||
Reference in New Issue
Block a user