Configuration
Zapper projects are configured with a zap.yaml file in the project root. packages/cli/src/config/schemas.ts is the source of truth for supported fields.
Zapper projects are configured with a zap.yaml file in the project root.
packages/cli/src/config/schemas.ts is the source of truth for supported
fields.
Minimal Config
project: myapp
native:
api:
cmd: pnpm devTop-Level Fields
project: myapp
env: [.env.base, .env]
profiles:
default:
env_files: [.env.base, .env]
services: "*"
e2e:
env_files: [.env.base, .env.e2e, .env]
services: [api, worker, postgres]
isolate: true
ports:
- FRONTEND_PORT
- BACKEND_PORT
init_task: seed
git_method: ssh
task_delimiters: ["{{", "}}"]
native:
# process definitions
docker:
# container definitions
volumes:
# top-level Docker volume declarations
secrets:
# top-level Docker secret declarations
tasks:
# task definitions
homepage: http://localhost:3000
notes: "API: http://localhost:${API_PORT}"
links:
- name: API Docs
url: http://localhost:${API_PORT}/docsprojectis required and is used as the native/Docker namespace.envdefines root environment file stacks.env_filesis accepted as a compatibility alias for rootenv.profilesdefines named runtime profiles with env files, service selection, and optional stack isolation.portslists uppercase env var names that Zapper assigns per instance.init_tasknames a task to run afterzap init.git_methodcontrols repo clone URLs:ssh,http, orcli.task_delimiterschanges task template delimiters.nativedefines local supervisor-managed processes.dockerandcontainersdefine Docker-managed services.volumesdeclares reusable Docker named volumes.secretsdeclares local file/env-backed secrets for Docker services.processesis accepted as a legacy process form.tasksdefines one-off commands.homepage,links, andnotesexpose project metadata to CLI and tools.
Environment Files
Root env is a file stack:
env: [.env.base, .env]Use profiles when you need named env file stacks or service subsets:
profiles:
default:
env_files: [.env.base, .env]
proddata:
env_files: [.env.base, .env.proddata, .env]
services: "*"Select a saved profile or use one for a single command:
zap profile set proddata
zap --profile proddata up
zap profile resetLater files override earlier files. Root env_files remains a compatibility
alias, but new configs should prefer env.
Profile service subsets automatically include depends_on dependencies. A
profile can list a native app service and Zapper will still include the Docker
services that app depends on.
See Environment Variable Management for detailed resolution rules.
Config Interpolation
String values inside service, task, metadata, build, watch, volume, and secret configuration support shell-style interpolation from the resolved root env stack, assigned ports, and the current process environment:
env: [.env]
docker:
api:
image: myapp/api:${API_TAG:-dev}
ports:
- "${API_PORT?API_PORT is required}:3000"Supported forms:
${VAR}expands to the variable value or an empty string.${VAR:-default}usesdefaultwhen the variable is unset or empty.${VAR?message}fails config loading withmessagewhen the variable is unset or empty.$$emits a literal$.
Port Assignment
Define port variable names in config and initialize them with zap init:
project: myapp
ports:
- FRONTEND_PORT
- BACKEND_PORT
- DB_PORTAssigned ports have highest precedence over values from .env files. This
supports multiple instances of the same project without port collisions.
Most config-backed commands initialize missing instance state automatically.
Read-only commands such as zap status, zap ls, zap state, zap logs, and
zap startup-log do not create or update .zap/state.json just by loading the
project.
State writes are protected by a local lock and saved atomically. If
.zap/state.json is malformed, commands that need to update state fail instead
of replacing it with default state.
Interpolation uses assigned port values:
FRONTEND_PORT=3000
FRONTEND_URL=http://localhost:${FRONTEND_PORT}After initialization, if FRONTEND_PORT is assigned 54321,
FRONTEND_URL resolves to http://localhost:54321.
Init Task
Set init_task to run a task after initialization:
init_task: seed
tasks:
seed:
cmds:
- pnpm db:seedzap init performs normal initialization and then runs the task.
Git Cloning
For multi-repo projects, add repo to services and choose a clone method:
project: myapp
git_method: ssh
native:
api:
cmd: pnpm dev
cwd: ./api
repo: myorg/api-service| Method | URL Format | Notes |
|---|---|---|
ssh | git@github.com:myorg/repo.git | Requires SSH key |
http | https://github.com/myorg/repo.git | May prompt for auth |
cli | Uses gh repo clone | Requires GitHub CLI |
Repos are cloned to the service cwd.
zap clone
zap clone api
zap clone api web