Skip to content

Instantly share code, notes, and snippets.

@The-Running-Dev
Last active April 16, 2026 18:48
Show Gist options
  • Select an option

  • Save The-Running-Dev/1b26d166cc1a68ac3eca3da4f0681981 to your computer and use it in GitHub Desktop.

Select an option

Save The-Running-Dev/1b26d166cc1a68ac3eca3da4f0681981 to your computer and use it in GitHub Desktop.

Docker Run vs. Docker Compose

At some point, every beginner runs into this question:

Should I use docker run, or should I use Docker Compose?

The practical answer is simple:

  • Use docker run when you want to start one container quickly
  • Use Docker Compose when you want to define and manage one or more containers as a reusable setup

You can think of it like this:

  • docker run = one command, typed by hand
  • docker compose = a saved recipe in a docker-compose.yml file

When to use each one

Use case Better choice
Quick test docker run
Learning basic flags docker run
Reusable setup Docker Compose
Multi-container app Docker Compose
Team sharing Docker Compose
Easier updates Docker Compose

Visual difference

flowchart LR
    A[docker run] --> B[One command typed manually]
    B --> C[One container starts]

    D[docker compose] --> E[YAML file defines services]
    E --> F[One command starts full stack]
Loading

Install Docker Compose

If you installed Docker Desktop, Compose is already included as docker compose.

If you want to install it explicitly:

winget install -e --id Docker.DockerCompose

Verify:

docker compose version

Simple example with docker run

docker run -d `
  --name my-nginx `
  -p 8080:80 `
  --restart unless-stopped `
  nginx

Parameters explained

  • -d → run in background
  • --name → container name
  • -p → port mapping (host:container)
  • --restart → restart policy
  • nginx → image

Open: http://localhost:8080


Same setup with Docker Compose

services:
  nginx:
    image: nginx
    container_name: my-nginx
    ports:
      - "8080:80"
    restart: unless-stopped

Run:

docker compose up -d

Why Compose is better here

  • No need to remember long commands
  • Easy to edit and reuse
  • Shareable config
  • Cleaner structure

Advanced example — Portainer (docker run)

docker volume create portainer_data

docker run -d `
  --name portainer `
  -p 9000:9000 `
  --restart always `
  -v /var/run/docker.sock:/var/run/docker.sock `
  -v portainer_data:/data `
  portainer/portainer-ce

Parameters explained

  • docker volume create → persistent storage
  • -v host:container → mount volume
  • /var/run/docker.sock → allows Portainer to control Docker
  • portainer_data:/data → saves app data
  • --restart always → auto restart

Same Portainer setup with Docker Compose

services:
  portainer:
    image: portainer/portainer-ce
    container_name: portainer
    ports:
      - "9000:9000"
    restart: always
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer_data:/data

volumes:
  portainer_data:

Run:

docker compose up -d

docker compose commands

Start

docker compose up

Start (background)

docker compose up -d

Stop & remove

docker compose down

Remove including volumes

docker compose down -v

Restart

docker compose restart

Stop only

docker compose stop

Start stopped services

docker compose start

Status

docker compose ps

Logs

docker compose logs

Follow logs

docker compose logs -f

Pull updates

docker compose pull

Rebuild

docker compose up --build

Force recreate

docker compose up -d --force-recreate

Remove orphan containers

docker compose up -d --remove-orphans

Restart policies

In docker run:

--restart always

In Compose:

restart: always

Types

  • no
  • always
  • unless-stopped
  • on-failure

Final takeaway

  • Use docker run for quick tests
  • Use Docker Compose for anything you want to keep

That’s the real difference.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment