CLI first · Docker & Podman · Self-hosted
Give your containers more machine.
COMA points Docker, Podman and your coding agents at a bigger machine: any Linux VM you can reach over SSH. Bind mounts, localhost ports and interactive commands keep working, so your workflow doesn't change. The heavy lifting just happens somewhere with more CPU, memory and disk.
Works with a VM you already have. No COMA account needed.
$ coma machine add bigbox ssh://dev@203.0.113.10Added machine bigbox (ssh://dev@203.0.113.10) Ubuntu 24.04.3 LTS · linux/amd64 · 16 CPUs · 62.7 GiB memory · 180 GiB free on / engines: docker 29.8.2 $ coma workspace up --machine bigboxWorkspace shop is up on bigbox (docker 29.8.2 over ssh-streamlocal) docker (and Compose) in any terminal now run on the machine $ docker compose up -d[+] Running 5/5 $ curl localhost:3000/healthokYour laptop should not be the limit
The container workflow is local. The compute does not have to be.
Docker Compose stacks keep getting heavier. Coding agents run builds, databases, browsers, test suites and local services without caring how much memory your laptop has left.
COMA separates the tools you use from the machine doing the work. Your tools stay the same. The container engine runs somewhere much bigger.
Move the stack. Keep the workflow.
- API
- 2 GiB
- Postgres
- 4 GiB
- Redis
- 1 GiB
- Playwright
- 3 GiB
- Search
- 6 GiB
- Blockchain
- 8 GiB
- Laptop
- unhappy
The hard part isn't the connection
DOCKER_HOST=ssh:// moves the engine. COMA moves the workflow.
Pointing Docker at a remote host is one line. Making everything that relies on “local” keep working is the rest of the job.
| Situation | Plain Docker over SSH | With COMA |
|---|---|---|
./src:/app/src bind mounts | Mount whatever is at that path on the VM, usually nothing | Your directory is synced to the machine, and mounts resolve to the synced copy |
ports: ["3000:3000"] | Opens on the VM, not on your laptop | Mirrored to localhost:3000 on your laptop |
| Who can reach that port | Published on all of the VM's interfaces by default | Published on 127.0.0.1 on the machine; reachable only through COMA |
| Laptop sleeps | Connection drops; commands fail | comad reconnects in the background |
| A tool quietly uses the local engine | Nothing tells you | coma doctor flags containers created locally while connected |
| Host identity | Whatever your SSH config allows | Host key verified when the machine is added |
./src:/app/srcbind mounts- Plain Docker over SSH
- Mount whatever is at that path on the VM, usually nothing
- With COMA
- Your directory is synced to the machine, and mounts resolve to the synced copy
ports: ["3000:3000"]- Plain Docker over SSH
- Opens on the VM, not on your laptop
- With COMA
- Mirrored to
localhost:3000on your laptop
Who can reach that port
- Plain Docker over SSH
- Published on all of the VM's interfaces by default
- With COMA
- Published on
127.0.0.1on the machine; reachable only through COMA
Laptop sleeps
- Plain Docker over SSH
- Connection drops; commands fail
- With COMA
comadreconnects in the background
A tool quietly uses the local engine
- Plain Docker over SSH
- Nothing tells you
- With COMA
coma doctorflags containers created locally while connected
Host identity
- Plain Docker over SSH
- Whatever your SSH config allows
- With COMA
- Host key verified when the machine is added
Same docker compose up. Fewer surprises.
Three steps
Add. Connect. Forget where it runs.
- 01
Add a machine
Register a Linux VM you already own. COMA verifies its host key, takes an inventory and changes nothing on it. On a bare VM, COMA can install Docker or Podman, but only after showing you the plan.
coma machine add dev ssh://you@203.0.113.10coma machine bootstrap dev --engine docker # only on a bare VM - 02
Connect your project
Point the Docker CLI at the machine for everything, or describe a project in
coma.yamlso its source stays synced and its ports come home.coma connect devor, per project:
coma workspace initcoma workspace up --machine dev - 03
Use your normal tools
Run Docker, Podman, Compose, tests and coding agents as usual. The containers run on the machine; their ports answer on
localhost.docker compose upcurl localhost:3000
Self-hosted first
Your VM is already a COMA machine.
You should not have to move to another cloud to get more compute. Start with infrastructure you already pay for (Hetzner, AWS, GCP, a server under your desk) and keep full control of it.
No COMA account. Self-hosted use needs nothing from us.
Nothing on the network. No Docker socket exposed: traffic goes over SSH, and the local socket is private to you.
No surprises on the server.
machine addonly reads.machine bootstrapshows its plan and asks before installing anything.Your VM remains your VM.
coma machine removeforgets it; the server is not changed.
coma machine add buildbox ssh://root@203.0.113.42coma machine inspect buildboxcoma connect buildboxOne control surface
Containers have enough CLIs already.
COMA adds one small set of commands for machines and connections, and keeps Docker's and Podman's own CLIs exactly as they are.
- coma machine
- register, bootstrap and inspect machines
- coma connect
- point Docker, Compose and podman at a machine
- coma disconnect
- switch them back
- coma workspace
- run a project from its coma.yaml
- coma sync
- keep a directory on the machine so bind mounts work
- coma port
- see container ports mirrored to localhost
- coma context
- named default targets
- coma docker
- run the docker CLI on the machine
- coma podman
- run the podman CLI on the machine
- coma doctor
- find what's sending commands to the wrong place
Native passthrough
coma docker --machine dev -- system dfcoma podman infoScriptable by default
Every command takes --json. Human output goes to stdout; progress, warnings and errors go to stderr. Errors carry stable codes and the next command to run.
Normalise the common path. Keep native power available.
For humans and coding agents
Your coding agent doesn't need to know.
coma connect switches the Docker CLI's context, so every new shell uses the machine, including the ones Codex, Claude Code and Cursor start. Your coding agent keeps running docker compose up and npm test. The memory it eats is on the machine.
When an agent needs to check what COMA is doing, every command speaks JSON with stable error codes.
coma workspace status --jsoncoma doctor --jsonNext: compute on request.
A coding agent asks for what it needs (CPU, memory, engine, a time limit, a budget), does the work and releases it, without ever seeing a cloud console or your credentials.
coma request compute --cpu 16 --memory 32GiB --engine docker --ttl 2hCOMA is not another container engine.
Docker and Podman already do that job well. COMA manages where they run, how your tools reach them, and what keeps working when they're not on your laptop.
You · your coding agent
docker · docker compose · podman (unchanged)
COMA on your laptop
local Docker socket · source sync · localhost ports · reconnect
Docker / Podman on your machine
over SSH, host key verified
Your VM
Hetzner, AWS, GCP, a home server, bare metal
Where COMA is going
Start with one machine. The rest is on the way.
Everything above works today. Everything below is designed and planned, not shipped. We'll move items up as they land.
Machine agent
RoadmapAn optional service on the machine: a persistent control channel, machine identity, better health. SSH stays supported.
Providers
RoadmapPlugins that create machines, storage, databases, caches and networks on the infrastructure you choose.
COMA Cloud
RoadmapManaged machines that suspend when idle and keep your workspace state.
Compute on request
RoadmapCoding agents ask for CPU, memory, an engine, a time limit and a budget; COMA finds the machine.
Pools and clusters
RoadmapSchedulable capacity across many machines.
Want to try COMA?
COMA is in private pre-alpha. Leave your email and we'll send access as we open it up.
Your containers don't need to fit on your laptop.
Start with a Linux VM you already have. Keep Docker. Keep Podman. Keep your workflow.