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.
The 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.
Warning
For index-based arrays (like whitelist and connections), merges will override existing keys. We do not recommended merging these at this time.
Detailed 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
env:
APP_NAME: "My Awesome App"
# 2. Global environments block
environments:
production:
# This applies to ALL production environments
env:
APP_DEBUG: false
LOG_LEVEL: "error"
# 3. Instances block
instances:
nl:
hostname: "my-app.nl"
http:
replicas: 2 # Overrides top-level
# 4. Instance-specific environments
environments:
staging:
# inherits nl instance config
production:
hostname: "www.my-app.nl" # Overrides instance-level hostname
http:
replicas: 10 # Overrides instance-level replicas
env:
APP_LOCALE: "nl_NL" # Merged with global production env
be:
hostname: "my-app.be"
# Inherits top-level replicas: 1
environments:
production:
hostname: "www.my-app.be"
# Also inherits top-level replicas: 1
# Merged with global production env
Final Configuration for nl instance, production environment:
CAP merges: Top-Level -> Global production -> Instance (nl) -> Instance production.
# Final merged config for nl-production
http:
replicas: 10 # From instance 'nl' production env (most specific)
port: 8080 # From top-level
env:
APP_NAME: "My Awesome App" # From top-level
APP_DEBUG: false # From global production env
LOG_LEVEL: "error" # From global production env
APP_LOCALE: "nl_NL" # From instance 'nl' production env
hostname: "www.my-app.nl" # From instance 'nl' production env
Final Configuration for be instance, production environment:
CAP merges: Top-Level -> Global production -> Instance (be) -> Instance production.
# Final merged config for be-production
http:
replicas: 1 # From top-level (instance 'be' did not override it)
port: 8080 # From top-level
env:
APP_NAME: "My Awesome App" # From top-level
APP_DEBUG: false # From global production env
LOG_LEVEL: "error" # From global production env
hostname: "www.my-app.be" # From instance 'be' production env