← Back to Blog DevOps

Docker Run vs Docker Compose: When to Use Each

docker run launches a single container from the command line. Docker Compose defines multi-container applications in a YAML file, making complex deployments reproducible and version-controlled. If you have a working docker run command and need to convert it to a docker-compose.yml, the Docker Run to Compose Converter handles the translation locally in your browser — your server configurations and internal image names stay private.

Docker Run: What It Does

The docker run command creates and starts a container from an image in a single step. It's the most direct way to launch a container:

docker run -d \
  --name postgres-dev \
  -p 5432:5432 \
  -v pgdata:/var/lib/postgresql/data \
  -e POSTGRES_USER=admin \
  -e POSTGRES_PASSWORD=secret123 \
  -e POSTGRES_DB=myapp \
  --restart unless-stopped \
  postgres:16-alpine

This single command configures detached mode (-d), port mapping (-p), persistent storage (-v), environment variables (-e), a restart policy, and the image version. It works well for isolated tasks, but the configuration exists only in your shell history.

Docker Compose: What It Does

Docker Compose takes the same configuration and defines it declaratively in a docker-compose.yml file:

services:
  postgres:
    image: postgres:16-alpine
    container_name: postgres-dev
    ports:
      - "5432:5432"
    volumes:
      - pgdata:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: admin
      POSTGRES_PASSWORD: secret123
      POSTGRES_DB: myapp
    restart: unless-stopped

volumes:
  pgdata:

The configuration is now version-controlled, shareable, and reproducible. Run docker compose up -d and the entire stack comes up. Run docker compose down and it tears down cleanly. Add more services (Redis, your API, Nginx) by adding more entries under services:.

Docker Run vs Compose: Side-by-Side

  • Single container, quick test: Use docker run. It's faster for one-off tasks where you don't need to save the configuration.
  • Multi-container application: Use Compose. Defining services, networks, and volumes in one file is dramatically simpler than chaining multiple docker run commands.
  • Team collaboration: Use Compose. The YAML file lives in your repo, making it easy for every developer to spin up the same environment.
  • Production deployment: Use Compose (or a Compose-derived format like Docker Stack). Infrastructure-as-code is essential for reliable deployments.
  • CI/CD pipelines: Use Compose. A single docker compose up in your CI script sets up the entire test environment.

Converting Docker Run Commands to Compose

Every docker run flag has a corresponding Compose YAML key:

  • -p 8080:80ports: ["8080:80"]
  • -v data:/app/datavolumes: ["data:/app/data"]
  • -e KEY=valueenvironment: KEY: value
  • --name myservicecontainer_name: myservice
  • --network mynetnetworks: [mynet]
  • --restart alwaysrestart: always
  • -d → implied (Compose runs detached by default with -d)

For complex commands with many flags, manual conversion is tedious and error-prone. The Docker Run to Compose Converter parses your command, maps every flag to the correct YAML structure, and outputs a valid docker-compose.yml — all processed in your browser.

Managing Environment Variables

Hardcoding secrets in your docker-compose.yml is a security risk if the file is committed to version control. Instead, use the env_file directive:

services:
  api:
    image: myapp:latest
    env_file:
      - .env
    ports:
      - "3000:3000"

This loads variables from a .env file that you add to .gitignore. If your .env file has gotten messy with duplicate keys, trailing whitespace, or inconsistent formatting, the Env File Formatter cleans it up locally in your browser.

Validating Your docker-compose.yml

YAML is whitespace-sensitive, and a single indentation error can cause Compose to fail silently or misconfigure your services. Common issues include:

  • Mixed tabs and spaces (YAML requires spaces only)
  • Incorrect indentation under nested keys
  • Unquoted strings containing special characters (:, #, )
  • Missing top-level services: key

Before deploying, validate your YAML structure with the YAML Validator to catch syntax errors, or use our dedicated Docker Compose Validator to test full schema compliance, duplicate ports, and configuration bugs entirely in your browser.

Frequently Asked Questions

Can I convert any docker run command to docker-compose.yml?
Most docker run flags have direct docker-compose.yml equivalents: -p maps to ports, -v maps to volumes, -e maps to environment, --name maps to the service name, and --network maps to networks. Complex flags like --cap-add or --device may require additional configuration.
When should I use Docker Run instead of Compose?
Use docker run for quick, one-off tasks: testing an image, running a database for local development, or executing a utility container. Use Compose when you have multiple services, need reproducible environments, or want to version-control your container configuration.
Does Docker Compose work with Docker Swarm?
Docker Compose files can be used with Docker Swarm via docker stack deploy. However, some Compose features (like build) are not supported in Swarm mode. The deploy key in Compose files is specifically designed for Swarm and Kubernetes orchestration.
How do I pass environment variables in Docker Compose?
You can define environment variables inline using the environment key, reference an external file with env_file: .env, or use variable substitution with ${VARIABLE_NAME} syntax in the Compose file. The env_file approach keeps secrets out of version control.
Is docker-compose deprecated in favor of docker compose?
The standalone docker-compose binary (Python-based, V1) was deprecated in July 2023. Docker Compose V2 is built into the Docker CLI as docker compose (without the hyphen). The Compose file format itself is not deprecated — only the standalone binary.