docker run to compose is the process of translating a docker run command and its flags into equivalent services, image, ports, volumes, environment, and command declarations in a docker-compose.yml file for declarative multi-container orchestration.
docker run --rm -it progrium/stress --cpu 2 --io 1 --vm 2 --vm-bytes 128M --timeout 10s
The equivalent docker-compose.yml for this command:
version: "3.6"
services:
stress:
image: progrium/stress
command: "--cpu 2 --io 1 --vm 2 --vm-bytes 128M --timeout 10s"
Key rule: --rm and -it are not expressed in Compose because the container lifecycle is managed by docker-compose up / down. Resource limits map to deploy.resources in swarm mode or cpus/mem_limit in version 3.x.
Conversion Mapping Reference
Each docker run flag maps to a YAML key under a service definition. The table below covers the most common mappings validated against Docker Compose v2 and Docker Engine 25.0.3.
| Action | docker run flag | docker-compose.yml key | Example value |
|---|---|---|---|
| Port mapping | -p 8080:80 |
ports |
"8080:80" |
| Volume mount | -v /host/path:/container/path |
volumes |
- /host/path:/container/path |
| Environment variable | -e VAR=value |
environment |
VAR: value or - VAR=value |
| Container name | --name mycontainer |
container_name |
container_name: mycontainer |
| Network | --network mynet |
networks |
networks: - mynet (define top-level networks:) |
| Command override | image cmd args |
command |
command: "--cpu 2" or command: ["--cpu","2"] |
| Entrypoint override | --entrypoint /bin/sh |
entrypoint |
entrypoint: ["/bin/sh","-c"] |
| Interactive / tty | -it |
stdin_open: true + tty: true |
stdin_open: truetty: true |
| Restart policy | --restart always |
restart |
restart: always |
| CPU / memory limits | --cpus 1.5 --memory 512m |
deploy.resources.limits (swarm) or cpus/mem_limit |
cpus: '1.5'mem_limit: 512m |
Advanced Implementation
Mapping Interactive and Detached Flags
The -it flag combines --interactive and --tty. In Compose:
services:
debug:
image: alpine
stdin_open: true
tty: true
command: ["sh"]
-d (detached) is the default when running docker-compose up -d; no explicit YAML key.
Multiple Containers and Dependencies
Convert multiple docker run calls into a single Compose file with depends_on:
docker run -d --name web -p 5000:5000 -v .:/code myapp
docker run -d --name redis redis:alpine
Becomes:
version: "3.6"
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
depends_on:
- redis
redis:
image: redis:alpine
Environment File Handling
Replace multiple -e flags with env_file:
environment:
- VAR1=value1
- VAR2=value2
# or
env_file: .env
Networks and Aliases
Define top-level networks for custom bridges:
networks:
frontend:
driver: bridge
services:
app:
networks:
frontend:
aliases:
- api
Error Resolution & Troubleshooting
| Error / Symptom | Root Cause | Remediation |
|---|---|---|
ERROR: Version in "./docker-compose.yml" is unsupported |
Using outdated format (e.g. v1) with Docker v25+ that only supports v2/v3. | Set version: "3.6" or omit version (defaults to 3.6 in newer Compose). |
service "stress" must specify one of "image" or "build" |
Missing image or build key. |
Add image: progrium/stress or a build: context. |
Attribute 'command' must be a string or list |
YAML interprets bare string as separate items if unquoted. | Use command: "--cpu 2" or command: ["--cpu","2"]. |
ports are not available: listen tcp4 0.0.0.0:80: bind: address already in use |
Host port occupied by another container or process. | Change host port mapping (e.g., "8080:80") or stop conflicting container. |
Cannot start service xxx: OCI runtime create failed |
Invalid command or entrypoint that container cannot execute. |
Verify binary exists inside image; test with docker run --entrypoint sh <image>. |
Production-Grade Implementation
Use Explicit Version Pinning
Specify version: "3.6" at the top for consistent behavior across Docker Engine versions. Omit version only when using Compose v2 exclusively.
Leverage .env Files for Secrets
Store sensitive data in a .env file referenced by env_file. Never embed secrets in the YAML:
# .env
DB_PASSWORD=s3cret
services:
db:
image: postgres:16
env_file: .env
Implement Healthchecks
Replace --health-cmd with native Compose healthcheck:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost"]
interval: 30s
timeout: 10s
retries: 3
Minimize Permissions via Read-Only Filesystems
Add read_only: true and mount /tmp as tmpfs:
services:
app:
image: myapp
read_only: true
tmpfs:
- /tmp
Automate Conversion with composerize
The open-source tool composerize (composerize.com) accepts a docker run string and outputs a starting docker-compose.yml. It is not perfect for complex commands but accelerates prototyping.
Version Control the Compose File
Keep docker-compose.yml in the same repository as the application code. Use environment-specific override files (docker-compose.override.yml) for local development and exclude them from production branches.
Frequently Asked Questions
What is the difference between docker run -v and docker compose volumes?
Answer: docker run -v imperatively binds a host path or named volume; docker compose volumes: declaratively defines bind mounts or named volumes. The long syntax in Compose gives explicit control over type, source, target, and read-only.
# docker run
docker run -v /host/path:/container/path:ro image
# docker-compose.yml
services:
app:
image: image
volumes:
- type: bind
source: /host/path
target: /container/path
read_only: true
When should I use the –build flag with docker compose up?
Answer: Use --build to force rebuild images from Dockerfiles before starting containers. Without it, Compose uses cached images. Combine with --force-recreate to ensure fresh containers.
docker compose up --build --force-recreate
How do I fix “Container name already in use” when switching to docker compose?
Answer: Remove the conflicting container with docker rm -f <container_name> or use docker compose up --force-recreate. Compose defaults to project_service_n naming.
docker rm -f mycontainer
docker compose up --force-recreate
Does docker compose work on Apple Silicon (M1/M2)?
Answer: Yes, recent Docker Desktop includes native ARM binaries. Verify with docker compose version. For x86 images, use --platform linux/amd64 or enable emulation.
docker compose version
docker compose run --platform linux/amd64 service
What is the fastest way to convert a docker run command to docker-compose.yml?
Answer: Use composerize (composerize.com) or manually map flags to YAML using the table above. For complex commands, manual verification is recommended.
# Example via composerize (not a CLI tool, web service)
# Paste command at composerize.com

Command Line Expert & Software Engineer
Welcome! I’m Thomas Heinrich, a software engineer and system administrator with a deep passion for the Command Line Interface (CLI). With years of experience navigating the terminal, building backend architectures, and automating server deployments, I created this space to share practical, real-world terminal knowledge.
Whether you are a beginner taking your first steps in a Linux environment or a seasoned DevOps engineer looking to optimize your deployment scripts, you will find actionable solutions here. My goal is to help you ditch the mouse, speed up your workflow, and harness the full power of the command line.