Docker Run to Compose Converter
Developer Tools ยท Added
A docker run command that has grown to five lines of flags is a container nobody can reproduce. This parses one in your browser and writes the equivalent Compose service โ ports, volumes, environment, limits, healthcheck and the top-level declarations that named volumes and external networks need โ and lists the flags that have no Compose counterpart with the reason, rather than quietly discarding them.
How to use the docker run to compose converter
- 1Paste the full docker run command. Line continuations with a trailing backslash are fine.
- 2Read the generated compose.yaml, then check the 'not carried over' list underneath it.
- 3Copy or download the file, save it as compose.yaml, and start it with docker compose up -d.
- 4Move anything that looks like a credential out of the environment list and into an env_file before committing the result.
Examples
A database with a named volume
- Input
- docker run -d --name pg -e POSTGRES_PASSWORD=secret -p 5432:5432 -v pgdata:/var/lib/postgresql/data postgres:16
- Result
- A pg service with ports, environment and volumes, plus a top-level pgdata volume
The top-level declaration matters: without it Compose creates its own prefixed volume and the existing data is not what the container sees.
Flags with no equivalent
- Input
- docker run -d --rm --name web -p 8080:80 nginx:alpine
- Result
- The service, plus notes that -d and --rm do not map
Detaching is how you invoke Compose rather than a property of the service, and Compose keeps containers so they can be inspected.
A healthcheck
- Input
- docker run --health-cmd "redis-cli ping" --health-interval 10s redis:7
- Result
- healthcheck with test [CMD-SHELL, redis-cli ping] and interval 10s
CMD-SHELL is used because --health-cmd is a shell string, not an argument list.
About the docker run to compose converter
Why the two are not the same shape
A docker run command is an imperative act with a moment attached: start this container now, with these settings, attached to this terminal. A Compose file is a description of a desired state that something else reconciles โ and the difference is exactly why some flags convert cleanly and some cannot convert at all. Ports, volumes, environment and restart policy are all properties of the container that exists afterwards, so they map one to one. Detach, remove-on-exit and interactive attachment are properties of the invocation, and there is nothing in the file to hold them.
Understanding which category a flag falls into makes the conversion predictable. If the flag would still be meaningful about a container that is already running, it has a Compose key. If it only makes sense at the moment of starting, it belongs on the compose command line instead.
The two declarations that are easy to forget
A named volume referenced by a service also has to be declared at the top level of the file, or Compose invents its own project-prefixed volume โ and the data you expected to find is quietly somewhere else. The converter emits that declaration whenever it sees a named volume, which is the difference between a file that works and one that appears to work until you look for the data.
External networks are the same story with an extra decision. A --network flag naming an existing network means an existing network, so the generated file marks it external: true. If instead you want Compose to create the network for this project, delete that line โ the choice is genuinely yours, which is why it is generated with a note rather than assumed silently.
After the conversion
Run docker compose config against the result before anything else. It validates the file, resolves variables and prints the fully expanded configuration, which catches indentation mistakes and unknown keys in a second. Then bring the stack up and compare docker inspect on the new container with the old one if you still have it โ the mounts, environment and network settings should match.
The larger win is not the file itself but what it enables. Once a container is described in a file, it can be reviewed, versioned and extended: a second service alongside it, a depends_on relationship, a healthcheck that gates startup. Almost every multi-container setup began as one long docker run command that somebody finally wrote down.
Frequently asked questions
Why is there no version key at the top of the file?
What happened to my -d flag?
Why does the converter use mem_limit rather than deploy.resources.limits?
Is it safe to paste a command containing a password?
What if my command has a flag this does not know?
Related tools
curl to Code Converter
Developer Tools
Turn a curl command into fetch, axios, Python requests or Node https code.
JSON to YAML Converter
Developer Tools
Convert JSON to YAML or YAML back to JSON, with the ambiguous values quoted.
ENV and INI to JSON
Developer Tools
Convert .env, .ini and .properties files to JSON, and back again.
ASCII Table
Developer Tools
Searchable ASCII reference with decimal, hex, octal, binary and escapes.