Configuration Hierarchy
CAP provides a powerful and flexible configuration system that allows you to define a base configuration and then override it for specific instances or environments. Understanding this hierarchy is key to managing your application deployments efficiently.
Merge order
CAP merges configurations from different levels in a specific order. Settings from later levels take precedence over and override settings from earlier levels.
The merge order is as follows:
- Top-Level
config.cap.yaml: The default settings in your application'sconfig.cap.yamlthat are not nested underinstancesorenvironments. - Global
environmentsBlock: Settings from the top-levelenvironmentsblock that match the current deployment environment. This allows you to define global settings for allproductionorstagingdeployments, regardless of the instance. - Instance-Level Config: Settings defined within a specific instance in your
config.cap.yaml(e.g., underinstances.nl). - Instance-Specific
environmentsBlock: Settings defined within an environment nested inside an instance (e.g.,instances.nl.environments.production). This is the final and most specific level of configuration.
The merging is recursive for objects and dictionaries. For example, if you define http.replicas at the top level and http.port at the environment level, the final http block will contain both replicas and port. However, if you define the same property at multiple levels, the value from the most specific level is used.
Lists written as plain sequences, such as whitelist and connections, are appended rather than replaced:
a list at a more specific level extends the one above it instead of overriding it. A value written
lower down therefore cannot remove an entry from a level above, and an empty list has no effect. See
IP whitelist.
Example
Let's walk through a complete example to see how the hierarchy works.
config.cap.yaml
# 1. Top-level defaults
http:
replicas: 1
port: 8080
variables:
APP_NAME: My Awesome App
# 2. Global environments block
environments:
production:
# This applies to ALL production environments
variables:
APP_DEBUG: "false"
LOG_LEVEL: error
# 3. Instances block
instances:
nl:
http:
hostname: my-app.nl
replicas: 2 # Overrides top-level
# 4. Instance-specific environments
environments:
staging:
# inherits nl instance config
production:
http:
hostname: www.my-app.nl # Overrides instance-level hostname
replicas: 10 # Overrides instance-level replicas
variables:
APP_LOCALE: nl_NL # Merged with global production environment
be:
http:
hostname: my-app.be
# Inherits top-level replicas: 1
environments:
production:
http:
hostname: www.my-app.be
# Also inherits top-level replicas: 1
# Merged with global production environment
Result for the nl instance
CAP merges: Top-Level -> Global production -> Instance (nl) -> Instance production.
# Final merged config for nl-production
http:
hostname: www.my-app.nl # From instance 'nl' production environment
replicas: 10 # From instance 'nl' production environment (most specific)
port: 8080 # From top-level
variables:
APP_NAME: My Awesome App # From top-level
APP_DEBUG: "false" # From global production environment
LOG_LEVEL: error # From global production environment
APP_LOCALE: nl_NL # From instance 'nl' production environment
Result for the be instance
CAP merges: Top-Level -> Global production -> Instance (be) -> Instance production.
# Final merged config for be-production
http:
hostname: www.my-app.be # From instance 'be' production environment
replicas: 1 # From top-level (instance 'be' did not override it)
port: 8080 # From top-level
variables:
APP_NAME: My Awesome App # From top-level
APP_DEBUG: "false" # From global production environment
LOG_LEVEL: error # From global production environment