Config Inheritance (extends)
Runix supports config file inheritance via the extends field. This lets you share common configuration across environments while overriding specific values.
Usage
# base.yaml
defaults:
restart_policy: on-failure
max_restarts: 10
processes:
api:
runtime: go
entrypoint: ./cmd/api
env:
LOG_LEVEL: info
# runix.yaml (production override)
extends: ./base.yaml
defaults:
restart_policy: always
max_restarts: 50
processes:
api:
env:
LOG_LEVEL: warn
DATABASE_URL: postgres://prod-db:5432/myapp
Merge Behavior
The extends system performs a deep merge:
| Type | Merge Strategy |
|---|---|
| Scalars (strings, numbers, bools) | Child value overrides parent |
Maps (env, processes) | Merged — child keys override parent keys, parent keys are preserved |
Arrays (args, depends_on, tags) | Child array replaces parent array entirely |
defaults | Deep merged — child overrides specific fields |
Example Merge
Parent (base.yaml):
defaults:
restart_policy: on-failure
max_restarts: 10
processes:
api:
runtime: go
entrypoint: ./cmd/api
env:
PORT: "8080"
LOG_LEVEL: info
args: ["--verbose"]
Child (runix.yaml):
extends: ./base.yaml
processes:
api:
env:
LOG_LEVEL: debug
ENABLE_CACHE: "true"
args: ["--debug"]
Result (effective config):
defaults:
restart_policy: on-failure # from parent
max_restarts: 10 # from parent
processes:
api:
runtime: go # from parent
entrypoint: ./cmd/api # from parent
env:
PORT: "8080" # from parent
LOG_LEVEL: debug # overridden by child
ENABLE_CACHE: "true" # added by child
args: ["--debug"] # replaced by child (arrays don't merge)
Chain Depth
Config files can extend other files that extend further files. The chain depth is limited to prevent infinite recursion.
Validation
The merged config is validated after all extends are resolved. This means validation errors reference the final effective config, not individual files.
What's Next
- Configuration Reference — Full YAML schema
- Defaults — Default values and precedence
- Hot Reload — Live config changes