CLI first · Docker & Podman · Self-hosted
Give your containers more machine.
COMA points Docker, Podman and coding agents at any Linux VM over SSH. Bind mounts and localhost ports keep working.
$ coma machine add bigbox ssh://dev@203.0.113.10Added machine bigbox (ssh://dev@203.0.113.10) Ubuntu 24.04 LTS · linux/amd64 · 16 CPUs · 32 GiB memory engines: docker 27.3.1$ coma workspace up --machine bigboxWorkspace shop is up on bigbox (docker 27.3.1 over ssh-streamlocal) docker (and Compose) in any terminal now run on the machine$ docker compose up -d[+] Running 5/5$ curl localhost:3000/healthok$ Works with
Engines
- Docker
- Podman
- Compose
Coding agents
- Claude Code
- Codex
- Cursor
Your machines
- Hetzner
- AWS
- GCP
- DigitalOcean
- Bare metal
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
stack 24 GiBlaptop 16 GiB
laptop unhappy
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.
./src:/app/srcbind mounts
Plain Docker over SSHMounts whatever is at that path on the VM, usually nothing
With COMAYour directory is synced to the machine, and mounts resolve to the synced copy
ports: ["3000:3000"]published ports
Plain Docker over SSHOpens on the VM, not on your laptop
With COMAMirrored to
localhost:3000on your laptop0.0.0.0 vs 127.0.0.1who can reach that port
Plain Docker over SSHPublished on all of the VM's interfaces by default
With COMAPublished on
127.0.0.1on the machine; reachable only through COMAlaptop sleepsthe connection
Plain Docker over SSHConnection drops; commands fail
With COMA
comadreconnects in the backgroundlocal enginea tool quietly falls back
Plain Docker over SSHNothing tells you
With COMA
coma doctorflags containers created locally while connectedhost identitywho you're talking to
Plain Docker over SSHWhatever your SSH config allows
With COMAHost key verified when the machine is added
Same docker compose up. Fewer surprises.
Three steps
Add. Connect. Forget where it runs.
01Add 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 VM02Connect 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 dev # or, per project:coma workspace initcoma workspace up --machine dev03Use 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
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 buildboxContainers 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.
Machines and connections
- coma machine
- Register, bootstrap and inspect machines
- coma connect
- Point Docker, Compose and Podman at a machine
- coma disconnect
- Switch them back
- coma context
- Named default targets
Projects
- 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
Engines and diagnosis
- 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
# flags and output are Docker's and Podman's owncoma 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.
- --json
- stdout · stderr
- stable error codes
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 a coding agent needs to check what COMA is doing, every command speaks JSON with stable error codes.
coma workspace status --jsoncoma doctor --json # envelope: coma.sh/cli/v1alpha1# stable error codes, next command to runRoadmap
planned · not shippedNext: 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.
Client
You · your coding agent
- terminal
- editor
- docker · docker compose · podmanunchanged
COMA
COMA on your laptop
- local Docker socket
- source sync
- localhost ports
- reconnect
- SSHhost key verified
Engine
Docker / Podman on your machine
Host
Your VM
- Hetzner
- AWS
- GCP
- a home server
- bare metal
Roadmap · 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.
ShippedPlanned
Today: one machine over SSH
ShippedToday: one machine over SSH
machine add · connect · workspaces · sync · localhost ports · doctor · --json
Machine agent
PlannedMachine agent
An optional service on the machine: a persistent control channel, machine identity, better health. SSH stays supported.
Providers
PlannedProviders
Plugins that create machines, storage, databases, caches and networks on the infrastructure you choose.
COMA Cloud
PlannedCOMA Cloud
Managed machines that suspend when idle and keep your workspace state.
Compute on request
PlannedCompute on request
Coding agents ask for CPU, memory, an engine, a time limit and a budget; COMA finds the machine.
Pools and clusters
PlannedPools and clusters
Schedulable 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.
- Only COMA access and major product updates. No marketing list.
- No IP addresses or user agents stored.
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.