RPC API Contract
Relevant source files
The following files were used as context for generating this wiki page:
The kamal-proxy project utilizes a Remote Procedure Call (RPC) mechanism to facilitate communication between the Command Line Interface (CLI) and the long-running proxy server. This communication occurs over a Unix domain socket, typically named kamal-proxy.sock, using Go's standard net/rpc library. The RPC interface is the primary control plane for managing services, deployments, traffic rollouts, and cache operations.
The contract is strictly defined by the CommandHandler struct and the registered service name "kamal-proxy". This naming is considered "load-bearing," and renaming the module, binary, RPC service, or socket is prohibited to ensure compatibility between client calls and server registration.
Sources: CLAUDE.md:12-22, internal/server/commands.go:121
System Architecture
The RPC architecture follows a Layered approach where the CLI acts as the client (Layer 2) and the RPC server resides within the internal/server package (Layer 1).
RPC Lifecycle and Connectivity
- Server Initialization: During startup, the server creates a
CommandHandler, registers it under the name "kamal-proxy", and begins listening on a Unix domain socket. - Connection Handling: The server runs an infinite loop to accept connections, spawning a new goroutine for each client session via
rpc.ServeConn. - Client Invocation: The CLI uses the
withRPCClientutility to dial the Unix socket and execute specific methods.
The RPC server manages concurrent requests by dispatching method calls to the underlying Router or Server instances.
Sources: internal/server/commands.go:115-145, internal/cmd/util.go:36-43, CLAUDE.md:46-51
API Methods and Endpoints
The CommandHandler exposes several methods that define the API contract. Most methods return a boolean indicating success or an error if the operation fails.
Core Service Management
| Method | Argument Type | Reply Type | Description |
|---|---|---|---|
Deploy | DeployArgs | *bool | Deploys or updates a service with targets and options. |
Pause | PauseArgs | *bool | Pauses a service with a specific drain and pause timeout. |
Resume | ResumeArgs | *bool | Resumes a previously paused service. |
Stop | StopArgs | *bool | Stops a service and displays an optional message. |
Remove | RemoveArgs | *bool | Removes a service from the proxy configuration. |
List | bool | *ListResponse | Retrieves a map of all active services and their targets. |
Drain | DrainArgs | *bool | Flushes routing state to disk and prepares the server for exit. |
Sources: internal/server/commands.go:147-194
Traffic Rollout and Cache Control
The RPC API also manages canary deployments and the response cache.
Sources: internal/server/commands.go:196-224
Data Structures (The Argument Contract)
The RPC contract relies on several key argument structs that encapsulate complex configurations.
DeployArgs
This is the most significant structure, used to configure service behavior, TLS, and target pool options.
- Service: String identifier for the service.
- TargetURLs / ReaderURLs: Slices of strings defining host:port targets (with optional weights).
- ServiceOptions: Complex struct containing TLS settings, path prefixes, basic auth, and rate limiting.
- TargetOptions: Configures health checks, timeouts, and buffering.
Sources: internal/server/commands.go:30-37, internal/server/service.go:82-147
Deployment and Service Options
The ServiceOptions struct includes JSON tags for persistence, as the proxy saves state to disk.
type ServiceOptions struct {
Hosts []string `json:"hosts"`
PathPrefixes []string `json:"path_prefixes"`
TLSEnabled bool `json:"tls_enabled"`
TLSRedirect bool `json:"tls_redirect"`
BasicAuth string `json:"basic_auth,omitempty"`
RateLimit float64 `json:"rate_limit,omitempty"`
ExcludeMetricsPaths []string `json:"exclude_metrics_paths"`
}
Note: BasicAuth is hashed on the CLI side before being sent over the RPC socket to ensure plaintext credentials never cross the interface.
Sources: internal/server/service.go:82-147, internal/cmd/deploy.go:148-154
Dynamic Domains and Diagnostics
The RPC API provides specialized endpoints for inspecting and refreshing dynamic TLS domains when the proxy is running with ACME features enabled.
DomainsStatusResponse
This response provides a comprehensive view of the dynamic domain manager's state.
| Field | Type | Description |
|---|---|---|
Services | map[string]DomainsServiceStatus | Domains organized by service, including certification status. |
QueueLength | int | Number of domains waiting for issuance. |
Quarantine | map[string]QuarantineStatus | Domains blocked due to repeated issuance failures. |
Certificates | int | Count of total managed certificates. |
Sources: internal/server/commands.go:94-106, internal/cmd/domains.go:57-78
Method: DomainsRefresh
The DomainsRefresh method allows the CLI to trigger an immediate re-poll of all dynamic domain sources. It returns the count of domain sources for which a refresh was requested.
Sources: internal/server/commands.go:242-250, internal/cmd/domains.go:121-137
Conclusion
The RPC API Contract in kamal-proxy serves as the robust backbone for all administrative operations. By utilizing Go's net/rpc over Unix sockets, it provides a high-performance, type-safe interface that decouples the CLI's command execution from the server's traffic handling logic. The strict naming conventions and structured argument types ensure that service configurations remain consistent between deployments and across server restarts.