Docker Run to Docker Compose Converter
Paste docker run commands, get a Compose file — or turn a Compose file into commands.
Paste one or more docker run commands (line continuations with \, ^ or ` are fine). docker network create and docker volume create lines become definitions too.
Check these
About the Docker Run to Docker Compose Converter
Paste one or more docker run commands — straight from a README, a shell script or your history — and get a compose.yaml that follows the Compose Specification: ports, volumes and mounts, environment and env files, networks with aliases and fixed IPs, restart policy, health check, logging, ulimits, CPU, memory and GPU limits. Several commands become several services in one file, docker network create and docker volume create lines become network and volume definitions, and the obsolete version: key is left out.
The other direction works too: paste a Compose file and get the docker network create, docker volume create, docker build and docker run commands that start the same containers. Options that have no equivalent are listed under the result — and as comments in the file — with the reason, never dropped silently. Everything runs in your browser.
How to use it
- Choose docker run → Compose or Compose → docker run.
- Paste the commands or the Compose file, open a file, or press Load sample. The result updates as you type.
- Pick the output style: environment as a map or a list, limits as service attributes or
deploy.resources, whether volume and network names are kept, and whether--networknetworks already exist. - Read Check these under the result: every option that was changed or could not be converted is listed with its input line.
- Copy the result or download
compose.yaml(start it withdocker compose up -d) orrun.sh.
Examples
docker run -d --name web -p 8080:80 -v "$(pwd)/site":/usr/share/nginx/html:ro --restart unless-stopped nginx:1.27
services:
web:
image: nginx:1.27
container_name: web
restart: unless-stopped
ports:
- "8080:80"
volumes:
- ./site:/usr/share/nginx/html:ro$(pwd) becomes ., because Compose resolves relative paths from the folder of the Compose file. -d is not part of the file: run docker compose up -d.
docker run -e API_URL=${API_URL:-http://localhost} -e PRICE='$5' -e DEBUG=no imgservices:
img:
image: img
environment:
API_URL: ${API_URL:-http://localhost}
PRICE: $$5
DEBUG: "no"The variable stays a variable (Compose reads it from your environment or a .env file); the single-quoted $5 was literal, so it is written $$5. no is quoted so YAML 1.1 parsers do not read it as false.
services:
cache:
image: redis:7
command: ["redis-server", "--appendonly", "yes"]
volumes:
- redis-data:/data
volumes:
redis-data:docker network create app_default docker volume create redis-data docker run -d \ --name cache \ -v redis-data:/data \ --network app_default \ --network-alias cache \ redis:7 redis-server --appendonly yes
The network is the one Compose creates for a project (named app_… when the file has no name:): on it, containers reach each other by service name, which Docker’s default bridge network cannot do.
Common uses
- Turning the docker run line from a project’s README into a Compose file you can keep in the repository.
- Moving containers you started by hand on a server (with their volumes and networks) to docker compose.
- Running a service from a Compose file on a machine without Compose, or debugging one container with plain docker run.
What is converted
All 103 options of docker container run in the Docker CLI reference are recognised. They map to their Compose attributes: -p → ports, -v and --mount → volumes (short syntax when it can hold the options, else the long syntax with bind, volume and tmpfs settings), -e / --env-file → environment / env_file, --network, --network-alias, --ip, --ip6, --mac-address → networks or network_mode, --health-* → healthcheck, --log-driver / --log-opt → logging, --ulimit → ulimits, --gpus → a GPU device reservation, --cpus, -m, --pids-limit → limits, --link → links (or external_links for a container the pasted commands do not start), and so on for capabilities, devices, DNS, sysctls, security options, users, namespaces and block-IO limits.
Shell syntax is read like bash: quotes, escapes, $'…', \ line continuations (and ^ / ` ` from Windows), sudo, docker container run, docker create and podman. Redirections such as > out.log, 2>&1 and here-documents (<<EOF`) only change where input and output go, so they are left out with a note.
What has no Compose form
--rm: Compose keeps containers untildocker compose down; for one-off containers usedocker compose run --rm <service>.-d,-a,--detach-keys,--sig-proxy,-q: these are about how you start the command, not the container.-P(publish every exposed port at random): list the ports instead.--cidfile,--cpuset-mems,--umask,--io-maxbandwidth,--io-maxiops: the Compose Specification has no attribute for them.- Shell command substitutions such as
$(hostname): Compose does not run commands, so they are kept as text with a warning;$(pwd)and${PWD}are understood.
The Docker CLI also refuses some combinations, and the notes say so: --rm with --restart, ports or a hostname on a container that shares another container’s network.
Compose → docker run
The commands do what docker compose up -d does, step by step: networks and volumes are created first, images with build: are built (docker build -t …), and services start in depends_on order. Services that name no network join a project network with their service name as an alias, so they can still reach each other by name. Relative bind mounts become "$(pwd)/…" because docker run needs absolute paths, file-based secrets and configs are mounted read-only at /run/secrets/<name> (as Compose does without Swarm), and an entrypoint list becomes --entrypoint plus leading arguments. Unknown keys get a “did you mean” suggestion. Health-based depends_on conditions, deploy replicas and other Swarm settings, profiles and develop have no docker run form and are listed.
How the results were checked
Every Compose file produced in the test suite is validated against the official Compose Specification JSON schema, and generated docker scripts are re-read word by word. The sample scripts were also run in bash with a stand-in docker command to confirm that each argument arrives exactly as intended — quotes, $ signs, $(pwd) paths with spaces and all.
Limitations
- Only the commands are converted: images are not inspected, so what an image sets itself (exposed ports, its own HEALTHCHECK, volumes) does not appear in the file.
- Compose names networks and volumes after the project (myapp_data) unless they set
name:; keep the Docker names (the default) to reuse the data of containers you started with docker run. - Shell variables are kept as Compose variables; set them in your environment or a
.envfile next tocompose.yaml. - Swarm-only settings (
deployreplicas, placement, update and rollback settings) have no docker run equivalent.
Privacy
Everything happens in your browser. What you enter or open here is not uploaded or stored by MySmartCoPilot.
Frequently asked questions
Why is there no version: line?
The Compose Specification made version obsolete: current Docker Compose ignores it and warns that it is obsolete. Files without it work with every Compose v2 release.
Why are my networks marked external: true?
docker run only joins networks that already exist, so the faithful conversion tells Compose to use the existing network rather than create a new one. Choose Created by Compose if you want docker compose up to create it. Networks created with docker network create in the pasted commands are defined in the file with their subnet and driver.
Why did $ become $$?
Compose replaces $NAME and ${NAME} with variables from your environment. A literal dollar sign (from single quotes or \$ in the shell) must be written $$ in a Compose file, or Compose would try to substitute it.
Is it the same as composerize?
It does the same job, and the reverse (Compose → docker run) on the same page. It knows every option of today’s docker run (GPUs, health checks, block IO, the advanced --network syntax), keeps shell quoting and variables correct, and lists each option it cannot convert with the reason. It runs in your browser, with nothing uploaded.
Should the file be called docker-compose.yml or compose.yaml?
Both work. The Compose Specification prefers compose.yaml and Docker Compose looks for it first; docker-compose.yml is still read for backward compatibility.