Computers & Electronics
114,816 views
25 min · 3 min read
7 steps
Advanced

How to install, configure, and use Docker Compose for multi‑container local development

Docker Compose lets you define and run multi-container applications locally using a single YAML file. This guide walks you through installing Compose, creating a simple docker-compose.yml, configuring services and volumes, and running a reproducible development stack. Follow each step and you should have a working local environment in about 10–20 minutes.

Verified by pleasexplain editors
  1. Step 1: Install Docker Engine

    Download and install Docker Desktop for macOS or Windows, or Docker Engine for Linux, following the official package for your OS. Verify the installation by running docker --version and docker run hello-world; both should complete in under a minute and confirm the daemon is working.

    [Illustration: Laptop showing terminal with 'docker --version' and 'hello-world' output.]

  2. Step 2: Install Docker Compose

    If your Docker distribution does not include Compose v2, install the standalone Compose binary matching your OS and place it in a directory on PATH. Confirm with docker compose version or docker-compose --version — you should see a semantic version like 2.x in the output within a few seconds.

    [Illustration: Terminal displaying 'docker compose version' output on a dark background.]

  3. Step 3: Create project directory

    Make a new directory for your app, for example mkdir myapp && cd myapp, and initialize any code (sample Node, Python, or static files). Keeping everything in one folder simplifies relative paths in docker-compose.yml and lets you rebuild containers quickly.

    [Illustration: File explorer or terminal showing a new folder named 'myapp' with a simple app file.]

  4. Step 4: Write docker-compose.yml

    Create docker-compose.yml with at least two services (web and db), specifying images, ports, volumes, and depends_on. Use concrete settings like ports: "8080:80", volumes: ./code:/app, and environment variables for DB credentials so the stack is reproducible and easy to share.

    [Illustration: Text editor open with a docker-compose.yml showing services web and db and port mappings.]

  5. Step 5: Configure persistent volumes

    Declare named volumes (e.g., db_data:) and bind mounts for code to preserve database state and enable live code editing. Using a named volume ensures data survives container recreation; bind mounts let you edit files locally and see changes within seconds in the container.

    [Illustration: Diagram showing host folder mapped to container /app and a named volume attached to /var/lib/postgresql/data.]

  6. Step 6: Bring the stack up

    Run docker compose up --build in your project root to build images and start containers; add -d to run in the background. Expect first build to take several minutes; subsequent starts are faster. Verify with docker compose ps and test the app at http://localhost:8080.

    [Illustration: Terminal running 'docker compose up --build' with logs streaming and a browser showing localhost:8080.]

  7. Step 7: Iterate and debug containers

    Use docker compose logs -f servicename to follow logs, docker compose exec servicename sh or bash to open a shell, and docker compose down to stop and remove containers. These commands let you inspect runtime state, run migrations, and quickly rebuild the environment when code or config changes.

    [Illustration: Terminal split view: one pane with 'docker compose logs -f' and another with an interactive shell inside a container.]


  • Pin image versions (for example node:18-alpine) to avoid unexpected changes when rebuilding.
  • Use .env file to store non-secret configuration like ports and usernames; reference them in docker-compose.yml with ${VAR}.
  • Use healthcheck entries to make depends_on more reliable; set interval: 10s, retries: 5 for service readiness.
  • Mount only necessary directories as bind mounts to keep container performance good; avoid mounting your entire home directory.
  • Run docker system prune --volumes monthly to reclaim disk space, but be cautious as it removes unused images and volumes.
  • Add a Makefile with shortcuts (make up, make down, make logs) to speed common workflows and reduce typing.

  • Never store production secrets in docker-compose.yml or .env; use a secrets manager or environment injection instead.
  • docker compose down --volumes will delete named volumes and irreversibly remove data; back up databases first if you need the data.
  • Be careful with published ports like 0.0.0.0:80:80 on shared networks; they expose services to other machines and can create security risks.
  • Avoid running containers as root unless required; use user directives in Dockerfile or compose to limit privilege escalation.

Was this guide helpful?