Skip to content
COMA

Your first workspace

Describe a project in coma.yaml, then plan, bring up, check and stop it with coma workspace.

A workspace is a project directory with a coma.yaml that names its machine, engine, sync rules and ports. coma workspace up connects to the machine and keeps the source synced there, so docker compose up in any terminal runs remotely with bind mounts and localhost ports working. See Workspaces for the model.

You need a machine with an engine first: Add a machine, then Bootstrap a bare VM if it has none. The examples use a machine called dev and a project in /Users/you/src/web with a compose.yaml.

Write coma.yaml

In the project directory:

coma workspace init
Wrote /Users/you/src/web/coma.yaml:

apiVersion: coma.sh/v1alpha1
kind: Workspace
metadata:
  name: web
spec:
  source:
    path: .
  runtime:
    compose:
      files:
        - compose.yaml
  sync:
    mode: one-way-safe

Next: coma workspace plan, then coma workspace up

init names the directory as the workspace and lists the Compose file it finds. It writes a machine only when you pass --machine: machine names are per user, and coma.yaml is meant to be committed. It writes an engine only with --engine docker or --engine podman. --name sets another workspace name, and --force replaces an existing coma.yaml.

The smallest valid coma.yaml is the header and a name:

apiVersion: coma.sh/v1alpha1
kind: Workspace
metadata:
  name: web

The full schema is in the coma.yaml reference.

COMA finds coma.yaml (or coma.yml) in the current directory or its parents, stopping at the repository root. --file points at another one.

Check it

coma workspace validate
/Users/you/src/web/coma.yaml is valid (web)

validate reports every problem at once, each with its line, column and YAML path:

Error: /Users/you/src/web/coma.yaml is not a valid workspace manifest:
  /Users/you/src/web/coma.yaml:17:15 spec.ports.0.remote: required: a port number from 1 to 65535 (workspace_manifest_invalid)

Sections that the schema reserves but COMA does not implement yet are accepted and listed as not implemented yet, ignored, never silently dropped.

Which machine and engine

COMA picks the machine and engine in this order. The first one set wins:

OrderMachineEngine
1--machine--engine
2spec.target.machine in coma.yamlspec.runtime.engine in coma.yaml
3the current context's machine (coma use)the machine's only working engine, or the context's

With none of the three for the machine, COMA stops with workspace_target_required. If the machine has both Docker and Podman and nothing picks one, COMA stops with engine_selection_required and asks for --engine or spec.runtime.engine. See Contexts and Engines.

See the plan

plan shows what up would do, and where each choice came from. It changes nothing.

coma workspace plan --machine dev
Workspace web (/Users/you/src/web/coma.yaml)
  machine: dev (from --machine)
  engine:  docker (from the machine (its only working engine, or the context's))
  source:  /Users/you/src/web

ACTION  SUBJECT    DETAIL
create  workspace  register web from /Users/you/src/web/coma.yaml
start   endpoint   dev-docker endpoint; the Docker context `coma` points at it
sync    source     /Users/you/src/web to dev, kept current (one-way-safe: what changes on the machine is never overwritten)
noop    runtime    not started by COMA yet: run `docker compose up` once the workspace is up (compose files: [compose.yaml])

plan reads the machine's inventory from COMA's local state. If the inventory is out of date, refresh it with coma machine discover dev.

Bring it up

coma workspace up --machine dev
Workspace web is up on dev (docker 28.2.2 over ssh-streamlocal)
  docker (and Compose) in any terminal now run on the machine
Next: docker compose up. `coma workspace status` shows health; `coma disconnect` switches the CLIs back.

up registers the workspace, starts the endpoint for the machine's engine, makes the Docker context coma current (and, for Podman, podman's default connection), and syncs the source to the machine. It also prints how many files it synced and where. Running up again is safe.

up does not start containers. That is the next command, in this terminal or any other:

docker compose up

Bind mounts of project files now see the machine's copy of your source, and published ports open on your localhost.

  • --no-connect keeps the Docker CLI's and podman's defaults; use docker --context coma instead.
  • --no-sync skips syncing; bind mounts of the source are then refused.

Files in .gitignore, .comaignore and .git/ are not copied. plan warns about .env files that would be synced, because they often hold secrets. See Source sync.

Declare ports

Every TCP port a container publishes is mirrored on your localhost at the same number, with or without coma.yaml. Declare a port in spec.ports to give it a name, map it to another local number, or forward a port on the machine:

spec:
  ports:
    - name: web
      remote: 3000

local defaults to the remote number; it can be another port, auto or disabled. Only TCP is supported. plan lists one forward action per declared port, and up reports where each one is reachable. See Ports.

Check its health

coma workspace status
Workspace web (ws_01K6PZ4Q8J3V7N2XG5T9RMB0CD): up on dev, engine docker
  last up 2026-10-04 14:20:11
  PASS  ManifestValid
  PASS  CompatibilityEndpointReady  dev-docker: ready
  PASS  SyncReady                   watching, 214 files
  PASS  PortsReady                  coma.yaml declares no ports; published ports are mirrored

Each condition is PASS, WARN or FAIL with a message. status also reports drift when coma.yaml changed after the last up. coma workspace list shows every registered workspace.

Stop it

coma workspace down
Workspace web is down: sync stopped; the copy on the machine stays

down stops syncing and stops forwarding the ports declared in coma.yaml. It leaves the containers, the copy on the machine and the endpoint alone. To finish:

docker compose down
coma disconnect

Delete it

coma workspace delete
Deleting workspace web will:
  - stop syncing /Users/you/src/web and forget its sync state
  - stop forwarding its coma.yaml ports
  - forget workspace web
It keeps:
  - the source directory /Users/you/src/web
  - containers, images and volumes on the machine
  - the endpoint and Docker context (`coma disconnect` switches back)

delete shows what it will do and asks first; pass --yes in scripts. It never touches your source directory, containers, images, volumes or the endpoint. The copy of the source on the machine, under ~/.coma/workspaces, stays unless you add --remote:

coma workspace delete --remote

Next

On this page