Dynamic Domains & Redirects
Relevant source files
The following files were used as context for generating this wiki page:
Dynamic Domains and Redirects are key features of kamal-proxy that allow for runtime-editable configurations without requiring a proxy restart or redeployment. These systems use a polling mechanism to fetch configuration data from external or internal application endpoints, enabling features like multi-tenancy TLS and host-scoped path redirects.
The subsystem is divided into two primary managers: the DynamicDomainManager, which handles automated TLS certificate issuance for dynamically discovered hostnames, and the DynamicRedirectManager, which manages runtime-editable redirect rules and path policies. Both systems share a similar architecture involving background pollers, state persistence, and atomic updates to the proxy's routing logic.
Sources: internal/server/dynamic_domains.go:61-75, internal/server/dynamic_redirects.go:40-52, internal/server/redirect_map.go:1-6
Dynamic Domain Management
The DynamicDomainManager coordinates the discovery of new hostnames and the subsequent automated issuance of TLS certificates. It integrates with SANCertManager to handle ACME certificate lifecycles for domains retrieved via a "domain source" endpoint.
Architecture and Data Flow
The system employs a sourcePoller for each service configured with a TLSDomainsSource. These pollers fetch a JSON list of domains at regular intervals. When new domains are identified, the manager triggers a pre-flight probe to ensure the domain correctly routes to the proxy before attempting ACME issuance.
The following diagram illustrates the lifecycle of a dynamic domain from discovery to certification:
The flow shows how the proxy validates reachability via a pre-flight probe before involving the ACME issuer.
Sources: internal/server/dynamic_domains.go:88-105, internal/server/dynamic_domains.go:277-300
Pre-flight Probing
To prevent burning ACME rate limits or orders on unreachable domains, the proxy performs a self-probe. It generates a unique preflightNonce and attempts to fetch it via HTTP from the new domain.
- Endpoint:
http://<domain>/.kamal-proxy/preflight/<nonce> - Security: The probe client never follows redirects to prevent Server-Side Request Forgery (SSRF).
Sources: internal/server/dynamic_domains.go:343-370, internal/server/dynamic_domains_test.go:207-220
Dynamic Redirect Management
The DynamicRedirectManager provides host-scoped, runtime-editable redirect rules. Unlike static rules defined at deploy time, these are polled from the application, allowing for thousands of tenant-specific redirects.
Redirect Map Structure
The redirect map is host-scoped and supports three primary behaviors:
- Host-level Redirects: Using
redirect_toto map an entire host to another URL (e.g.,old.comtonew.com). - Path Rules: RE2-anchored regex patterns for path-level redirection with capture group expansion.
- Trailing Slash Policy: A "strip" policy to automatically redirect
/path/to/path.
This class diagram shows the hierarchical relationship between host entries and their specific redirect configurations.
Sources: internal/server/redirect_map.go:78-95, internal/server/redirect_map.go:121-125
Data Payload Schema
Applications must serve a JSON object with a hosts key. If the hosts key is missing, the proxy treats it as an error and keeps the previous map serving.
| Field | Type | Description |
|---|---|---|
redirect_to | String | Absolute http(s) URL for host-level redirection. |
status | Integer | HTTP status code (301, 302, 303, 307, 308). Default is 301. |
preserve_path | Boolean | If true, appends request path and query to redirect_to. |
trailing_slash | String | Set to "strip" to remove trailing slashes. |
paths | Array | List of objects with from (regex) and to (replacement). |
Sources: internal/server/redirect_map.go:48-67, internal/server/redirect_map.go:176-200
Polling and Persistence
Both managers share a common polling infrastructure. Configuration can be fetched via an absolute URL or a path relative to the service's own targets.
Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
TLSDomainsInterval | Duration | 5m | Frequency for polling domain sources. |
RedirectsInterval | Duration | 5m | Frequency for polling redirect sources. |
StatePath | String | N/A | Path to persist last-known state across restarts. |
SourceToken | String | N/A | Bearer token sent in Authorization header during polls. |
Sources: internal/server/dynamic_domains.go:18-21, internal/server/dynamic_redirects.go:14-17, internal/server/dynamic_redirects.go:27-38
State Persistence
States are persisted to disk to ensure the proxy can serve domains and redirects immediately upon reboot, even if the application backend is temporarily unreachable.
- Domains: Persists the domain list and ETag.
- Redirects: Persists the raw host configuration map, ETag, and fetch timestamp.
Sources: internal/server/dynamic_domains.go:153-157, internal/server/dynamic_redirects.go:119-123
CLI and API Interaction
The proxy provides internal RPC endpoints and CLI commands to inspect and manage dynamic state.
CLI Commands
The domains command allows operators to inspect the current state of dynamic TLS.
kamal-proxy domains list: Lists services, their domains, and certification/quarantine status.kamal-proxy domains stats: Shows aggregate counters for dynamic domains and certificates.kamal-proxy domains refresh: Triggers an immediate re-poll of all domain sources.
Sources: internal/cmd/domains.go:25-33, internal/cmd/domains.go:58-85
Refresh Endpoint
A special namespace /.kamal-proxy/ is reserved for proxy management. If a RefreshToken is configured, an external system can trigger a re-poll via an authorized POST request.
- Domains Refresh:
POST /.kamal-proxy/domains/refresh - Redirects Refresh:
POST /.kamal-proxy/redirects/refresh
Sources: internal/server/dynamic_domains_test.go:121-140, internal/server/dynamic_redirects_test.go:261-275
Conclusion
The Dynamic Domains & Redirects system provides kamal-proxy with the flexibility required for high-scale, multi-tenant environments. By delegating domain discovery and redirect rules to the application layer via polling, the proxy remains a lightweight but powerful routing engine that automatically handles TLS security and traffic shaping at runtime.