Skip to content
COMA

Tools that ignore Docker contexts

Point Docker SDKs, Testcontainers and other DOCKER_HOST tools at a remote machine with coma endpoint env, a per-machine endpoint or a fixed Docker context.

coma connect switches the Docker CLI's current context to coma. The Docker CLI and docker compose follow it. Many other tools do not read Docker contexts: Docker SDKs and test libraries usually read DOCKER_HOST, and some tools take a socket path as a setting. For those, COMA gives you a socket.

The stable socket

COMA serves the machine's engine on a private Unix socket on your computer. coma connect points a stable socket, docker.sock in COMA's run directory, at the machine you connected to. Connect to another machine and the same path follows.

SetupStable socket
macOS~/.coma/run/docker.sock
Linux$XDG_RUNTIME_DIR/coma/docker.sock, or ~/.coma/run/docker.sock without XDG_RUNTIME_DIR
COMA_HOME set$COMA_HOME/run/docker.sock

When that path would be too long for a Unix socket, COMA uses a short directory under /tmp/coma-<uid>/ instead. You do not need to work out the path: coma endpoint env prints it.

coma endpoint env

coma endpoint env

prints shell code that points DOCKER_HOST at the stable socket and clears variables that would override it:

export DOCKER_HOST='unix:///Users/you/.coma/run/docker.sock'
unset DOCKER_CONTEXT DOCKER_TLS_VERIFY DOCKER_CERT_PATH

Apply it to the current shell, then run the tool from that shell:

eval "$(coma endpoint env)"

The syntax follows $SHELL. Choose another with --shell (bash, zsh, fish or powershell):

eval "$(coma endpoint env --shell bash)"

With --podman, it sets CONTAINER_HOST for the podman CLI instead and unsets CONTAINER_CONNECTION. With --json, the EndpointEnv result lists the variables to set and unset.

An unsupported --shell is an error (exit 2). If your $SHELL is one coma does not write for, such as tcsh, it prints bash syntax and says so on stderr.

Pin one endpoint

The stable socket follows coma connect to whichever machine you connect next. To keep a shell on one endpoint instead, pass its name or ID (from coma endpoint list):

eval "$(coma endpoint env dev-docker)"

That points DOCKER_HOST at the endpoint's own socket. If the endpoint is not running, coma warns; the socket works once it runs (coma endpoint start or coma connect).

Things to know:

  • coma endpoint env only prints; it never changes your shell by itself. When nothing is connected it warns on stderr, because the socket does not exist yet. Run coma connect first; until then, and after coma disconnect, clients using this DOCKER_HOST fail to connect.
  • In that shell, the Docker CLI uses DOCKER_HOST too, so it reaches the same machine.
  • coma connect warns when DOCKER_HOST or DOCKER_CONTEXT is set in the shell you run it from, because either one overrides the coma context.

To leave the Docker CLI's context alone and still re-point the stable socket, connect with --no-switch:

coma connect dev --no-switch
eval "$(coma endpoint env)"

A socket for one machine

The stable socket follows coma connect. To give a tool a socket that always reaches one machine and engine, start that endpoint on its own:

coma endpoint start --machine dev --engine docker
Endpoint dev-docker is ready
  DOCKER_HOST=unix:///Users/you/.coma/run/endpoints/ep_<id>/docker.sock

coma endpoint start does not touch the Docker context or podman's default. Endpoints are named <machine>-<engine>; coma endpoint list shows them and their state.

A Docker context for one machine

For tools that accept a context name (docker --context, DOCKER_CONTEXT), install a context fixed to one machine and engine:

coma docker-context install --machine dev --engine docker
docker --context coma-dev-docker compose up

The context is named coma-<machine>-<engine> unless you give a name. Installing it starts the endpoint if needed and does not change the current context, so you can use several machines side by side. The name coma stays reserved for coma connect.

CommandDoes
coma docker-context listLists the contexts COMA manages, including coma
coma docker-context verify <name>Checks the context exists, still points where COMA wrote it, its endpoint runs and the engine answers
coma docker-context install <name> againRepairs the context
coma docker-context remove <name>Removes a context COMA created

COMA only changes contexts it created. A context with the same name that COMA did not create is replaced only with --replace. A context edited outside COMA fails verify with docker_context_drifted.

Testcontainers

Testcontainers asks the engine which host port each container received and connects to localhost on that port. COMA mirrors every published port, including random ones, to localhost, and holds the container's start response (for up to 2 s) until the mirrors are open. You do not need TESTCONTAINERS_HOST_OVERRIDE.

coma connect dev
eval "$(coma endpoint env)"
npm test

Testcontainers for Node (Redis and Postgres, a user network, exec, file copy, log streaming and Ryuk cleanup) has run through COMA on both Docker and Podman engines. Ryuk mounts the Docker socket named in DOCKER_HOST; COMA maps that mount to the engine's socket on the machine, so Ryuk removes the containers it should.

If Testcontainers fails before it reaches any engine, check Docker's config.json for a credsStore whose helper is not installed. coma doctor reports it.

Containers that mount the Docker socket

CI runners and other tools start helper containers that bind-mount the Docker socket. Through COMA, a bind mount of /var/run/docker.sock, of the stable socket, or of the endpoint's own socket is mapped to the engine's socket on the machine. coma endpoint doctor <endpoint> --explain-last shows the mapping after the container is created.

Some tools take the socket as a setting instead of reading DOCKER_HOST. For example, act ran a GitHub Actions job on the machine with --container-daemon-socket set to COMA's socket.

On this page