← 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. If you run into permission denied errors when binding host directories with -v, the Docker Volume Permissions Helper resolves container UID/GID mapping issues instantly. While docker run works well for isolated tasks, 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

When deciding between command-line execution and declarative YAML, comparing their operational characteristics explains why workflows naturally transition to Compose as projects scale:

Feature / Scenario docker run Docker Compose
Configuration Storage Shell history or bash scripts Declarative YAML file (docker-compose.yml)
Multi-Container Apps Complex manual networking & linking Native orchestration with automatic networking
Version Control & CI/CD Difficult to version-control & share across teams Checked into Git for reproducible environments
Startup & Teardown Multiple manual commands needed per container Single command (docker compose up / down)
Best For Quick tests, isolated scripts, single tasks Local dev stacks, team collaboration, staging/prod
  • 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.

Troubleshooting Common Conversion & Deployment Issues

Whether transitioning from standalone commands to declarative YAML or debugging multi-container stacks, developers frequently encounter configuration and permission obstacles. Here are practical troubleshooting workflows for the most common deployment issues:

  • Volume Permission Denied (EACCES / 13: Permission denied): When mounting host directories into containers (such as PostgreSQL data directories or Node.js workspaces), file ownership mismatches between host users and container UIDs often prevent write access. To diagnose and fix UID/GID mapping errors without guessing Linux chmod/chown flags, use our Docker Volume Permissions Helper to generate the exact volume permission fixes and user directives for your environment.
  • YAML Schema & Indentation Errors: Because YAML is strictly whitespace-sensitive, a single misplaced space or unquoted character sequence (such as time strings or passwords with colons and hashes) can cause Compose to fail silently or throw parsing errors. Run your configuration through the Docker Compose Validator to verify schema compliance, detect duplicate port mappings, and catch syntax bugs directly in your browser.
  • Port Allocation Conflicts (bind: address already in use): If docker compose up fails because port 80 or 5432 is already occupied on your host machine, inspect running containers with docker ps or update your Compose file to map to a free host port (e.g., changing "5432:5432" to "5433:5432").
  • Complex Command Translation Errors: Migrating lengthy bash scripts containing numerous docker run flags (such as custom networks, memory limits, and restart policies) by hand is tedious and error-prone. Use the Docker Run to Compose Converter to automatically generate clean, valid YAML structures in seconds.

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.