Skip to content

Docker Compose Import

Bart Reardon edited this page Aug 9, 2026 · 3 revisions

Importing a docker-compose file

Stacks ▸ + ▸ Import Template… accepts a docker-compose.yml and converts it into a stack definition on the way in. It's a best-effort conversion of a practical subset — and it tells you exactly what it couldn't carry over rather than quietly dropping it.

What converts

Compose Result
image Used as-is. Required — see build:
environment Both the map and the list form
ports Short ("8080:80") and long ({target, published}) forms
volumes Short and long forms; relative host paths resolved against the compose file's folder
depends_on Start order, list or map form
command String or argv list
platform Normalised to OCI spelling (linux/x86_64linux/amd64)
mem_limit, cpus Applied to the service; deploy.resources.limits is read too

Service references become address tokens

Containers don't resolve each other by name unless you've configured Local DNS, and an import can't assume you have — so a value that names another service is rewritten to an ${IP:…} token:

In the compose file Imported as
DB_HOST=db DB_HOST=${IP:db}
DB_HOST=db:3306 DB_HOST=${IP:db}:3306
DSN=postgres://u:p@db:5432/app DSN=postgres://u:p@${IP:db}:5432/app
URL=http://db:8080/health URL=http://${IP:db}:8080/health

A value that merely contains a service name (UNRELATED=database) is left alone.

Variables become fields

Compose's ${VAR} interpolation uses the same syntax as a stack definition's own fields, so each variable becomes a field on the create form:

  • ${TAG:-alpine} — the inline default becomes the field's default.
  • A .env file beside the compose file prefills them, and the import summary says how many of them it filled.
  • Names that look like secrets (PASSWORD, SECRET, TOKEN, PRIVATE_KEY) are masked.
  • You can also load one later with Import .env… on the create sheet.

The web port

The first published port on the last service to start becomes the stack's Open in Browser target, and is turned into a port field so each deployment can choose its own.

What doesn't convert

Everything else is skipped and listed — with the reason — in the summary shown after import and in the stack's log. Among them:

Key Why
restart Restart policies aren't supported; start the stack again
deploy Only resources.limits is read; replicas and placement aren't supported
healthcheck Not run; dependants wait for the port to accept connections instead
networks, links, dns, extra_hosts Every service shares one stack network and reaches the others by address
env_file Not read; use Import .env… on the create sheet
entrypoint Fold it into command:
secrets, configs Pass values as environment variables
container_name Names come from the stack and the service key, so a stack can be created twice without colliding
profiles Not evaluated — every service is imported
cap_add, privileged, devices, user, working_dir, logging No equivalent in the runtime

Services that build:

container builds images through a separate command, so a service with build: and no image: can't be represented. It's skipped rather than failing the whole file, and reported. Build it first under Images ▸ Build Image…, then reference the tag with image:.

If every service uses build:, the import fails and says so — there'd be nothing left.

Anonymous volumes

A mount with a target but no source can't be named, so it's skipped and reported. Give it a volume name or a host path.

Waiting for dependencies

Compose's service_healthy and service_completed_successfully conditions aren't evaluated. Instead each service is waited on until it accepts TCP connections on the ports it exposes, up to two minutes, before the next one starts.

That's usually equivalent in practice and occasionally isn't — a database that accepts connections before it has finished initialising will let the next service start early. If that bites, an init service that waits properly is the reliable answer.

After importing

The import opens the stack's create sheet with the fields it found. Nothing is created until you click Create, so it's safe to import a file just to see what it makes of it.

If anything was dropped, an alert says so first, and the same text is kept in the stack's Log afterwards — so "what didn't come across?" is answerable a week later.

If you need full fidelity

container-compose implements far more of the compose spec as a container CLI plugin, at the cost of running a forked runtime. This importer is aimed at getting a real compose file running quickly, not at covering the spec.

Clone this wiki locally