Free tool

Docker run to Docker Compose converter

Paste one or more docker run commands and get the matching compose.yaml as you type. Ports, volumes, environment, networks, healthchecks, logging and resource limits are mapped, anything Compose cannot express is listed as a note, and you can switch the direction to turn a Compose file back into docker run.

Free · no sign-up · runs in your browser, nothing is uploaded

docker run commands
compose.yaml

The Compose file appears here as you type.

Drop a shell script with docker run commands, or a compose.yaml, or click to pick one.

Commands and files stay in this tab. They are not added to the page URL, since they often contain passwords.

How docker run flags map to Compose keys

A docker run command describes one container. A Compose file describes the same container as a service under services:, with one key per flag. These are the flags people use most:

docker runcompose.yamlNote
--name dbcontainer_name: dbAlso used as the service name
-p 8080:80ports: ["8080:80"]Quoted, so YAML cannot misread it
-v pgdata:/datavolumes: ["pgdata:/data"]Named volumes are added to top-level volumes:
-v ./site:/usr/share/nginx/html:rovolumes: ["./site:/usr/share/nginx/html:ro"]Bind mounts stay relative to the compose file
-e KEY=valueenvironment: { KEY: value }Or a - KEY=value list, your choice
--env-file .envenv_file: [.env]
--restart unless-stoppedrestart: unless-stopped
--network appnetnetworks: [appnet]host, none and container:x become network_mode
--health-cmd "…"healthcheck: { test: ["CMD-SHELL", "…"] }With interval, timeout, retries, start_period
--memory 1g --cpus 1.5mem_limit: 1g, cpus: 1.5
--log-opt max-size=10mlogging: { options: { max-size: 10m } }
--gpus alldeploy.resources.reservations.devicesWith capabilities: [gpu]
image + argsimage: … and command: […]Arguments after the image become command

The converter knows the other run flags too (capabilities, devices, ulimits, sysctls, DNS, hosts, labels, user, workdir, entrypoint and more). A flag it cannot map is never dropped silently: it shows up under Notes with the reason.

From several containers to one stack

The usual reason to convert is a set of containers you start by hand. Paste the whole script, including docker network create, and each docker run becomes a service in one file:

docker network create appnet
docker run -d --name postgres --network appnet -e POSTGRES_PASSWORD=secret postgres:16
docker run -d --name web --network appnet -p 3000:3000 ghcr.io/acme/web:latest

becomes

services:
  postgres:
    image: postgres:16
    container_name: postgres
    environment:
      POSTGRES_PASSWORD: secret
    networks:
      - appnet
  web:
    image: ghcr.io/acme/web:latest
    container_name: web
    ports:
      - "3000:3000"
    networks:
      - appnet
networks:
  appnet: {}

Inside a Compose network, services reach each other by service name, so web can connect to postgres:5432. If the network already exists outside Compose, keep the "Networks already exist" option on and it is written as external: true instead.

Running the converted file

Save the output as compose.yaml and use the Compose commands instead of docker run:

BeforeWith ComposeWhat it does
docker run -d …docker compose up -dCreates and starts every service in the background
docker stop / docker rmdocker compose downStops and removes the containers and the networks it created
docker logs -f webdocker compose logs -f webFollows one service’s logs
docker run --rm … cmddocker compose run --rm web cmdOne-off container from a service definition
docker pull …docker compose pullPulls new images for all services

docker compose down keeps named volumes. Add -v only when you really want the data gone. Run docker compose config to see the file exactly as Compose reads it, with variables filled in.

Things to check after converting

  • Secrets. Passwords in -e end up in the file. Move them to an .env file next to compose.yaml and write ${POSTGRES_PASSWORD} instead. Add .env to your .gitignore.
  • Dollar signs. Compose fills in ${VAR} from your shell and .env. A literal $ must be written as $$. The tool does this for values that were single-quoted or escaped in the shell, and keeps $VAR where the shell would have expanded it.
  • Start order. docker run has no depends_on. If one service needs another to be ready, add depends_on with condition: service_healthy and a healthcheck on the dependency.
  • Container names. container_name stops you from scaling a service to more than one container. Remove it if you do not need a fixed name.
  • Validate. Paste the result into the YAML validator or run docker compose config before you deploy.

FAQ

How do I convert a docker run command to docker compose?+

Paste the command into the box above and the compose.yaml appears on the right. Each flag becomes a service key: -p becomes ports, -v becomes volumes, -e becomes environment, --restart becomes restart and the image becomes image. Save the file as compose.yaml and run docker compose up -d in the same folder.

Can I convert several docker run commands into one Compose file?+

Yes. Paste them one after another, separated by new lines, ; or &&. Each command becomes its own service, named after --name or the image. docker network create and docker volume create lines become top-level networks and volumes that Compose manages. To extend a file you already have, turn on "Add to an existing compose.yaml" and paste it: the new services are added next to the old ones.

What happens to -d and --rm?+

Neither is a service key. -d (detached) is chosen when you start the stack: docker compose up -d. --rm has no equivalent because Compose removes containers with docker compose down. For one-off containers, docker compose run --rm <service> still exists.

Do I still need the version line at the top of docker-compose.yml?+

No. The Compose Specification says the top-level version element is obsolete, and current Docker Compose ignores it and prints a warning. This tool leaves it out.

Should the file be called compose.yaml or docker-compose.yml?+

Both work. The Compose Specification prefers compose.yaml in the working directory; compose.yml, docker-compose.yaml and docker-compose.yml are still read for backwards compatibility.

Can I convert docker-compose.yml back to docker run?+

Yes. Switch the direction to Compose → docker run and paste the file. You get one docker run command per service, in depends_on order, plus docker network create lines for the networks it needs. Services that relied on the Compose default network are put on a shared network so they can still reach each other by name. Keys with no docker run flag, like profiles and secrets, are listed as notes.

Why are my ports in quotes?+

YAML 1.1 parsers read some unquoted values like 22:22 as base-60 numbers, so the Compose docs recommend quoting port mappings. The tool quotes every port and any value YAML could misread, such as yes, no, on or off.

Is my command uploaded anywhere?+

No. Parsing and conversion run in your browser. The commands are not put in the page URL either, because docker run lines often contain passwords in -e flags.

Sources: Compose Specification: services · Compose Specification: version and name · Compose file reference · docker container run reference · docker compose up · docker compose run · compose-spec on GitHub. Checked October 2026.