docker run to docker-compose
Convert docker run commands into a docker-compose.yml file.
Related Tools
Convert a docker-compose.yml into docker run commands.
Convert a docker-compose.yml into Kubernetes Deployment and Service manifests.
Convert a .env file into a docker-compose environment section.
Format and validate YAML with 2-space or 4-space indentation.
Convert a .env file into a base64-encoded Kubernetes Secret manifest.
Convert a .env file into gh secret set commands for GitHub Actions.
Documentation
What is docker run to docker-compose?
This tool reads one or more docker run invocations and generates the equivalent docker-compose.yml services: block — useful when a project started as a handful of ad-hoc docker run commands (in a README, a shell script, your shell history) and has grown to the point where a proper compose file is worth having.
How it works
Each docker run command (commands are separated by a blank line for multi-service input) is tokenized the same way a shell would split it — respecting quoted arguments — then walked flag by flag. -p/--publish becomes a ports: entry, -e/--env becomes an environment: entry, and -v/--volume becomes a volumes: entry — a direct, lossless mapping in every case, since compose's syntax for each of these is a superset of what docker run's flags can express. The image name becomes the service's image: field, and any positional arguments after the image become the service's command:. --name becomes the service key directly if present; if it's missing, a name is derived from the image (its last path segment, with the tag stripped), and that inference is called out in a comment at the top of the generated file rather than silently presented as if --name had been there all along.
Features
- Multiple
docker runcommands in one paste, each becoming its own service -p,-e, and-vmapped directly to their compose equivalents- Container command (anything after the image) preserved as
command: - Missing
--namehandled by inferring a service key from the image, with an explicit comment noting it - Copy or download the generated
docker-compose.yml
Example
Input:
docker run -d --name web -p 8080:80 -e NODE_ENV=production -v ./html:/usr/share/nginx/html nginx:latest docker run -d --name db -p 5432:5432 -e POSTGRES_PASSWORD=secret -v db-data:/var/lib/postgresql/data postgres:15
Output:
services:
web:
image: nginx:latest
ports:
- "8080:80"
environment:
- NODE_ENV=production
volumes:
- ./html:/usr/share/nginx/html
db:
image: postgres:15
ports:
- "5432:5432"
environment:
- POSTGRES_PASSWORD=secret
volumes:
- db-data:/var/lib/postgresql/dataCommon errors
A docker run command with no positional image argument at all — for example one where every token was consumed as a flag or its value — produces an error rather than a service with a blank image: field, since a compose service with no image and no build context isn't a valid service. Two commands that don't set --name and happen to use images with the same last path segment (e.g. org1/api:1.0 and org2/api:2.0) get de-duplicated service keys (api, api-2) rather than one silently overwriting the other in the output.
Best practices
Treat the generated file as a starting point, not a finished compose setup: it has no depends_on, restart policy, health check, or network configuration, because docker run commands never carried that information to begin with — there's nothing here to lose, but there's also nothing here to gain for free. Add those manually once you have the base file, and run docker compose config to validate the result before relying on it.
Frequently Asked Questions
Can I convert more than one docker run command at once?▾
Yes — separate each docker run command with a blank line, and each becomes its own service in the generated services: block.
What happens if a command has no --name?▾
A service key is derived from the image name (the last path segment, tag stripped) — for example postgres:15 becomes postgres, and ghcr.io/acme/api-server:latest becomes api-server. A comment above the compose file notes which service names were inferred this way rather than pretending --name was there.
Does this recreate depends_on, restart policies, or a build context?▾
No — docker run has no equivalent to any of these, so there's nothing to recover. If your actual stack needs startup ordering or restart policies, you add those to the generated compose file by hand; docker run alone never carried that information in the first place.
What flags does this tool actually read?▾
--name, -p/--publish, -e/--env, and -v/--volume — the flags that have a direct docker-compose equivalent. Everything else (like -d, --rm, --network) is parsed and discarded rather than guessed into a compose field it doesn't map onto cleanly.