Skip to content

Configuration Reference

This is the complete reference for EMB configuration files.

EMB uses two types of configuration files:

  • .emb.yml - Project-level configuration at the monorepo root
  • Embfile.yml - Component-level configuration in each component folder

Required. Basic project information.

project:
name: my-project # Required: Project identifier
rootDir: . # Optional: Root directory (default: .)

Optional. List of plugins to load.

plugins:
- name: autodocker # Auto-discover components with Dockerfiles
- name: dotenv # Load .env files
config:
- .env
- .env.local
- name: embfiles # Load component Embfile.yml files

Built-in plugins:

  • autodocker - Auto-discovers components by looking for Dockerfiles
  • dotenv - Loads environment variables from .env files
  • embfiles - Loads component configuration from Embfile.yml files
  • vault - Fetches secrets from HashiCorp Vault (see Secrets Management)

Optional. Environment variables available to all processes.

env:
DOCKER_TAG: ${env:DOCKER_TAG:-latest}
NODE_ENV: development

Supports variable expansion with ${env:VAR_NAME:-default} syntax.

Optional. Variables for string expansion (not passed to subprocesses).

vars:
version: "1.0.0"
registry: "docker.io/myorg"

Optional. Default settings for builds and execution.

defaults:
docker:
tag: ${env:DOCKER_TAG} # Default image tag
target: development # Default build target
platform: linux/amd64 # Target platform (e.g., linux/amd64, linux/arm64)
buildArgs: # Default build arguments
NODE_ENV: development
labels: # Default labels
maintainer: team@example.com
publish: # Default publishing settings
registry: ghcr.io/myorg # Registry to push images to
tag: ${env:VERSION} # Tag override for publishing
kubernetes:
namespace: staging # Default namespace for K8s operations
selectorLabel: app.kubernetes.io/component # Label for pod selection

Kubernetes defaults:

OptionDescriptionDefault
namespaceDefault Kubernetes namespacedefault
selectorLabelLabel name used to find component podsapp.kubernetes.io/component

Optional. Inline component definitions (usually loaded via plugins).

components:
api:
rootDir: services/api
resources:
image:
type: docker/image
tasks:
test:
script: npm test

Optional. Project-level tasks.

tasks:
lint:
script: npm run lint
deploy:
pre: [lint, test]
script: ./scripts/deploy.sh

Optional. Project-level flavor configurations.

flavors:
production:
patches:
- op: replace
path: /env/NODE_ENV
value: production

Optional. Path to component root (auto-detected).

rootDir: services/api

Optional. Human-readable description.

description: REST API service

Optional. Resources this component provides.

resources:
image:
type: docker/image
publish: true # Mark as publishable (opt-in)
dependencies:
- base:image
params:
target: development
buildArgs:
NODE_ENV: development
labels:
version: "1.0.0"
context: .
dockerfile: Dockerfile

Common resource properties:

PropertyTypeDescription
typestringResource type (required): docker/image, file, op/file
publishbooleanMark resource as publishable for emb resources publish
dependenciesarrayList of resource IDs this depends on
paramsobjectType-specific parameters
rebuildTriggerobjectOverrides when a rebuild happens. Read by docker/image resources. See Rebuild triggers.

Resource types:

Builds a Docker image.

ParameterTypeDescription
imagestringImage name (without project prefix or tag). Defaults to component name.
tagstringImage tag. Defaults to defaults.docker.tag or latest.
targetstringBuild stage to target
platformstringTarget platform (e.g., linux/amd64, linux/arm64)
buildArgsobjectBuild arguments
labelsobjectImage labels
contextstringBuild context path
dockerfilestringDockerfile path
publish.registrystringRegistry to push to (overrides defaults.docker.publish.registry)
publish.tagstringTag for publishing (overrides defaults.docker.publish.tag)

By default a docker/image resource rebuilds when any git-tracked file under its build context has a newer mtime than the sentinel from the last successful build. That’s the right default for CI and production. In dev, where source is often bind-mounted into containers, it’s wasteful — the running container already sees the new code.

The rebuildTrigger field on the resource (or a flavor-level default under flavors.<flavor>.defaults.rebuildPolicy['docker/image']) lets you pick how the rebuild decision is made.

StrategyRebuilds whenTypical use
auto (default)any git-tracked file in the docker context has changedCI, production
alwaysevery invocationimages that fetch external content at build time
watch-pathsone of the listed paths has changeddev with bind-mounted source
resources:
image:
type: docker/image
rebuildTrigger:
strategy: watch-paths
paths:
- Dockerfile
- package.json
- /shared/base.Dockerfile # /-prefix escapes to monorepo root

Paths in watch-paths are resolved against the resource’s docker context (the same base used for dockerfile / context). A leading / escapes to the monorepo root, which is useful for shared files like root-level lockfiles or base Dockerfiles.

rebuildTrigger follows this precedence, highest wins:

  1. resources.<name>.rebuildTrigger on the resource itself.
  2. flavors.<flavor>.defaults.rebuildPolicy['docker/image'] on the active flavor — see Flavors → Rebuild policies.
  3. Built-in { strategy: auto }.

Non-auto rebuilds (and any --force run) print the resolved strategy, source, reason, and watched files in the build output, so you can see exactly why a rebuild did or didn’t happen.

Regardless of the strategy, two invariants hold:

  • If a dependency was rebuilt, this resource rebuilds too (dep cascade).
  • --force always rebuilds.

Generates a file.

ParameterTypeDescription
pathstringOutput file path (defaults to resource name)
contentstringContent to write to the file (supports template expansion with secrets)
scriptstringScript to generate the file

Example with content and secrets:

resources:
.env:
type: file
params:
content: |
DATABASE_URL=${op:Private/db-credentials#connection_string}
API_KEY=${op:Private/api-keys#production}

Example with script:

resources:
config.json:
type: file
params:
path: config.json
script: |
echo '{"key": "value"}' > config.json

Note: If both content and script are provided, content takes precedence.

Materializes a 1Password attachment (document or file field) as a file on disk. Requires a configured 1Password provider.

ParameterTypeDescription
referencestringRequired. Full 1Password secret reference, e.g. op://vault/item/file
pathstringDestination path relative to the component (defaults to the resource name)
resources:
service-account.json:
type: op/file
params:
reference: op://Production/gcp-service-account/credentials.json
path: .secrets/service-account.json

Optional. Component tasks.

tasks:
test:
description: Run tests
script: npm test
executors:
- container # Run in container (default)
vars:
NODE_ENV: test

Task properties:

PropertyTypeDescription
descriptionstringTask description
scriptstringShell script to execute
prearrayTasks to run before this one
dependenciesarrayResource refs (name or component:name) that must be built before this task runs
executorsarrayWhere to run: local, container, or kubernetes
interactivebooleanRequires TTY (default: false)
varsobjectTask-specific variables
confirmobjectRequire user confirmation

Optional. Component-level flavors.

flavors:
production:
patches:
- op: replace
path: /resources/image/params/target
value: production

Optional. Kubernetes-specific configuration for the component.

kubernetes:
selector: app=api,tier=backend # Custom label selector for finding pods
container: main # Container name for multi-container pods
OptionDescription
selectorLabel selector to find pods (overrides default {selectorLabel}={component})
containerContainer name for multi-container pods

EMB supports variable expansion in configuration values:

env:
# Use environment variable with default
TAG: ${env:DOCKER_TAG:-latest}
# Use another config variable
IMAGE: ${vars:registry}/app:${env:TAG}
# Use a secret from Vault
DATABASE_URL: ${vault:secret/myapp/database#url}

Syntax:

  • ${env:VAR_NAME} - Environment variable (required)
  • ${env:VAR_NAME:-default} - Environment variable with default
  • ${vars:VAR_NAME} - Config variable
  • ${vault:path#key} - Secret from Vault (requires vault plugin)

Flavors use JSON Patch (RFC 6902) operations:

patches:
# Add a new property
- op: add
path: /resources/image/params/labels/version
value: "2.0.0"
# Replace existing value
- op: replace
path: /resources/image/params/target
value: production
# Remove a property
- op: remove
path: /resources/image/params/buildArgs/DEBUG
# Move a property
- op: move
from: /old/path
path: /new/path
# Copy a property
- op: copy
from: /source/path
path: /dest/path
.emb.yml
project:
name: my-app
plugins:
- name: autodocker
- name: dotenv
config: [.env]
- name: embfiles
env:
DOCKER_TAG: ${env:DOCKER_TAG:-latest}
REGISTRY: docker.io/myorg
defaults:
docker:
tag: ${env:DOCKER_TAG}
tasks:
deploy:
pre: [build]
script: ./deploy.sh
flavors:
production:
patches:
- op: replace
path: /env/DOCKER_TAG
value: ${env:VERSION:-latest}
api/Embfile.yml
description: REST API service
resources:
image:
type: docker/image
params:
target: development
tasks:
test:
description: Run API tests
script: npm test
migrate:
description: Run database migrations
executors: [local]
script: npm run migrate
flavors:
production:
patches:
- op: replace
path: /resources/image/params/target
value: production