Docker/Podman Composer — Tips & Tricks

The converter's limits, round-trip loss, which flags get dropped, and how to combine the Composer with cheat sheets and other JPKCom tools.

Back to the overview: Docker/Podman Composer · Open the tool live: www.jpkc.com/tools/docker/

The manual lists every flag, the examples show the walkthroughs. This page is about what both assume: where the converter deliberately has limits, what gets lost in a round trip, and how to get the most out of the tool.

What the converter does NOT map

The Composer is a text-to-text translator. Some things fall away in the process by design — not a bug, but the nature of the two formats. The important part: the tool reports most of what it leaves out in the notes list below the output — but not everything. Sub-keys of known Compose keys such as build.cache_from or deploy.placement, and the network create options --scope, --aux-address, and --ipv4, are dropped without a note (details in the manual). Read the list before you adopt the result, and with complex files compare input and output.

  • --rm has no Compose equivalent — Compose keeps stopped containers. For one-off runs, use docker compose run --rm. -d/--detach is dropped silently because it's implicit in Compose; in the other direction, Compose → Run always adds a -d.
  • -P/--publish-all and options such as --cidfile, --kernel-memory, --volume-driver, or the Podman options --pod and --systemd have no Compose key and are dropped with a note.
  • Unknown flags are skipped and reported. If such a flag expects a value, the tool may mistake that value for the image — the note then names the word in question. Write such flags as --flag=value and the assignment is unambiguous.
  • Pipes, redirections, and command substitution (| tee log, > out, $(pwd)) belong to the shell, not the container. Everything after | or > on that line is ignored, and $(…) is kept as plain text.

Compose-only: what you add by hand after conversion

Some Compose constructs can't be derived from a run command — and get lost in full or in part going Compose → Run. The Reference tab lists them as "Compose-only Features":

  • depends_on — on Run → Compose you add it by hand. In the reverse direction the tool orders the commands accordingly, but doesn't check conditions like service_healthy.
  • build — on Run → Compose you add it by hand. In the reverse direction it becomes a docker build -t … in front of the run.
  • profiles, deploy.replicas, and scale — ignored with a note on Compose → Run; every run starts exactly one container.
  • secrets / configs — variants with file: become read-only mounts on Compose → Run, secrets under /run/secrets/<target>, configs at /<target> (an absolute target is used as is); those from environment:, with content:, or from Swarm don't.

You no longer have to write top-level networks and volumes yourself: the tool declares them on Run → Compose (as external: true or, if docker network create/docker volume create is part of the input, with the exact name:) and creates them in the script on Compose → Run.

The practical trick: the YAML output in the run tab is editable ("editable" badge). Convert your run commands first, then type a depends_on or a build: block right inside the tool before you copy the file or download it as compose.yaml. But careful: if you then change the input or the project name, the tool recalculates and overwrites your additions.

Round trip isn't lossless

If you convert a command to Compose and then back to run, you won't necessarily get your exact input back:

  • Dropped flags don't come back. --rm, -P, and unknown flags are gone after the first step.
  • -d is re-added. Compose → Run puts a -d on every command, even if the original had none.
  • The network changes. A docker run without --network runs in the default bridge network. On the way back, the container lands in the network <project>_default, as with Compose, and gets its service name as --network-alias. Without --name, it's called <project>-<service>-1.
  • The health-check form changes. --health-cmd "…" becomes test: [CMD-SHELL, …]. If you import a Compose file with ["CMD", …], the tool joins the words, each shell-quoted, into one --health-cmd and points out that docker run only knows the shell form — the image needs /bin/sh for it.
  • Order and quoting change. Flags appear in a fixed order, each on its own line. In YAML, ports and numeric strings are quoted ("8080:80", "3600"); in the script, literal values sit in single quotes. Semantically identical, but it looks different from your original.

Bottom line: use the Composer as a starting point and scaffold, not as a bit-exact round trip. Give the result a once-over before it goes to production.

Small knacks

  • Several commands at once. Paste a whole setup snippet from a tutorial into the input field — docker network create and docker volume create included. Every run becomes a service, and the networks and volumes end up properly declared in the same file. sudo, comments, and commands like docker ps don't get in the way.
  • Break long commands with a backslash. The tokenizer understands \ line continuations and shell quoting, so you can paste a copied multi-line command unchanged. --flag=value, --flag value, and bundles like -dp 80:80 all work.
  • Set the project name. Enter the name you'll later start docker compose under in the Compose project name field (otherwise Compose uses the folder name). Then the network, volume, and container names in the script match what Compose would create — important when you mix Compose with containers started by hand.
  • Check the result. docker compose config reports undefined networks and volumes and shows the file the way Compose understands it. You can check the generated script for syntax errors with sh -n run.sh before running it.
  • run.sh instead of Copy. The download comes with #!/bin/sh and set -e — the script stops at the first error instead of carrying on with the next container. Networks are only created if they're missing (network inspect … || network create …), so an existing network doesn't break the run.
  • Export your variables. If ${VAR} stays in the script, the shell fills in the value — Compose would also have read it from .env. Export the variables beforehand, for example with set -a; . ./.env; set +a.
  • Privacy included. Because everything runs client-side and nothing is sent anywhere, you can convert commands with passwords, tokens, or internal hostnames without worry. Only the project name and the runtime choice are stored. Still: in the real Compose file such values belong in a .env file or in secrets, not in plaintext in the repository.
  • A Compose snippet without the services: wrapper works too. In the reverse direction the parser also accepts a bare services map, as long as every service has image or build.

Combining with other JPKCom tools

  • Building or understanding a run command? The Docker cheat sheet explains the container lifecycle and the key docker flags — a good reference before you throw a command into the Composer.
  • Working with the generated YAML? The Docker Compose cheat sheet shows how to run the file with docker compose up, down, logs, and friends — and which fields (depends_on, build …) you can still add.
  • Moving to Podman? The Podman cheat sheet puts the podman commands the tool generates in podman mode into context.
  • Scheduling a container job? With the cron generator you build the matching crontab line, for example for a recurring docker run maintenance job.

More context: the overview for the big picture, the manual for every flag, and the examples for the step-by-step walkthroughs. You can try everything directly in the tool.