Skip to main content
DevOps Insightsguides & answers

Interactive tool

From docker run to compose.yaml

A long docker run command is hard to review and easy to mistype. This turns it into a Compose service, keeps the quoting Compose needs, and lists every flag it could not convert instead of silently dropping it.

Runs in your browser · nothing is sent anywhere

compose.yaml

services:
  web:
    image: "nginx:1.27"
    container_name: "web"
    ports:
      - "8080:80"
    environment:
      - "TZ=UTC"
    volumes:
      - "web-data:/usr/share/nginx/html"
    restart: "unless-stopped"
volumes:
  "web-data": {}

The link holds the docker run command above. Remove passwords and tokens before you send it.

What changed on the way

  • -d has no Compose attribute: run docker compose up -d instead.
  • Named volumes are declared at the top level: web-data.

What Compose adds to docker run

docker run starts one container with all of its settings typed on the command line. Compose writes the same settings into a file, compose.yaml, so they can be reviewed, kept with the code and started again with one command, docker compose up.

This reads the command the way a shell would and writes the matching Compose service. Anything it has no safe translation for is listed, not dropped.

Using it

Paste the whole command, line continuations included. Read the not converted list first: those settings are missing from the file until you add them. Save the result as compose.yaml, then run docker compose config, which validates it and shows it the way Compose will read it, before docker compose up -d.

What this checks

  • Converts the docker run flags it knows into Compose service attributes, each checked against the Compose file reference, and quotes values the way Compose needs.
  • Declares named volumes, and a user-defined network as external, at the top level.

What it cannot know

  • Convert --mount, --ulimit, --gpus, health checks and other flags it lists as not converted.
  • Know whether your volumes and networks exist, or what an -e VAR with no value will be where Compose runs.
  • Run Docker. The file is only as right as the command you pasted.

Check it for real

docker compose config

Parses the file, substitutes variables and prints the result in canonical form, so it fails on anything Compose would reject before you start a container. Docker — docker compose config

What behaves differently once it is in Compose

Networking. Containers started with plain docker run on the default bridge network can reach each other only by IP address. Compose creates a network for the project, named after its directory, and every service can reach the others by service name. A second container you used to start separately belongs in the same file as another service.

Dollar signs. Compose substitutes $VAR in values from your environment or a .env file, much as the shell did before docker run saw them. A $ that the shell kept literal, inside single quotes, has to be written $$ in the file, and the converter does that for you.

Names and paths. container_name fixes the container's name, which means the service cannot be scaled to more than one container. Relative paths in volumes are resolved from the directory holding the compose file, not from where you run the command.

Questions people ask about this

How do I convert a docker run command to docker compose?

Each docker run flag has a Compose attribute: -p becomes ports, -e becomes environment, -v becomes volumes, --restart becomes restart, and so on. The image becomes image, and anything after it becomes command. Paste the command above to get the file, then check it with docker compose config.

Why are the ports and restart: "no" in quotes?

The Compose file reference says ports should always be written as quoted strings. For restart, an unquoted no is read as the boolean false by YAML 1.1 parsers, and Compose expects the text “no”. Quoting every value, as the converter does, avoids both problems.

Why did a $ in my command become $$?

Compose replaces $VAR in values with variables from your environment or a .env file. A dollar sign that was meant literally, inside single quotes on the command line, has to be written $$ in the file, or Compose would try to substitute it. Shell variables such as $HOME are left as they are, because Compose fills them in as the shell did.

Did this get you to an answer?

No text box on purpose — please do not paste production logs anywhere

Something wrong or out of date? Report it