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
The Compose file appears here as you type.
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 run | compose.yaml | Note |
|---|---|---|
| --name db | container_name: db | Also used as the service name |
| -p 8080:80 | ports: ["8080:80"] | Quoted, so YAML cannot misread it |
| -v pgdata:/data | volumes: ["pgdata:/data"] | Named volumes are added to top-level volumes: |
| -v ./site:/usr/share/nginx/html:ro | volumes: ["./site:/usr/share/nginx/html:ro"] | Bind mounts stay relative to the compose file |
| -e KEY=value | environment: { KEY: value } | Or a - KEY=value list, your choice |
| --env-file .env | env_file: [.env] | |
| --restart unless-stopped | restart: unless-stopped | |
| --network appnet | networks: [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.5 | mem_limit: 1g, cpus: 1.5 | |
| --log-opt max-size=10m | logging: { options: { max-size: 10m } } | |
| --gpus all | deploy.resources.reservations.devices | With capabilities: [gpu] |
| image + args | image: … 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:
| Before | With Compose | What it does |
|---|---|---|
| docker run -d … | docker compose up -d | Creates and starts every service in the background |
| docker stop / docker rm | docker compose down | Stops and removes the containers and the networks it created |
| docker logs -f web | docker compose logs -f web | Follows one service’s logs |
| docker run --rm … cmd | docker compose run --rm web cmd | One-off container from a service definition |
| docker pull … | docker compose pull | Pulls 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
-eend up in the file. Move them to an.envfile next to compose.yaml and write${POSTGRES_PASSWORD}instead. Add.envto 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$VARwhere the shell would have expanded it. - Start order. docker run has no
depends_on. If one service needs another to be ready, adddepends_onwithcondition: service_healthyand a healthcheck on the dependency. - Container names.
container_namestops 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 configbefore you deploy.
More free developer tools
Looking for a full product instead? See DevOps tools on DevHunt.
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.