Container Desktop
Container Desktop / Documentation

Documentation

English · Polski

Docker Compose

Container Desktop runs docker-compose.yml stacks on top of Apple's container CLI, which has no compose support of its own. The app parses your YAML and translates every service into a plain container run invocation — there is no extra daemon and no hidden state. Open it via Containers → Compose…, paste the YAML and press Run.

For each project the app:

Supported service keys

KeyNotes
imageRequired. build: is not supported — point at a ready image.
container_nameOverrides the default <project>-<service> name.
command / entrypointString or list. Multi-token entrypoints (e.g. ["dotnet", "dbmgr.dll"]) are translated correctly.
environmentMap or list form.
portsShort syntax ("8080:80", optionally /udp) and long syntax.
volumessource:target[:ro]; named volumes must already exist.
mem_limit / cpusVM resource limits (also deploy.resources.limits). The default is 1 GB — memory-hungry init tasks (e.g. database seeding) usually need mem_limit: 4g.
depends_onList or map (conditions other than service_started are ignored with a warning).
x-initContainer Desktop extension — see x-init tasks.

host.containers.internal

Use the hostname host.containers.internal anywhere in environment values or command to reach your Mac from inside the containers (the equivalent of Docker's host.docker.internal).

environment:
  DB_SERVER: "host.containers.internal,1433"   # SQL Server running on the host

Why an alias instead of an IP: every compose project gets its own vmnet network with its own subnet, so the host's gateway address differs per project and can even change between restarts of the container service (e.g. 192.168.64.1 vs 192.168.65.1). The app inspects the project network right after creating it and substitutes the alias with the actual gateway IP — the mapping is printed in the progress log.

The host service must listen on all interfaces (0.0.0.0), not just 127.0.0.1, to be reachable from the vmnet subnet. Ports published by other Container Desktop projects or by Docker Desktop on the host are reachable the same way.

Service hostnames (/etc/hosts wiring)

Services reach each other by container name — e.g. with the default naming, service server in project shop is shop-server:

environment:
  API_URL: "http://shop-server:22000"

container 1.0.0 ships a DNS resolver for container names, but it never matches: names are registered without the FQDN trailing dot while DNS queries arrive canonicalized, so every lookup fails with SERVFAIL. Container Desktop works around this: after each service starts, the app reads its IP and exchanges /etc/hosts entries between all services of the project (the progress log shows each mapping).

The entries live inside the containers, so they survive until a container is recreated. If you stop and start a single container by hand and its IP changes, re-run the compose with “Replace existing” to refresh the wiring.

x-init tasks

Mark a service with x-init: true to run it as a one-off setup task — for example creating a database with the same image but a different entrypoint. Init tasks run before all regular services, sequentially and to completion; regular services start only after every init task exits successfully.

services:
  dbinit:
    image: registry.example.com/server:1.0
    x-init: true
    entrypoint: ["dotnet", "dbmgr.dll"]
    command: create mydb --sqlserver "host.containers.internal,1433" --recreate

  server:
    image: registry.example.com/server:1.0
    # starts only after dbinit exits with code 0

Limitations

Troubleshooting

← Container Desktop · GitHub · MIT