Deploy Hooks System
Relevant source files
The following files were used as context for generating this wiki page:
The Deploy Hooks System in Kamal is an extensibility framework that allows developers to execute local scripts at specific lifecycle events during the deployment process. These hooks are executed on the local machine (the "deployer") and can be used for notifications, audit logging, or integration with external services.
The system supports a variety of lifecycle events including connection, building, deployment, and rollback. Hooks are defined as executable files located within a specific directory in the project structure, traditionally .kamal/hooks.
Sources: lib/kamal/cli/base.rb:69-80, lib/kamal/configuration.rb:271-273, test/integration/main_test.rb:10-12
Architecture and Execution Flow
The hook system is integrated into the Kamal::Cli::Base class, which provides a run_hook method. When a command reaches a lifecycle event, it triggers this method. The system checks for the existence of a corresponding executable file in the configured hooks_path.
If a hook exists and hooks are not explicitly skipped via the --skip-hooks CLI option, Kamal prepares a set of environment variables containing metadata about the current operation. The hook is then executed locally using SSHKit::DSL#run_locally.
Hook Execution Sequence
The following diagram illustrates the sequence of operations when a hook is triggered during a deployment.
Lifecycle Events
Hooks are triggered at various stages of the deployment workflow. The main CLI entry points (deploy, redeploy, setup, rollback) are the primary users of the hook system.
| Hook Name | Trigger Point | Description |
|---|---|---|
pre-connect | Before first SSH connection | Used for pre-flight checks or dynamic secret retrieval. |
pre-build | Before image building | Triggers before Docker build operations. |
pre-deploy | Before container boot | Executed once the deploy lock is acquired but before new containers are started. |
pre-app-boot | Before app containers boot | Specific to the application container lifecycle. |
post-app-boot | After app containers boot | Triggered once the application containers are reported healthy. |
post-deploy | After all deploy tasks | Final hook executed after containers are booted and old ones pruned. |
Sources: lib/kamal/cli/main.rb:39-61, lib/kamal/cli/base.rb:227-230, test/integration/main_test.rb:10-12
Environment Variables
When a hook is executed, Kamal populates the local environment with metadata to provide context to the script. This allows scripts to be dynamic based on the service, version, or performer.
- KAMAL_SERVICE: The name of the service being deployed.
- KAMAL_VERSION: The full version/git SHA being deployed.
- KAMAL_HOSTS: A comma-separated list of target hosts.
- KAMAL_ROLES: A comma-separated list of roles involved.
- KAMAL_COMMAND: The main command being run (e.g.,
deploy). - KAMAL_PERFORMER: The user performing the action (often derived from git config).
- KAMAL_RECORDED_AT: The timestamp of the operation.
Sources: lib/kamal/cli/base.rb:73-79, test/integration/main_test.rb:142-150
Configuration
The behavior of the hook system is controlled through the deploy.yml configuration and CLI flags.
Directory Mapping
By default, Kamal looks for hooks in .kamal/hooks. This can be overridden in the configuration file:
hooks_path: custom/hooks/dir
Sources: lib/kamal/configuration.rb:271-273
Output Control
Developers can control the verbosity of hook output. The hooks_output setting supports global or per-hook configuration, with levels :quiet (minimal logging) or :verbose (detailed output).
hooks_output:
pre-deploy: verbose
post-deploy: quiet
Sources: lib/kamal/configuration.rb:287-293, lib/kamal/cli/base.rb:82-89
CLI Options
The hook system respects several global CLI options defined in the base CLI class:
| Option | Type | Description |
|---|---|---|
--skip-hooks | Boolean | Disables the execution of all hooks for the current command. |
--verbose | Boolean | Forces hook output to be detailed (debug level). |
--quiet | Boolean | Silences hook output (error level only). |
Sources: lib/kamal/cli/base.rb:27-30, lib/kamal/cli/base.rb:43
Error Handling
Hooks are treated as critical parts of the deployment process. If a hook script returns a non-zero exit status, the Kamal::Cli::HookError is raised, typically causing the deployment to halt. The execution is wrapped in a HOOK_MUTEX to ensure that process-global state (like SSHKit verbosity) is handled safely when multiple threads might attempt to fire hooks simultaneously.
Sources: lib/kamal/cli/base.rb:21, lib/kamal/cli/base.rb:91-95
Conclusion
The Deploy Hooks System provides a robust mechanism for local task automation during the Kamal lifecycle. By utilizing standardized environment variables and flexible configuration for output and location, it allows teams to integrate Kamal into wider CI/CD and monitoring ecosystems without modifying the core tool.
Sources: lib/kamal/cli/main.rb:206-210, test/cli/main_test.rb:47-52