Skip to content
COMA

coma.yaml

Every field of the workspace manifest, apiVersion coma.sh/v1alpha1, with its values, defaults and validation rules.

A coma.yaml makes a project directory a workspace: it names the machine, the engine, what to sync and which ports to forward. It is meant to be committed. coma workspace init writes a minimal one; coma workspace validate checks it.

Complete example

apiVersion: coma.sh/v1alpha1
kind: Workspace
metadata:
  name: shop
  description: Storefront and its database
  labels:
    team: web
spec:
  source:
    path: .
  target:
    machine: dev
  runtime:
    engine: docker
    compose:
      files:
        - compose.yaml
      projectName: shop
  sync:
    mode: one-way-safe
    gitignore: true
    ignore:
      - node_modules/
      - "*.log"
    include:
      - .env.development
  ports:
    - name: web
      remote: 3000
    - name: db
      remote: 5432
      local: 15432
    - service: web
      remote: 80
      local: auto
    - name: redis
      remote: 6379
      local: disabled

Finding the file

Workspace commands use --file when given. Otherwise they look for coma.yaml or coma.yml in the current directory, then in each parent, and stop at the repository root (a directory containing .git) or the filesystem root. A directory with both names is an error (workspace_manifest_ambiguous). A manifest may be at most 1 MiB, and each list at most 256 entries.

Validation

Unknown keys and wrong types are errors, reported with the file and line. Once the file decodes, every field error is reported together, with its line, column and YAML path:

coma workspace validate
Error: ./coma.yaml is not a valid workspace manifest:
  ./coma.yaml:4:9 metadata.name: "Bad_Name" must be lower-case letters, digits and dashes (at most 63)
  ./coma.yaml:6:5 metadata.labels: label "coma.sh/x" uses the reserved coma.sh/ prefix
  ./coma.yaml:13:19 spec.ports.0.visibility: public visibility is not supported: COMA never opens public ingress (workspace_manifest_invalid)

An invalid manifest exits with 2 (workspace_manifest_invalid). With --json, each problem is in error.details.diagnostics with file, line, column, path and message.

coma workspace status reports drift when coma.yaml changed after the last coma workspace up.

Top level

FieldRequiredValue
apiVersionyescoma.sh/v1alpha1
kindyesWorkspace
metadatayesSee below
specnoSee below

The older name coma.dev/v1alpha1 is still read, with a warning to change it. Any other apiVersion fails with workspace_api_version_unsupported (exit 8).

metadata

FieldRequiredValue
nameyesLower-case letters, digits and dashes; starts and ends with a letter or digit; at most 63 characters
descriptionnoFree text
labelsnoMap of string keys to string values. Keys may not start with coma.sh/, which COMA reserves

coma workspace init derives the name from the directory's name.

spec.source

FieldDefaultValue
path.The source directory, relative to the directory holding coma.yaml. It must exist and be a directory; absolute paths are refused

spec.target

FieldValue
machineThe name of a machine in your COMA inventory
pool, clusterAccepted by the schema, but plan and up fail with workspace_target_kind_unsupported (exit 8)

Set at most one of the three. Machine names are per user, so coma workspace init writes machine only when you pass --machine.

The machine is chosen in this order: --machine, then spec.target.machine, then the current context's machine. With none of them, plan and up fail with workspace_target_required. coma workspace plan shows which one was used.

spec.runtime

FieldValue
enginedocker or podman
workingDirectoryA directory relative to the source; used for the Compose project's default name
compose.filesCompose files, relative and inside the source. plan warns when one does not exist
compose.projectNameThe Compose project name
compose.profilesList of Compose profiles
compose.envFilesEnv files, relative and inside the source
compose.removeOrphanstrue or false

The engine is chosen in this order: --engine, then spec.runtime.engine, then the current context's preference or the machine's only working engine.

COMA does not start Compose: you run docker compose up after coma workspace up. files, profiles, envFiles and removeOrphans are accepted and their paths checked, but COMA does not pass them to Compose. projectName matters now: it is the project in which spec.ports entries with service find their containers. Without it, COMA uses Compose's default, the name of the source directory (or workingDirectory), lower-cased, keeping letters, digits, - and _.

spec.sync

FieldDefaultValue
modeone-way-safenone, one-way-safe, one-way-mirror or bidirectional
ignorenoneGit-style patterns to leave out
includenoneGit-style patterns to bring back in
gitignoretruefalse stops applying .gitignore files

Sync modes

ModeWhat it doesWho can turn it on
noneNothing is synced; bind mounts of the source are refusedcoma.yaml
one-way-safeYour changes go to the machine; a file changed on the machine is never overwritten (a conflict instead)Default
one-way-mirrorThe machine's copy is made identical to yours: files created or changed there, outside ignored paths, are overwritten or deletedcoma.yaml, and a confirmation before the first sync (--yes without a terminal)
bidirectionalChanges on either side are copied to the other; a file changed on both is left as a conflictcoma.yaml plus your own sync.allowBidirectional: true in COMA's config, or COMA_SYNC_ALLOW_BIDIRECTIONAL=1

A repository's coma.yaml alone cannot make changes on the machine flow back to your computer: without your setting, bidirectional blocks up with workspace_plan_blocked. Both opt-in modes need the Mutagen sync engine; otherwise up fails with sync_mode_unsupported. coma workspace up --no-sync skips sync for one run. See Source sync.

Ignore rules

ignore and include entries are Git-style patterns relative to the source directory. Each must be one line of at most 1,024 bytes, not empty, not a comment, and must not leave the source directory (..).

Rules apply in this order, later rules winning: the built-in rules (.git/ and .coma/), .comaignore, the root .gitignore, ignore, include, then nested .gitignore files. As in Git, include cannot bring back a path inside a directory that is excluded. gitignore: false drops the .gitignore files; the built-in rules and .comaignore still apply.

coma sync explain <path> says whether a path is synced and which rule decided.

Fields reported as unsupported

FieldWhat happens
remotePathAny value other than auto is reported as unsupported. COMA keeps the copy at ~/.coma/workspaces/<id>/source on the machine
delete, watchReported as unsupported. COMA always watches, and the mode decides what is deleted

spec.ports

Each entry forwards a port on the machine to your computer, possibly at another number. While the workspace is up, a declared port replaces the automatic mirror of the same remote port. See Ports.

FieldRequiredValue
remoteyes1 to 65535. The machine's host port, or with service, the container's port
localnoA port number, auto (a free port, kept across ups when still free) or disabled (nothing forwarded, and the mirror of that port is turned off). Default: the remote number
namenoLower-case letters, digits and dashes. Default: <service>-<remote>, or port-<remote>
servicenoA Compose service in the workspace's project
protocolnotcp, the only one forwarded
visibilitynolocal (default) or none, which acts like local: disabled. public is refused: COMA never opens public ingress
containernoRefused: not supported yet; use service
hostnoRefused: ports are forwarded from the machine itself

Names, explicit local ports and forwarded targets must each be unique within the file. A local port that is busy on your computer, or declared by another workspace, is reported as local_port_in_use; coma port list shows the state of each port.

Reserved sections

These spec sections are accepted with any content but not implemented yet. coma workspace validate and plan list each one as "not implemented yet, ignored", so nothing is silently dropped:

requirements, environment, secrets, persistence, caches, lifecycle, idle, budget, policy, extensions.

On this page