Workspaces
A workspace is a project directory with a coma.yaml that names its machine, engine, sync rules and ports.
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, so docker compose up in any terminal runs remotely.
You do not need a workspace to use COMA. coma connect and coma sync watch work without one. A workspace writes those choices down in a file you can commit.
coma.yaml
coma workspace init writes a minimal manifest for the current directory and names the Compose file it finds:
apiVersion: coma.sh/v1alpha1
kind: Workspace
metadata:
name: app
spec:
source:
path: .
runtime:
compose:
files:
- compose.yaml
sync:
mode: one-way-safeinit writes a machine only when you pass --machine, because machine names are per user and coma.yaml is meant to be committed. It never reads .env files. Every field is described in the coma.yaml reference.
COMA validates the manifest strictly. Unknown keys and wrong types fail with the file, line, column and YAML path, all reported at once (workspace_manifest_invalid). Sections COMA accepts but does not act on yet are listed as unsupported by workspace plan; they are never silently ignored.
How COMA finds coma.yaml
Workspace commands look for coma.yaml or coma.yml in the current directory, then in each parent directory. The search stops at the repository root (the directory with .git). You can run them from any subdirectory of the project.
--file <path>uses a specific manifest instead.- A directory with both
coma.yamlandcoma.ymlis an error (workspace_manifest_ambiguous). Remove one.
Manifests written before the identifier change use apiVersion: coma.dev/v1alpha1. COMA still reads them and warns:
Warning: /Users/you/code/app/coma.yaml: apiVersion coma.dev/v1alpha1 is the old name; change it to coma.sh/v1alpha1Change the value to coma.sh/v1alpha1. Support for the old name will be removed in a later release.
Which machine and engine
workspace plan and workspace up resolve the machine in this order:
--machine <name>;spec.target.machineincoma.yaml;- the machine of the current context.
With none of these, they fail with workspace_target_required.
The engine is --engine, then spec.runtime.engine, then the usual engine selection: the context's preference, or the machine's only working engine. workspace plan shows where each choice came from.
Lifecycle
| Command | What it does |
|---|---|
coma workspace init | Write a coma.yaml for the current directory |
coma workspace validate | Check coma.yaml and show where any problem is |
coma workspace plan | Show what up would do; changes nothing |
coma workspace up | Connect to the machine and sync the source |
coma workspace status | Show the workspace's health |
coma workspace down | Stop syncing the source |
coma workspace delete | Forget the workspace; --remote also removes the machine's copy |
coma workspace list | List registered workspaces |
up
coma workspace upup registers the workspace, starts its endpoint, points the Docker context coma at it (and, for a Podman engine, podman's default connection), syncs the source and starts any ports declared in coma.yaml. It does not start containers: run docker compose up next, in any terminal. Running up again is safe.
--no-connectleaves the Docker CLI's and podman's defaults alone; usedocker --context coma ….--no-syncskips syncing. Bind mounts of the source are then refused.
status and drift
workspace status reports four conditions: ManifestValid, CompatibilityEndpointReady, SyncReady and PortsReady.
When you run up, COMA stores a hash of the manifest's content. If coma.yaml changes afterwards, status reports the drift as a warning (in warnings and drift with --json):
Warning: coma.yaml changed since the last `workspace up`workspace plan shows the same change as an update. Run coma workspace up again to apply it.
down and delete
down stops syncing and stops declared ports. Containers, the copy on the machine and the endpoint are left alone. Stop containers with docker compose down, and switch the CLIs back with coma disconnect.
delete forgets the workspace: sync stops and COMA removes its record. With --remote, it also removes the source's copy on the machine (~/.coma/workspaces/<id>). COMA shows what it will remove and what it keeps, and asks first (--yes in scripts). Your source directory, containers, images, volumes and the endpoint are never touched.
Trust
coma.yaml often comes from a repository someone else wrote. COMA treats it as untrusted input:
- the parser is strict and fuzz-tested;
workspace planwarns about.envfiles that sync would copy;- a manifest cannot turn on bidirectional sync on its own. That needs a setting in your own COMA config (see Sync);
- a manifest cannot open a port to the network:
visibility: publicis rejected.