Deployments & Rollouts
Relevant source files
The following files were used as context for generating this wiki page:
Deployments and rollouts in kamal-proxy provide a mechanism to manage application lifecycle, specifically how traffic is transitioned from old targets to new ones. The system supports full service deployments, where a service is updated with new target URLs, and gradual rollouts (canary releases), where a percentage of traffic is directed to a new set of targets while the majority remains on the active set.
The architecture utilizes a Go-based server that maintains state across restarts, communicating with a CLI via RPC over a Unix socket. Services are modeled as logical entities that can have both an "active" and a "rollout" load balancer simultaneously. Sources: internal/server/service.go:210-220, internal/server/commands.go:121-125
Service Deployment Architecture
A deployment involves defining a service name, target URLs for read/write traffic, and various operational options. When a deployment occurs, the system creates a new load balancer, waits for it to become healthy (unless forced), and then replaces the existing active load balancer for that service.
Deployment Flow
The following diagram illustrates the sequence of events when a user initiates a deployment via the CLI.
Key Deployment Components
| Component | Description | Source |
|---|---|---|
DeployArgs | Data structure containing service name, target URLs, and service/target options. | internal/server/commands.go:25-32 |
ServiceOptions | Configuration for TLS, health checks, path prefixes, and basic auth. | internal/server/service.go:82-171 |
TargetOptions | Timeouts, connection limits, and header forwarding rules for upstream targets. | internal/server/target.go (referenced in service.go:212) |
DeploymentOptions | Timeouts for the deployment process and drain duration for old connections. | internal/server/service.go:76-80 |
Rollout Management
Rollouts allow for gradual traffic shifting. A "Rollout" is distinct from an "Active" deployment in that it introduces a second set of targets that only receive a portion of the traffic based on a defined percentage or an allowlist of specific cookies.
Rollout Traffic Control
The RolloutController determines if a specific request should be routed to the rollout group. It uses the kamal-rollout cookie value to perform a deterministic split.
Traffic Split Logic
The traffic split is implemented using an FNV-32a hash of the cookie value. This ensures that a client with a consistent cookie always gets routed to the same pool (active or rollout) regardless of how many requests they make, provided the percentage split remains the same.
Sources: internal/server/rollout_controller.go:44-52
Target Lists and Load Balancing
Both deployments and rollouts use a TargetList to manage upstream hosts. These targets are grouped into two pools:
- Write Targets: The primary application instances.
- Read Targets: Optional read-only replicas.
Deployment State Persistence
The system persists the routing state to a JSON file (typically kamal-proxy.state). This allows the proxy to resume routing to existing targets immediately upon restart without waiting for a new deployment command.
Sources: internal/server/router.go:136-168, internal/server/service.go:406-434
Draining and Connection Management
When a new deployment replaces an old one, the system does not immediately terminate old connections. Instead, it "drains" them.
- Stop New Requests: The old load balancer is disposed of so it no longer receives new requests.
- Drain Timeout: The system waits for a configurable
DrainTimeoutfor existing in-flight requests to complete. - Active Connections: Once the timeout expires, any remaining hijacked or long-lived connections are forcefully closed.
Sources: internal/server/router.go:384-387, internal/server/service.go:503-516, internal/server/commands.go:132-141
Summary of RPC Deployment Commands
| Command | Purpose | Source |
|---|---|---|
Deploy | Updates the primary target pool for a service. | internal/server/commands.go:121-123 |
RolloutDeploy | Deploys a set of targets specifically for the rollout slot. | internal/server/commands.go:167-169 |
RolloutSet | Configures the traffic percentage and allowlist for an existing rollout. | internal/server/commands.go:171-173 |
RolloutStop | Terminates the rollout and removes the rollout targets. | internal/server/commands.go:175-177 |
Remove | Completely removes a service and its targets from the proxy. | internal/server/commands.go:157-159 |
Deployments and rollouts are the core mechanisms kamal-proxy uses to ensure zero-downtime updates and safe testing of new application versions in production environments. By separating "Active" and "Rollout" slots, the system provides granular control over traffic shaping during release cycles. Sources: internal/server/router.go:343-415, internal/server/rollout_controller.go:10-15