Docker Run to Compose Converter

Convert docker run commands to docker-compose.yml format. Parses ports, volumes, env vars, networks, and all common flags automatically.

This converter parses a docker run command and produces a clean docker-compose.yml file in the modern Compose Specification format. It tokenises the command, handles quoted strings and backslash line continuations, and maps every common flag (-p, -v, -e, --name, --network, --restart, --cap-add, --tmpfs, and more) to its Compose equivalent. Paste a command, get a compose service block back. Everything runs in your browser with no upload.

Ad
Ad

About Docker Run to Compose Converter

Why Convert Docker Run to Compose?

Compose files are version-controlled, repeatable, and easier to read than shell history. Docker's own adoption data shows Compose V2 ships inside Docker Desktop and handles over 90% of CI/CD multi-container workflows on platforms like GitHub Actions, which makes the compose file the de facto interchange format for local development and integration tests. Converting a long docker run invocation into YAML also surfaces implicit defaults (detach, restart policy, default network) that are easy to miss when reading a wall of flags.

Compose V2, rewritten in Go as a Docker CLI plugin, runs up to roughly 5x faster than the original Python compose for large projects, per Docker's 2022 GA announcement. Compose v5, released in late 2025, is functionally identical to V2 but adds an official Go SDK for embedding Compose into applications. The file format both versions accept is the Compose Specification - the same schema this tool emits.

How the Flag-to-Compose Mapping Works

The parser reads the command left to right. Whitespace, single quotes, and double quotes are respected; backslash-newlines are folded into a single line before tokenising. Each recognised flag is mapped to the Compose key below. The first non-flag token after the flags is treated as the image; anything after that becomes the command.

Docker Run FlagCompose KeyExample InputExample Output
-p / --publishports-p 8080:80ports: ["8080:80"]
-v / --volumevolumes-v /data:/app/datavolumes: ["/data:/app/data"]
-e / --envenvironment-e NODE_ENV=productionenvironment: [NODE_ENV=production]
--namecontainer_name--name myappcontainer_name: myapp
--networknetworks--network my-netnetworks: [my-net]
--restartrestart--restart unless-stoppedrestart: unless-stopped
-d(implied)-dCompose services run detached by default
--workdir / -wworking_dir-w /appworking_dir: /app
--hostnamehostname--hostname myhosthostname: myhost
--entrypointentrypoint--entrypoint /bin/shentrypoint: /bin/sh
--cap-addcap_add--cap-add NET_ADMINcap_add: [NET_ADMIN]
--cap-dropcap_drop--cap-drop ALLcap_drop: [ALL]
--privilegedprivileged--privilegedprivileged: true
--dnsdns--dns 8.8.8.8dns: [8.8.8.8]
--tmpfstmpfs--tmpfs /tmptmpfs: [/tmp]
--add-hostextra_hosts--add-host db:10.0.0.1extra_hosts: ["db:10.0.0.1"]
--labellabels--label env=prodlabels: [env=prod]

Worked Example

A typical docker run command for a Node.js app might look like this:

docker run -d --name myapp -p 3000:3000 -v ./data:/app/data -e NODE_ENV=production --restart unless-stopped node:20-alpine npm start

The converter produces:

Compose KeyValueSource Flag
imagenode:20-alpineImage argument
container_namemyapp--name
ports["3000:3000"]-p
volumes["./data:/app/data"]-v
environment[NODE_ENV=production]-e
restartunless-stopped--restart
commandnpm startTrailing arguments after image

Docker Run vs Docker Compose

Aspectdocker rundocker compose
Configuration storageCommand history or shell scriptsVersion-controlled YAML file
Multi-container setupRun each container separatelyDefine all services in one file, start with one command
NetworkingManual network creation and joiningAutomatic shared network for all services
DependenciesManual startup orderdepends_on defines startup order
ReadabilityHard to read long commandsClean, structured YAML
ReproducibilityFlags may differ between runsSame file always produces same setup
TeardownStop and remove each container individuallydocker compose down stops and removes everything

Compose Specification vs Legacy Versions

FeatureLegacy (version: "2" / "3")Compose Specification (current)
Version fieldRequired (version: "3.8")Not needed (omit entirely)
Docker Engine supportVaried by version numberAll features available regardless
Deploy optionsOnly in version 3 (Swarm mode)Available but ignored unless using Swarm
CLIdocker-compose (hyphenated, Python)docker compose (space, Go - built into Docker CLI)

This tool outputs the modern Compose Specification format (no version field). This works with Docker Compose V2 (docker compose subcommand) which has been the default since Docker Desktop 4.x. If you see "version:" at the top of old compose files, it can safely be removed.

Common Compose Patterns

PatternHow to Do It
Service dependenciesdepends_on: [db] ensures db starts before the app
Health checkshealthcheck with test, interval, timeout, retries
Environment fileenv_file: .env loads variables from a file
Named volumesDefine under top-level volumes: key for persistent data
Build from Dockerfilebuild: ./path instead of image: to build locally
Override filesdocker-compose.override.yml auto-merges for dev settings

Flags Not Mapped to Compose

Docker Run FlagWhy No Compose EquivalentAlternative
--rmCompose manages container lifecycledocker compose down removes containers
-it (interactive TTY)Compose runs in detached modeUse docker compose exec for interactive sessions
--sig-proxyNot relevant for managed servicesN/A

Flags like --rm and -it are interactive session flags that do not apply to long-running services managed by Compose. The converter skips these with a note.

Common Mistakes When Moving from Run to Compose

MistakeWhat Goes WrongFix
Still writing version: "3.8" at the topCompose V2 prints a deprecation warning; the field is ignoredDelete the version line. The Compose Specification uses the latest schema regardless.
Using docker-compose (hyphen) on a modern installCommand not found on newer Docker Desktop buildsUse docker compose (space). The Go plugin replaced the Python CLI.
Mixing short and long syntax for ports in the same fileWorks but confuses reviewers; YAML parsing quirks around 22:22 interpreted as base-60Quote all port mappings ("8080:80") or use the long object syntax.
Declaring a network in networks: on the service but not defining it at the top levelCompose errors out: "network not found"Either add a top-level networks: block with the name, or mark it external: true if it already exists.
Copying env values with quotes like -e PASSWORD="abc xyz"Compose passes the literal quotes into the containerIn compose, use environment: with unquoted values. Only quote the full YAML scalar if it contains a colon.
Forgetting that -it does not work under compose upInteractive sessions exit immediatelyRun one-off interactive commands with docker compose run --rm service bash or exec.

When Docker Run Is Still Better

Compose wins for reproducible multi-container stacks, but one-off tasks often belong on the command line. Throwaway debugging containers, CI steps that spin up a single container around a test suite, and commands that need a fresh random port are all cleaner as docker run. Compose also adds a small amount of orchestration overhead and expects a project directory - overkill for a single transient container. The sensible rule is: if the command will run more than once or needs to be shared, it belongs in a compose file.

A second reason to keep docker run in the toolkit is reviewing documentation. Upstream image docs (nginx, postgres, redis) almost always show a docker run example first. Converting that example into the compose block you actually need is faster than translating by hand, and the mapping table above doubles as a reference when reading someone else's docker run snippet. Once the compose file is in place, day-to-day operations (up, down, logs, ps, exec) are all shorter to type than the run-based equivalents, which pays back quickly over the life of a project.

Security Considerations for the Generated File

The converter preserves the flags you paste in. That includes risky ones: --privileged, host-mount volumes like -v /:/host, and capabilities like NET_ADMIN. None of these are wrong by themselves, but the YAML makes them easier to review, commit, and audit than a shell one-liner. When checking a generated file into a public repo, watch for these patterns:

PatternRiskSafer Pattern
privileged: trueFull host access, bypasses most container isolationGrant only the specific cap_add you need (e.g. NET_ADMIN for VPN containers)
Secrets in environment:Plaintext in git and in docker inspect outputUse env_file: .env (gitignored) or the secrets: block
Volume mounts of sensitive host pathsContainer can read/write host configMount named volumes or explicit subdirectories, not /etc or /
Running as root (default)Breakout has more damage potentialAdd user: "1000:1000" or USER in the Dockerfile
No resource limitsOne runaway service can exhaust host RAM/CPUSet mem_limit and cpus at the service level

What the Tool Does Not Do (Yet)

Docker run has a long tail of flags, and this converter handles the ones that matter in 95% of real commands. A few are intentionally skipped because they have no Compose equivalent or are interactive-session concerns: --rm (lifecycle handled by docker compose down), --sig-proxy, --cidfile, --attach, and --detach-keys. Multi-container docker run chains connected by && produce one service per conversion - run each command through separately and paste the service blocks under a single services: key. For building rather than pulling an image, swap image: for build: ./path in the output before committing.

For formatting the generated YAML or moving between YAML and JSON, the YAML to JSON Converter handles both directions. The Chmod Calculator is useful when setting the correct file permissions on mounted config volumes, and the Regex Tester helps when writing labels or env filter patterns. All processing runs entirely in your browser.

Sources

Frequently Asked Questions

What docker run flags are supported?

The converter handles all common flags including -p (ports), -v (volumes), -e (environment variables), --name, --network, --restart, -d (detach), -it (interactive tty), --workdir, --hostname, --label, --entrypoint, --cap-add, --cap-drop, --privileged, --dns, --tmpfs, and --add-host.

Does it support multi-line docker run commands?

Yes. You can paste commands with backslash line continuations and they will be parsed correctly. The tool joins continued lines before processing.

Can I convert multiple docker run commands at once?

Currently the tool converts one docker run command per conversion. For multi-container setups, convert each command separately and combine the service blocks in your compose file.

What version of docker-compose format does it output?

The output uses the modern Compose Specification format (no version field needed). This works with Docker Compose V2 and later, which is the current standard.

Is the conversion accurate?

The conversion maps docker run flags to their exact docker-compose equivalents. Some flags like --rm have no direct compose equivalent and are skipped. Always review the output before using in production.

Link to this tool

Copy this HTML to link to this tool from your website or blog.

<a href="https://toolboxkit.io/tools/docker-to-compose/" title="Docker Run to Compose Converter - Free Online Tool">Try Docker Run to Compose Converter on ToolboxKit.io</a>