Engines
An engine is Docker or Podman on the machine. COMA detects engines and sits above them; it never replaces them.
An engine is Docker or Podman on the machine. COMA detects engines and sits above them; it never replaces them. Containers, images, volumes and networks belong to the engine, exactly as they would without COMA.
Detection
coma machine add and coma machine discover detect engines over SSH with the engines' own CLIs. Detection is read-only. For each engine COMA records:
- version and API socket;
- Compose, with its version;
- whether it runs rootless;
- health:
healthy,permission_denied(your SSH user cannot use the engine's socket),unavailable(the daemon is down) orunknown, each with a next step.
coma engine listcoma engine list and coma engine inspect read that record and do not contact the machine. engine inspect adds capabilities and health. After you install or reconfigure an engine, run coma machine discover <name>.
Detection also warns about three setups:
- the Docker API is exposed over TCP;
- rootful Docker is older than Engine 28, where ports published on
127.0.0.1are reachable from other hosts on the same network segment; - Podman's API socket is not active. The warning gives the
systemctlcommand that starts it.
Rootless Podman
coma machine bootstrap <name> --engine podman installs Podman for your SSH user and sets it up rootless: it enables lingering so the user's services keep running after you log out, and enables the user's Podman API socket. If you connect as root, COMA uses the system socket instead.
COMA reaches whatever socket detection recorded. It does not assume /var/run/docker.sock.
Which engine COMA uses
When a machine has both engines, commands that start an endpoint (coma connect, coma workspace up, coma docker-context install) choose in this order:
--engine dockeror--engine podman;- for a workspace,
spec.runtime.engineincoma.yaml; - the current context's preference, set with
coma engine use podman(coma engine use autoclears it); - the machine's only working engine.
Otherwise they stop with engine_selection_required. COMA never picks Docker because it happens to be listed first.
Run the engine's CLI on the machine
coma docker and coma podman run the engine's own CLI on the machine, as if you had logged in over SSH and typed the command there. Output, exit codes and interactive terminals are the engine's. COMA picks the machine and connects with a verified host key.
coma docker ps -a
coma podman run --rm -it alpine shWith an explicit machine, and -- before the engine's arguments:
coma docker --machine dev -- system df- Put COMA's flags (
--machine,--context) before the engine's arguments. Everything after the first engine argument goes to the engine unchanged, socoma docker ps -apasses-ato docker. - Use
--to separate them explicitly when the engine arguments start with a flag. - Without
--machine, the command runs on the current context's machine. - An interactive terminal is allocated when your stdin and stdout are both terminals. Piped input is forwarded.
--jsonis rejected here. Use the engine's own--format json.- COMA never logs the arguments, because engine commands can contain secrets.
Because the CLI runs on the machine, paths and ports refer to the machine. A bind mount such as -v ./src:/app names a directory on the machine, and COMA does not change port publications. For your local paths, localhost ports and COMA's loopback publishing, use coma connect and your normal docker CLI instead.
coma connect with a Podman engine
coma connect dev --engine podmanWith a Podman engine, coma connect does two things:
- points the Docker context
comaat Podman's Docker-compatible API, sodockeranddocker composereach Podman on the machine; - adds a podman connection named
comaand makes it podman's default, so the localpodmanCLI, and adockeralias for it, use the machine.
coma connect --no-switch leaves both defaults alone. coma disconnect switches both back. A podman connection named coma that COMA did not create is left alone unless you pass --replace.
For one shell instead of every shell, eval "$(coma endpoint env --podman)" sets CONTAINER_HOST. See the Podman guide.
Podman compatibility
Podman is checked with a reduced suite
COMA's compatibility suite targets Docker first. Podman is checked against a reduced version of it, so not every Docker behaviour is proven on Podman, and COMA does not claim Podman behaves exactly like Docker.
Through COMA, these were checked against Podman 5.7 on a real machine:
podman run -pwith a synced bind mount,-P,run -itwith exit codes, andrun -iandexec -iwith piped input;podman pod create -p, with ports mirrored tolocalhost;podman buildwith a local build context;- Testcontainers for Node with Redis and Postgres.
Some Podman API requests are refused with an explanation, because COMA cannot yet check their port publications or the machine-side paths they use. podman kube play is one of them.