Paste a docker run command and instantly get a production-ready docker-compose.yml. Switch modes to convert Compose files back to docker run commands.
Quick Presets
docker run command
docker-compose.yml
Output will appear here
Paste a command in the left panel to convert it.
A docker run command only exists in your shell history. Once you close the terminal or switch machines, those flags are gone unless you wrote them down somewhere. A docker-compose.yml file belongs in your repository next to your application code, so every configuration decision is tracked in version control. If something breaks, you can compare the current Compose file against the last working commit and see exactly what changed. For anything you intend to run more than once, converting to Compose is the right call.
Most docker run flags have a direct Compose counterpart. The -p flag maps to entries under ports, written as "host:container". The -e flag maps to entries under environment. The -v flag maps to entries under volumes for both bind mounts and named volumes. The --name flag becomes container_name. The --restart flag maps directly to restart with the same values: no, always, unless-stopped, on-failure. The --network flag becomes network_mode or a reference to a named network under the top-level networks section. The conversion is mostly mechanical once you know the mapping.
docker run on the default bridge network gives containers no name-based way to find each other at all. You either hardcode IP addresses, use the deprecated --link flag, or explicitly run docker network create and attach every container to that network with --network before name resolution works. That docker network create step is easy to lose when converting, because it isn't a flag on either docker run command. It's a separate command that already ran before either container started, so a flag-by-flag translation has nothing to map it to.
Compose replaces all of that with a network it creates automatically, where every service in the file can resolve every other service by its service name through Docker's built-in DNS. That's the trap: DNS resolves by service name, not by the --name you gave the container. If your original setup named a container redis-test and another container's environment variable reads HOST=redis-test, converting to a Compose service named redis breaks that lookup, because nothing in the new file is named redis-test anymore. Either pin the old name with container_name: redis-test, or update the environment variable to HOST=redis to match the service name, which is the more idiomatic Compose approach. This is the single most common surprise after a docker run to Compose conversion, and it's why translating the topology, not just the flags, is what actually matters.
Keep secrets out of your Compose file by using environment variable substitution with a .env file rather than hardcoding passwords directly in the YAML. Use named volumes for any data you want to persist across container recreations rather than bind-mounting a specific host path, since named volumes work consistently across machines. Pin your image tags to a specific version like postgres:15-alpine rather than latest so you know exactly what you are running. If you have multiple services, use depends_on with service_healthy to make sure dependent services wait until their dependencies are actually ready, not just started.
Save the output as docker-compose.yml in your project directory and run docker compose up -d to start all services in the background. From there docker compose logs tails the output, docker compose ps shows what is running, and docker compose down tears everything down cleanly including the network Docker created for you. If your Compose file defines named volumes that hold data you want to keep, use docker compose down without the --volumes flag or it will delete them. If you need YAML for your other config files, try our JSON to YAML converter. For generating project-specific ignore rules, use our gitignore generator.