Layer Cake Architecture
Relevant source files
The following files were used as context for generating this wiki page:
Kamal follows a "Layer Cake Architecture" designed to decouple user-facing CLI commands from the underlying logic of configuration parsing, command construction, and remote execution. This structured approach allows the tool to manage complex deployment workflows by delegating responsibilities across six distinct tiers, ranging from high-level Thor commands to low-level SSH execution.
The architecture ensures that the system's mental model remains consistent: user input flows through a singleton commander that resolves targets, which then utilizes specific builders to generate Docker commands executed over SSH.
Sources: CLAUDE.md:76-83, CLAUDE.md:85-87
Architectural Layers
The system is organized into six functional layers (Layer 0 through Layer 5). Each layer serves a specific purpose in the deployment lifecycle.
| Layer | Component | Responsibility | Relevant Files |
|---|---|---|---|
| Layer 5 | bin/kamal | Entry point for the executable. | bin/kamal, bin/dash |
| Layer 4 | Kamal::Cli::* | Thor-based CLI commands and lifecycle hooks. | lib/kamal/cli/ |
| Layer 3 | Kamal::Commander | Singleton manager for target resolution and coordination. | lib/kamal/commander.rb |
| Layer 2 | Kamal::Commands::* | Docker command builders for various services. | lib/kamal/commands/ |
| Layer 1 | Kamal::Configuration | Parsing deploy.yml into objects and validation. | lib/kamal/configuration.rb |
| Layer 0 | SSHKit | Remote execution of generated commands. | External Dependency |
Sources: CLAUDE.md:76-83
Layered Data Flow Diagram
The following diagram illustrates how a user request traverses the architecture to perform a deployment action.
The diagram shows the top-down flow from the command line entry point to the final execution on remote servers.
Sources: CLAUDE.md:76-83, lib/kamal/cli/main.rb:1-10, lib/kamal/configuration.rb:10-25
Layer 1: Configuration and Validation
At the base of the logic (above raw execution) sits the Configuration layer. It is responsible for loading deploy.yml files, merging destination-specific overrides, and validating the resulting environment.
Key Logic and Validation
The configuration layer performs critical safety checks before any remote connections are established. It resolves secrets using Kamal::Secrets and validates the system state.
- Secret Validation: The
validate_secrets!method ensures all required credentials (registry, builder, and role-specific secrets) are present early in the process to prevent mid-deploy failures. - Safety Checks: The system ensures valid service names, minimum Kamal versions, and proper readiness gate configurations for unproxied roles.
Sources: lib/kamal/configuration.rb:88-109, lib/kamal/configuration.rb:252-263
# Example of L1 validation logic
def validate_secrets!(include_accessories: false)
registry.username
registry.password
builder.secrets
# ... roles and accessories validation
true
end
Sources: lib/kamal/configuration.rb:88-109
Layer 2 & Layer 3: Command Construction and Coordination
Layer 3 (Kamal::Commander) acts as the central coordinator, while Layer 2 (Kamal::Commands) provides the specialized builders for Docker operations.
Coordination (Layer 3)
The Commander manages the scope of the deployment, including target host resolution and role filtering. It uses the parallel_roles? flag to determine if commands should iterate role-first or host-first.
Sources: lib/kamal/configuration.rb:142-145, test/cli/main_test.rb:390-398
Command Generation (Layer 2)
Layer 2 components, such as Kamal::Commands::Builder::Base, translate configuration objects into specific shell commands. These components leverage Kamal::Utils for shell escaping and argument formatting.
Sources: lib/kamal/commands/builder/base.rb:12-25, lib/kamal/utils.rb:9-25
The sequence shows how high-level CLI requests are decomposed into generated strings before being sent to the execution layer.
Sources: lib/kamal/cli/main.rb:24-30, lib/kamal/commands/builder/base.rb:17-27
Layer 4: CLI lifecycle and Hooks
The CLI layer (Kamal::Cli::Main) defines the user-facing interface and orchestrates high-level workflows like setup, deploy, and rollback. It is also responsible for executing lifecycle hooks (pre-deploy, post-deploy).
Deployment Workflow
The standard deploy command demonstrates the multi-layered interaction:
- Print Banner: Extracts high-level info from Layer 1.
- Validate: Calls Layer 1 secret validation.
- Build: Invokes Layer 2 builder via Layer 4 subcommand.
- Locking: Uses Layer 4
modify(lock: true)to ensure exclusive access. - Hooks: Runs configured scripts from the
.kamal/hooksdirectory.
Sources: lib/kamal/cli/main.rb:21-62, test/cli/main_test.rb:5-20
CLI Options and Parameters
The CLI uses Thor to define options that influence the configuration and command generation layers.
| Option | Type | Default | Description |
|---|---|---|---|
--skip_push | Boolean | false | Skips image build and push, pulling instead. |
--no_cache | Boolean | false | Disables Docker build cache. |
--confirmed | Boolean | false | Proceeds without confirmation prompts. |
--lock-wait | Boolean | false | Waits for an existing deploy lock to clear. |
Sources: lib/kamal/cli/main.rb:16-20, test/cli/main_test.rb:140-155
Kamal's Layer Cake Architecture provides a robust framework for managing containerized deployments by separating configuration, coordination, generation, and execution. This separation allows for complex features like multi-arch hybrid builds and readiness-gated deployments to be implemented cleanly within their respective layers.