ITInfoByte

Docker Run to Compose Converter

Paste one or more docker run commands, as you would type them in bash, PowerShell or cmd, and get a compose.yaml with one service per command. Named volumes and networks are collected at the top level, and every flag that is ignored or has no Compose equivalent is listed below the result rather than silently dropped. The conversion runs in this page, so commands containing passwords never leave your browser.

Runs locally — nothing you enter is sent Developer Free · no signup

How to use

  1. Paste your docker run commands into the left box, one per line. Multi-line commands joined with \ (bash), ` (PowerShell) or ^ (cmd) are fine, and a sudo prefix or a $ prompt is ignored.
  2. Leave "Keep exact volume names" ticked if the containers already have data in named volumes, so Compose reuses those volumes instead of creating new, project-prefixed ones.
  3. Click Convert, or press Ctrl+Enter.
  4. Read the notes under the result: they list flags that were ignored (such as -d and --rm) and flags that have no Compose equivalent.
  5. Copy the YAML or download it as compose.yaml, put it in an empty folder and run docker compose up -d there.

Examples

docker run
docker run -d --name web -p 8080:80 \
  -v "$(pwd)/html:/usr/share/nginx/html:ro" \
  -e TZ=Europe/London --restart unless-stopped nginx:1.27
compose.yaml
services:
  web:
    image: nginx:1.27
    container_name: web
    ports:
      - "8080:80"
    volumes:
      - ./html:/usr/share/nginx/html:ro
    environment:
      TZ: Europe/London
    restart: unless-stopped
Named volume and network
docker run --network backend -v pgdata:/var/lib/postgresql/data postgres:16
→ networks: backend: external: true, and volumes: pgdata: name: pgdata

Supported formats

  • Input: docker run, docker container run, docker create and podman run commands, with options before the image and the container's command after it. Both --flag value and --flag=value work, as do combined short flags such as -itd and -p8080:80.
  • Quoting follows the shell: single quotes, double quotes with backslash escapes (bash) or doubled quotes and backtick escapes (PowerShell). Commands can also be separated with ; or &&, and # comments are skipped.
  • Output: a compose.yaml for the current Compose Specification (Docker Compose v2), with services:, plus networks: and volumes: when they are used. There is no version: line.
  • Mapped flags include --name, -p, -v, --mount, -e, --env-file, --restart, --network, --network-alias, --ip, --hostname, -u, -w, --entrypoint, -l, --cap-add/--cap-drop, --privileged, --device, --dns, --add-host, --ulimit, --memory, --cpus, --pids-limit, --health-*, --log-driver/--log-opt, --tmpfs, --shm-size, --init, -t/-i, --platform, --pull, --read-only, --security-opt, --sysctl, --gpus, --link, --volumes-from and the block-I/O limits.

Privacy

This tool runs entirely in your browser. Nothing you enter or open is sent anywhere. Privacy policy.

Limitations

  • Only docker run style commands are converted. docker network create is used to mark that network as created by Compose; other commands (docker build, docker exec and so on) are skipped with a note.
  • Shell variables such as $HOME are left for Compose to fill in from your environment or a .env file when you run docker compose. A $ that was literal in the shell (inside single quotes or escaped) is written as $$ so Compose does not treat it as a variable. Command substitutions other than $(pwd) are copied as text.
  • In bash-style input, a backslash before a letter or digit is kept, so unquoted Windows paths such as C:\data survive; strictly, bash would remove it.
  • Without --network, docker run uses Docker's default bridge network, but Compose puts services on a project network where they can reach each other by service name. That is usually what you want, but it is a behaviour change.
  • -P (--publish-all), --cidfile, --cpuset-mems, --cpu-count and --cpu-percent have no Compose equivalent and are reported, not converted. Unknown or future flags are reported too; if one takes a value, check that the image name was read correctly.
  • The output is not checked against your Docker version. Run docker compose config to validate it before you rely on it.

FAQ

Why is there no version: line at the top?

The top-level version key is obsolete. Docker Compose v2 follows the Compose Specification, which ignores it and prints a warning that the attribute is obsolete. Leaving it out gives the same result with no warning.

Why are the ports in quotes?

YAML 1.1 parsers read some unquoted values of the form number:number, such as 22:22, as base-60 numbers, which breaks the port mapping. Docker recommends quoting port mappings, so every port is written as a string. The same rule quotes environment values such as yes, no, on, 1 or 0755, because Compose needs them as text.

Are --memory and --cpus written under deploy.resources?

No. They become the service-level mem_limit and cpus attributes (with mem_reservation, memswap_limit and pids_limit for the related flags), which map one-to-one to docker run and are applied by a plain docker compose up. deploy.resources.limits also works in Compose v2, but it is aimed at Swarm-style deployments. --gpus is the exception: Compose expresses GPUs only as deploy.resources.reservations.devices, so that is what you get.

Why does a named volume get a name: line?

Compose normally prefixes volume names with the project name, so a volume called pgdata becomes myproject_pgdata, which is empty. With "Keep exact volume names" ticked, each named volume gets name: pgdata, so Compose uses the volume your docker run containers already wrote to. Untick it for a fresh setup.

Why are my networks marked external: true?

A network passed with --network had to exist before docker run, so it is marked external and Compose expects it to exist too. If your paste includes docker network create for it, the converter instead declares it with name: so that Compose creates it. host, none and container:<name> become network_mode, and container:<name> becomes service:<name> when that container is in the same paste.

Are my commands sent anywhere?

No. The parsing and the YAML output are done by JavaScript in this page, with no network requests, so environment variables and passwords in the command stay on your device.