Primary role#
This defaults to web, but if you have no web role, you can change this:
primary_role: workersEverything config/deploy.yml can contain — destinations, roles, hooks, and every root-level setting.
Configuration is read from the config/deploy.yml.
When running commands, you can specify a destination with the -d flag, e.g., dash deploy -d staging.
In this case, the configuration will also be read from config/deploy.staging.yml and merged with the base configuration.
Kamal will not accept unrecognized keys in the configuration file.
However, you might want to declare a configuration block using YAML anchors and aliases to avoid repetition.
You can prefix a configuration section with x- to indicate that it is an extension. Kamal will ignore the extension and not raise an error.
This is a required value. It is used as the container name prefix.
service: myappThe image will be pushed to the configured registry.
image: my-imageAdditional labels to add to the container:
labels:
my-label: my-valueAdditional volumes to mount into the container:
volumes:
- /path/on/host:/path/in/container:roThe Docker registry configuration, see dash docs registry:
registry:
...The servers to deploy to, optionally with custom roles, see dash docs servers:
servers:
...See dash docs env:
env:
...Used for asset bridging across deployments, default to nil.
If there are changes to CSS or JS files, we may get requests for the old versions on the new container, and vice versa.
To avoid 404s, we can specify an asset path. Kamal will replace that path in the container with a mapped volume containing both sets of files. This requires that file names change when the contents change (e.g., by including a hash of the contents in the name).
To configure this, set the path to the assets.
You can also specify mount options after a colon, such as ro for read-only or z/Z for SELinux labels
asset_path: /path/to/assetsPath to hooks, defaults to .dash/hooks (.kamal/hooks is still read when only that exists). See https://dash.zoolutions.llc/docs/hooks for every hook, when it fires, and its environment:
hooks_path: /user_home/kamal/hooksHook output visibility. Can be set globally or per-hook. CLI flags (-v, -q) override these settings.
:quiet - hook output is hidden:verbose - hook output is shownWith no setting, hook output follows CLI verbosity flags.
Note: Failed hooks always show output in the error message regardless of setting.
Global setting for all hooks:
hooks_output: :verboseOr per-hook settings:
hooks_output:
pre-deploy: :verbose
pre-build: :quietPath to secrets, defaults to .dash/secrets (.kamal/secrets is still read when only that exists). dash looks for <secrets_path>-common first and then <secrets_path>. When using destinations, it instead looks for <secrets_path>-common first and then <secrets_path>.<destination>. Later files override earlier ones.
secrets_path: /user_home/kamal/secretsA directory relative to the app root to find error pages for the proxy to serve. Name each page after the HTTP status code it serves, e.g. 404.html, 500.html, 502.html, 503.html, and 504.html.
error_pages_path: publicWhether deployments require a destination to be specified, defaults to false:
require_destination: trueThis defaults to web, but if you have no web role, you can change this:
primary_role: workersWhether roles with no servers are allowed. Defaults to false:
allow_empty_roles: falseHow many old containers we retain per role, and how many images we retain, defaults to 5:
retain_containers: 3The minimum version of Kamal required to deploy this configuration, defaults to nil:
minimum_version: 1.3.0Seconds to wait for a container to boot after it is running, default 7.
This only applies to containers that do not run a proxy or specify a healthcheck:
readiness_delay: 4How long to wait for a container to become ready, default 30:
deploy_timeout: 10How long to wait for a container to drain, default 30:
drain_timeout: 10How long to wait for a container to stop after SIGTERM, default is the drain_timeout for non-proxied roles and 10s (Docker default) for proxied roles. Can be overridden per role:
stop_timeout: 30Where dash keeps its runtime files on each host — per-app env and assets, the proxy's boot files and apps-config mount, loadbalancer service claims, deploy locks, and the audit log. Resolved against the SSH user's home, default .dash. A host still holding the pre-3.4 .kamal directory is renamed to .dash in place the next time dash takes a lock on it; nothing is rebooted.
The key is accepted but not yet honoured — the path is currently always .dash. Tracked separately from the stage-3 rename.
run_directory: .dashSee dash docs ssh:
ssh:
...See dash docs builder:
builder:
...Additional services to run in Docker, see dash docs accessory:
accessories:
...Configuration for dash-proxy, see dash docs proxy:
proxy:
...See dash docs sshkit:
sshkit:
...See dash docs boot:
boot:
...Docker logging configuration, see dash docs logging:
logging:
...Configure output loggers (OTel, file), see dash docs output:
output:
...Advice printed under the deploy timing table, see dash docs report:
report:
...Alias configuration, see dash docs alias:
aliases:
...lib/dash/configuration/docs/configuration.yml — the same reference dash docs prints in your terminal, so this page always matches your installed version.