Accessories Configuration
Relevant source files
The following files were used as context for generating this wiki page:
Accessories in Kamal represent long-lived infrastructure services required by an application, such as databases (MySQL, PostgreSQL), caches (Redis), or search engines. Unlike the main application roles, accessories are managed as independent units with their own lifecycle, configuration, and host placement logic.
The configuration system handles the mapping of YAML definitions to Docker commands, manages environment variables, mounts volumes, and handles file uploads to remote hosts. Accessories can be pinned to specific hosts, roles, or identified via tags.
Sources: lib/kamal/configuration.rb:71, lib/kamal/configuration/accessory.rb:1-15, test/configuration/accessory_test.rb:8-50
Core Configuration Structure
Accessories are defined under the accessories key in the primary configuration file. Each accessory is identified by a unique name and contains specifications for its image, host placement, and runtime environment.
Host Resolution Logic
Kamal provides multiple ways to determine where an accessory should be deployed. The resolution follows a specific hierarchy:
- Direct Host(s): Explicitly defined via
hostorhosts. - Role-based: Inherits hosts from application roles using
roleorroles. - Tag-based: Matches hosts by tags defined in the server configuration using
tagortags.
Sources: lib/kamal/configuration/accessory.rb:41-43, lib/kamal/configuration/accessory.rb:194-220, test/configuration/accessory_test.rb:112-132
Configuration Parameters
| Parameter | Type | Description |
|---|---|---|
service | String | Optional override for the service name. Defaults to [app_name]-[accessory_name]. |
image | String | The Docker image to use (e.g., mysql:8.0). |
port | String/Integer | Port mapping. Can be a single port (3306) or mapping (3306:3306). |
env | Hash | Environment variables, split into clear and secret. |
files | Array/Hash | Local files to be uploaded and mounted into the container. |
directories | Array/Hash | Host directories to be created and mounted. |
volumes | Array | Standard Docker volume mappings. |
options | Hash | Additional Docker run options (CPU, memory, etc.). |
Sources: lib/kamal/configuration/accessory.rb:34-40, lib/kamal/configuration/accessory.rb:108-112, test/configuration/accessory_test.rb:14-40
Architecture and Data Flow
The configuration flow begins with the Kamal::Configuration class, which initializes Kamal::Configuration::Accessory objects for every entry in the YAML.
The diagram above shows how the YAML configuration is decomposed into specialized configuration objects before being used by the CLI to execute commands.
Sources: lib/kamal/configuration.rb:71-75, lib/kamal/configuration/accessory.rb:13-26
Lifecycle Management
The Kamal::Cli::Accessory class uses the configuration to perform lifecycle operations. During a boot operation, the system ensures directories exist, uploads files, generates environment files, and finally executes the Docker run command.
This sequence illustrates the preparation steps required before an accessory container is actually started on the target host.
Sources: lib/kamal/cli/accessory.rb:7-36, lib/kamal/cli/accessory.rb:45-56
Environment and Secret Management
Accessories use a dedicated environment system that supports ERB expansion for dynamic values. Secrets are typically stored in .kamal/secrets and injected into the accessory's environment file on the host.
- Storage: Environment files are stored in
.kamal/apps/[app]/env/accessories/[name].env. - Permissions: Secrets files are uploaded with
0600permissions. - Dynamic Files: Local files ending in
.erbare processed through ERB before upload, allowing them to reference environment variables or secrets.
Sources: lib/kamal/configuration/accessory.rb:73-82, lib/kamal/configuration/accessory.rb:133-150, test/configuration/accessory_test.rb:161-175
Volumes and Filesystem Mappings
The configuration supports three types of filesystem interactions:
- Files: Local files (like
my.cnf) are uploaded to the host path[service_name]/[remote_path]and then mounted into the container. - Directories: Host directories are created automatically (with optional mode/owner settings) and mounted.
- Volumes: Standard Docker volumes (including named volumes) can be passed directly.
Path Expansion Logic
For files and directories, Kamal calculates host paths relative to the user's home directory ($PWD) or uses absolute paths if provided. Remote host paths are prefixed with the accessory's service name to ensure isolation.
Sources: lib/kamal/configuration/accessory.rb:85-106, lib/kamal/configuration/accessory.rb:175-192, test/configuration/accessory_test.rb:216-240
Proxy Integration
Accessories can optionally run behind kamal-proxy by including a proxy block. This is useful for accessories providing a web interface (e.g., a monitoring dashboard).
Unlike application roles, accessory proxies:
- Do not load balance: Even if the primary role is multi-host, the accessory proxy routes to its own local container.
- Maintain Identity: Keep their own hostname, TLS configuration, and basic authentication settings.
Sources: lib/kamal/configuration/accessory.rb:123-131, test/configuration/accessory_test.rb:321-344
Summary
Accessories Configuration provides a robust framework for managing sidecar services alongside a main application. By abstracting host resolution, secret injection, and filesystem management, it allows developers to define complex infrastructure dependencies in a declarative manner. The system ensures that these services are isolated, correctly configured with secrets, and optionally integrated with the project's proxy layer.