Import a Docker Compose file

Turn a docker-compose.yml into Dekka services, managed databases and connections, see a report of what changed, and deploy it.

Updated 4 November 2026

Dekka can read a docker-compose.yml and set up the same app as Dekka services. Containers that run your code become services, Postgres, Redis and MinIO containers become managed databases and buckets with connections, and the variables that pointed at those containers are rewritten to use the connections. A report lists what carried over, what changed to fit Dekka and what was left out, and nothing is created until you deploy the plan.

Import in the dashboard

  1. On a project's canvas, choose Add, then Template or dekka.yaml, and open the Docker Compose tab.
  2. Paste the file or choose Open a file, then choose Translate.
  3. Read the report. If any service has a build section, choose the GitHub Repository and Branch to build it from.
  4. Fill in any values the file asks for, choose Review changes, check the planned changes and deploy them.

The translation is a dekka.yaml blueprint, so you can also copy it, keep it in your repository and plan it again later.

What the report looks like

This is part of n8n's own Compose file for running with Postgres.

docker-compose.yml
services:
  postgres:
    image: postgres:16
    environment:
      - POSTGRES_USER
      - POSTGRES_PASSWORD
      - POSTGRES_DB
    volumes:
      - db_storage:/var/lib/postgresql/data

  n8n:
    image: docker.n8n.io/n8nio/n8n
    environment:
      - DB_TYPE=postgresdb
      - DB_POSTGRESDB_HOST=postgres
      - DB_POSTGRESDB_USER=${POSTGRES_NON_ROOT_USER}
      - DB_POSTGRESDB_PASSWORD=${POSTGRES_NON_ROOT_PASSWORD}
      - N8N_ENCRYPTION_KEY=${N8N_ENCRYPTION_KEY:?set an encryption key}
      - GENERIC_TIMEZONE=${GENERIC_TIMEZONE:-Africa/Accra}
    ports:
      - 5678:5678
    volumes:
      - n8n_storage:/home/node/.n8n
    depends_on:
      - postgres

The report groups each note under Carried over as written, Changed to fit Dekka or Left out.

Service Level Note
postgres adjusted Becomes a managed Postgres 16. Dekka creates the credentials and gives them to the services that use it.
postgres applied Its storage is managed, so the volume isn't needed.
n8n adjusted The image has no tag, so it uses docker.n8n.io/n8nio/n8n:latest. Pin a version to control upgrades.
n8n applied Served on port 5678 at a public dekka.cloud domain.
n8n applied Gets a 1 GB volume at /home/node/.n8n. Resize it in Dekka if it needs more.
n8n adjusted DB_POSTGRESDB_HOST now reads PGHOST from the connection.
n8n adjusted DB_POSTGRESDB_USER now reads PGUSER from the connection.
n8n applied Connected to postgres.

The n8n service ends up with DB_POSTGRESDB_HOST set to ${{n8n.PGHOST}}, so it reads the managed database's host from its connection, and N8N_ENCRYPTION_KEY becomes a required value you enter before planning.

How Compose maps to Dekka

In Compose On Dekka
A service with image and ports A web service running that image on the first published port, at a public address
A service with image and only expose A web service on that port, reachable inside the environment only
A service with no ports A worker
build A service built from your GitHub repository with the Dockerfile builder, using context as the root directory and dockerfile, target and args as its settings
postgres, postgis, pgvector or timescaledb images A managed PostgreSQL 16 or 17, matching the image's major version
redis, valkey or keydb images A managed Redis with persistence on
A minio image A Dekka bucket
depends_on, links, or a variable naming a database container A connection from the service to that database
command and entrypoint The start command
environment Service variables
The first volumes entry with a container path A 1 GB volume at that path
healthcheck that requests http://localhost/... The health check path
deploy.resources.limits.memory or mem_limit Memory, rounded to a size Dekka offers
deploy.resources.limits.cpus or cpus vCPU, in steps of 0.25
deploy.replicas Replicas, unless the service has a volume
restart The restart policy, with unless-stopped treated as always

Variables that point at databases

Inside Compose, services find each other by container name, such as postgres:5432. On Dekka a connection gives the service its own credentials as variables, so the translation rewrites values that named a database container.

  • A URL such as DATABASE_URL=postgres://user:pass@db:5432/app or REDIS_URL=redis://cache:6379 is dropped, because the connection sets that variable itself.
  • A variable whose value is the container's name, port, user, password or database, such as DB_HOST=db or DB_PASSWORD=${POSTGRES_PASSWORD}, reads the matching connection variable instead, such as ${{web.PGHOST}} or ${{web.PGPASSWORD}}.
  • A URL or host variable that names another service, such as API_URL=http://api:8000, uses that service's private domain, ${{api.DEKKA_PRIVATE_DOMAIN}}.
  • A secret whose value is a placeholder, such as APP_SECRET=replace-me-with-a-random-string, gets a random value that Dekka generates once.
  • Variables Dekka sets itself, such as PORT, keep Dekka's value.

Values from your shell

Compose fills ${VAR} from your shell or a .env file, which Dekka can't see, so the translation turns them into values you enter when you plan.

In Compose On Dekka
${VAR:-default} or ${VAR-default} The default, written into the variable
${VAR}, $VAR or a bare VAR in a list An optional value you can enter, left unset if you don't
${VAR:?message} or ${VAR?message} A required value, with the message as its description
$$ A literal $

Names that look like secrets, such as ones containing PASSWORD, TOKEN or KEY, are entered as secrets. Commands and build arguments can't read these values, so a command or build argument that uses one without a default is left out and the report says so.

Services that build from source

A service with a build section is built from a GitHub repository you choose, with the Dekka GitHub App connected. Every such service in the file uses the same repository and branch, and its context becomes its root directory. Planning without a repository answers 422 repository_required with the services that need one. A remote build context, such as a Git URL, isn't fetched, and dockerfile_inline isn't read, so commit the Dockerfile to the repository instead.

What's left out

Compose setting What to do instead
More than one published port Dekka serves one port per service. Split the other ports into their own services.
UDP ports Dekka serves HTTP and TCP only.
A second volume on a service A service has one volume. Combine the paths under one directory.
env_file Add those variables to the service in Dekka.
secrets and configs Add secrets as secret variables, and put config files in the image or a volume.
extends Copy the settings into the service.
networks and network_mode Every service shares the environment's private network, so nothing is needed.
profiles Every service is included. Remove the ones you don't want before importing.
privileged, cap_add, devices, pid, ipc, sysctls and security_opt Services can't run with host-level access.
working_dir and user Set them in the image's Dockerfile.
extra_hosts, dns and tmpfs Not available.
A health check that isn't an HTTP request Dekka checks GET / instead, or set a health check path in the service's settings.

Settings that make no difference on Dekka, such as container_name, labels, logging and stop_signal, are ignored without a note.

Import with the API

POST /v1/compose/translate returns the blueprint, the report, the resources it would create, the values it needs and whether it needs a repository, and changes nothing.

curl https://api.dekka.cloud/v1/compose/translate \
  -H "Authorization: Bearer $DEKKA_API_KEY" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile content docker-compose.yml '{content: $content}')"

POST /v1/environments/{id}/compose/plan translates the file again and plans it into an environment, returning a changeset. Pass the values it asks for in inputs, and the repository for any build services.

curl https://api.dekka.cloud/v1/environments/$ENV_ID/compose/plan \
  -H "Authorization: Bearer $DEKKA_API_KEY" \
  -H "Content-Type: application/json" \
  -d "$(jq -n --rawfile content docker-compose.yml '{
        content: $content,
        inputs: {N8N_ENCRYPTION_KEY: "your-32-character-key"},
        repository: {full_name: "acme/shop", branch: "main"}
      }')"

Deploy the changeset with its id once you've read the changes.

curl -X POST https://api.dekka.cloud/v1/changesets/$CHANGESET_ID/deploy \
  -H "Authorization: Bearer $DEKKA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"confirm": true}'

A file that isn't valid YAML, has no services or is larger than 200 KB answers 422 invalid_compose. A required value left out answers 422 missing_input with the missing keys, and going over your plan's limits answers 403 entitlement_exceeded.