---
title: "Docker Compose"
lang: "en"
author: "Mohammad Abu Mattar"
canonical: https://mkabumattar.com/docker-compose
---

0

[Home](/)›[Cheatsheets](/cheatsheets)

Cheatsheets

# Docker Compose

Docker Compose reference guide covering services, volumes, networks, ports, environment variables, commands, configurations, and container orchestration best practices.

9 Categories26 Sections61 ExamplesPublished: 28 Feb 2026

[Markdown for AI(opens in a new tab)](/docker-compose/index.md "Open the plain-Markdown version of this page, for pasting into an AI tool")

Series

[Containers & Kubernetes](/series/containers--kubernetes)4/7

[PreviousKubernetes](/cheatsheets/kubernetes)[NextDockerfile](/cheatsheets/dockerfile)

All posts in this series (7)

Cheatsheets7

1.  [Docker](/cheatsheets/docker)
2.  [Helm](/cheatsheets/helm)
3.  [Kubernetes](/cheatsheets/kubernetes)
4.  [Docker ComposeYou are here](/cheatsheets/docker-compose)
5.  [Dockerfile](/cheatsheets/dockerfile)
6.  [Docker Swarm](/cheatsheets/docker-swarm)
7.  [kubectl](/cheatsheets/kubectl)

Docker Compose is a tool for defining and running multi-container Docker applications. It uses a YAML file to configure application services, networks, and volumes. This cheatsheet provides a quick reference for common Docker Compose commands, configuration options, best practices, and troubleshooting tips.

[Getting Started](#category-getting-started)

-   [Installation & Setup](#section-install-docker-compose)
-   [Project Structure & Configuration](#section-basic-setup)
-   [Version & Compatibility](#section-version-compatibility)

[Basic Services](#category-basic-services)

-   [Service Definition & Images](#section-service-definition)
-   [Resource Constraints](#section-service-constraints)
-   [Restart Policies](#section-service-restart)

[Ports & Networking](#category-ports-networking)

-   [Port Mapping & Exposure](#section-port-mapping)
-   [Network Configuration](#section-network-configuration)
-   [DNS & Service Discovery](#section-dns-resolution)

[Volumes & Storage](#category-volumes-storage)

-   [Volume Types & Mounting](#section-volume-types)
-   [Volume Management & Cleanup](#section-volume-management)

[Environment & Configuration](#category-environment-config)

-   [Environment Variables](#section-environment-variables)
-   [Configuration Files & Secrets](#section-configuration-files)

[Build Configuration](#category-build-config)

-   [Build from Dockerfile](#section-build-from-dockerfile)
-   [Build Arguments and Cache](#section-build-arguments)

[Advanced Features](#category-advanced-features)

-   [Health Checks & Monitoring](#section-healthchecks)
-   [Service Dependencies](#section-depends-on)
-   [Labels & Metadata](#section-labels-metadata)
-   [Override Entrypoint & Command](#section-override-entrypoint)

[Docker Compose Commands](#category-docker-compose-commands)

-   [Lifecycle Management (up/down/stop)](#section-lifecycle-commands)
-   [Execution & Interaction (exec/run/logs)](#section-execution-commands)
-   [Status & Information (ps/config/port)](#section-status-commands)
-   [Build & Push Commands](#section-build-commands)

[Network & Security](#category-network-security)

-   [Network Modes & Links](#section-network-modes)
-   [User Permissions & Security](#section-user-permissions)
-   [External Networks & Scaling](#section-external-networks)

No commands found

Try adjusting your search term

## Getting Started

### Installation & Setup

Install Docker Compose and verify installation on your system

#### Accessibility

Beginner

#### Keywords

installationsetupbinarypackage manager

#### Install Docker Compose on Linux

Downloads the Docker Compose binary for your system architecture and sets executable permissions

Code

Terminal window

```
curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-composechmod +x /usr/local/bin/docker-composedocker-compose --version
```

Execution

Terminal window

```
Docker Compose version v2.25.0
```

-   Requires curl to be installed
-   Verify checksum for security
-   Use docker compose instead of docker-compose in v2

#### Verify Docker Compose Installation

Check Docker Compose version and review available commands

Code

Terminal window

```
docker compose versiondocker compose --help
```

Execution

Terminal window

```
Docker Compose version v2.25.0, build somethingUsage: docker compose [OPTIONS] COMMAND
Options:  --version  Show the version and exit  -f, --file FILE  Specify path to compose file  -p, --project-name STRING  Set project name
```

-   Docker Compose v2 onwards uses 'docker compose' command
-   Legacy 'docker-compose' is deprecated

### Project Structure & Configuration

Set up a Docker Compose project with proper directory structure

#### Accessibility

Beginner

#### Keywords

project structurecompose.ymlconfigurationinitialization

#### Create Docker Compose Project Directory

Create a basic project structure for Docker Compose with necessary directories

Code

Terminal window

```
mkdir my-appcd my-apptouch compose.ymlmkdir -p app/srcmkdir -p data
```

Execution

Terminal window

```
$ tree my-app/my-app/├── compose.yml├── app│   └── src└── data
```

-   Keep compose.yml at project root
-   Use consistent directory naming

#### Initialize with Example Compose File

Create minimal valid compose.yml and validate with config command

Code

```
1version: '3.9'2services:3  app:4    image: nginx:latest5    ports:6      - "80:80"
```

Execution

Terminal window

```
$ docker compose configname: my-appservices:  app:    image: 'nginx:latest'    ports:      - mode: ingress        target: 80        published: "80"        protocol: tcpversion: '3.9'
```

-   Version '3.9' is latest v3 stable
-   Always validate configuration

### Version & Compatibility

Docker Compose versions and their compatibility requirements

#### Accessibility

Beginner

#### Keywords

versioncompatibilityfeaturesapi version

#### Check Docker Compose and Docker Version

Verify both Docker Engine and Docker Compose versions are installed

Code

Terminal window

```
docker --versiondocker compose versiondocker compose version --format json
```

Execution

Terminal window

```
Docker version 25.0.0, build abcdef12Docker Compose version v2.25.0, build build123{"Version":"v2.25.0","ApiVersion":"1.46","Experimental":false}
```

-   Docker Engine 20.10+ required for Compose v2
-   Use JSON format for parsing in scripts

#### Version-Specific Features in Compose File

Use version 3.9+ features like healthcheck for container monitoring

Code

```
1version: '3.9'2services:3  web:4    image: nginx:latest5    healthcheck:6      test: ["CMD", "curl", "-f", "http://localhost"]7      interval: 30s8      timeout: 10s
```

Execution

Terminal window

```
$ docker compose up -d[+] Running 1/1 ✔ Container my-app-web-1  Started
```

-   Version 3.8+ supports properties
-   Version 3.9 is feature-complete for most use cases

## Basic Services

### Service Definition & Images

Define services using images and configure basic service properties

#### Accessibility

Beginner

#### Keywords

serviceimagecontainerdefinition

#### Define Single Service with Image

Define a service using pre-built image with container naming and restart policy

Code

```
1version: '3.9'2services:3  web:4    image: nginx:1.245    container_name: my-nginx6    restart: always
```

Execution

Terminal window

```
$ docker compose up -d[+] Running 1/1 ✔ Container my-nginx  Created
```

-   Image format: name:tag or name:digest
-   container\_name overrides auto-generated name

#### Multiple Services from Different Images

Define multiple interdependent services each using different official images

Code

```
1version: '3.9'2services:3  web:4    image: nginx:latest5    container_name: web-server6  db:7    image: postgres:158    container_name: database9  cache:10    image: redis:7-alpine11    container_name: redis-cache
```

Execution

Terminal window

```
$ docker compose up -d[+] Running 3/3 ✔ Container web-server     Created ✔ Container database       Created ✔ Container redis-cache   Created
```

-   Services communicate via service name automatically
-   Alpine variants use less disk space

#### Service with Image Pull Configuration

Pull image from private registry and always fetch latest version

Code

```
1version: '3.9'2services:3  app:4    image: myregistry.azurecr.io/myapp:v1.05    pull_policy: always6    container_name: app-container
```

Execution

Terminal window

```
$ docker compose up[+] Pulling 1/1 ✔ myregistry.azurecr.io/myapp:v1.0 Pulled[+] Running 1/1 ✔ Container app-container  Created
```

-   pull\_policy can be always, never, or missing
-   Missing policy (default) only pulls if image not local

### Resource Constraints

Limit CPU and memory usage for services

#### Accessibility

Intermediate

#### Keywords

resource limitsmemorycpuconstraints

#### Set Memory and CPU Limits

Set hard limits and soft reservations for container resources

Code

```
1version: '3.9'2services:3  app:4    image: node:185    deploy:6      resources:7        limits:8          cpus: '0.5'9          memory: 512M10        reservations:11          cpus: '0.25'12          memory: 256M
```

Execution

Terminal window

```
$ docker compose up -d$ docker statsCONTAINER ID   NAME     CPU %    MEM USAGE / LIMITabc123def456   app-1    0.5%    128M / 512M
```

-   Limits prevent container from using more than specified
-   Reservations guarantee minimum resources
-   Format: 0.5 = 50% of one CPU

#### Cascading Resource Configuration

Apply different resource constraints to different services

Code

```
1version: '3.9'2services:3  database:4    image: mysql:85    deploy:6      resources:7        limits:8          cpus: '1.0'9          memory: 1G10  cache:11    image: redis:712    deploy:13      resources:14        limits:15          cpus: '0.5'16          memory: 256M
```

Execution

Terminal window

```
$ docker compose statsNAME       CPU %   MEM USAGE / LIMITdatabase   0.8%    512M / 1Gcache      0.2%    45M / 256M
```

-   Match resources to service requirements
-   Monitor actual usage to adjust limits

### Restart Policies

Configure how containers restart on failure

#### Accessibility

Beginner

#### Keywords

restart policyfailurerecoveryalways

#### Configure Restart Policy

Set restart policies to keep containers running or retry on failure

Code

```
1version: '3.9'2services:3  web:4    image: nginx:latest5    restart: always6  app:7    image: node:188    restart: on-failure9    deploy:10      restart_policy:11        condition: on-failure12        max_attempts: 313        delay: 5s
```

Execution

Terminal window

```
$ docker compose up -d[+] Running 2/2 ✔ Container web-1  Started ✔ Container app-1  Started
```

-   always: always restart unless explicitly stopped
-   on-failure: restart only if exit code is non-zero
-   max\_attempts: limit retry count

#### Restart Policy with Exponential Backoff

Retry with limited attempts and timeout window using deploy configuration

Code

```
1version: '3.9'2services:3  api:4    image: myapp:latest5    deploy:6      restart_policy:7        condition: on-failure8        max_attempts: 59        delay: 1s10        window: 120s
```

Execution

Terminal window

```
$ docker compose logs apiapi-1 | Starting service...api-1 | Service started
```

-   window: only count failures within this timeframe
-   Prevents infinite restart loops

## Ports & Networking

### Port Mapping & Exposure

Map container ports to host ports and expose services

#### Accessibility

Beginner

#### Keywords

port mappingexposureportexpose

#### Basic Port Mapping

Map host port 8080 to container port 80, and 8443 to 443

Code

```
1version: '3.9'2services:3  web:4    image: nginx:latest5    ports:6      - "8080:80"7      - "8443:443"
```

Execution

Terminal window

```
$ docker compose up -d$ curl http://localhost:8080<!DOCTYPE html><html><head><title>Welcome to nginx!</title></head>
```

-   Format: host:container
-   Can specify IP: 127.0.0.1:8080:80

#### Multiple Services with Port Mapping

Expose multiple services on different ports

Code

```
1version: '3.9'2services:3  web:4    image: nginx:latest5    ports:6      - "80:80"7  api:8    image: node:189    ports:10      - "3000:3000"11  db:12    image: postgres:1513    ports:14      - "5432:5432"
```

Execution

Terminal window

```
$ docker compose psNAME      IMAGE          PORTSweb-1     nginx:latest   0.0.0.0:80->80/tcpapi-1     node:18        0.0.0.0:3000->3000/tcpdb-1      postgres:15    0.0.0.0:5432->5432/tcp
```

-   Each service can have multiple port mappings
-   Default protocol is tcp, can specify udp

#### Port Mapping with Protocol Specification

Specify protocol (tcp/udp) and use verbose port syntax

Code

```
1version: '3.9'2services:3  dns:4    image: coredns:latest5    ports:6      - "53:53/udp"7      - "53:53/tcp"8  web:9    image: nginx:latest10    ports:11      - target: 8012        published: 808013        protocol: tcp
```

Execution

Terminal window

```
$ docker compose psNAME    IMAGE               PORTSdns-1   coredns:latest      0.0.0.0:53->53/tcp, 0.0.0.0:53->53/udpweb-1   nginx:latest        0.0.0.0:8080->80/tcp
```

-   Default protocol is tcp
-   Verbose syntax allows more control

### Network Configuration

Configure custom networks and manage service connectivity

#### Accessibility

Intermediate

#### Keywords

networkscustom networkbridgeconnectivity

#### Define Custom Networks

Define custom networks and assign services to them for isolation

Code

```
1version: '3.9'2services:3  web:4    image: nginx:latest5    networks:6      - frontend7  api:8    image: node:189    networks:10      - frontend11      - backend12  db:13    image: postgres:1514    networks:15      - backend16networks:17  frontend:18    driver: bridge19  backend:20    driver: bridge
```

Execution

Terminal window

```
$ docker compose up -d[+] Creating network my-app_frontend[+] Creating network my-app_backend$ docker network lsNETWORK ID    NAME               DRIVERabc123        my-app_frontend    bridgedef456        my-app_backend     bridge
```

-   Services on same network can communicate via service name
-   Services on different networks require linking

#### External Network Integration

Connect services to external networks created outside Compose

Code

```
1version: '3.9'2services:3  app:4    image: node:185    networks:6      - shared-network7networks:8  shared-network:9    external: true10    name: production-network
```

Execution

Terminal window

```
$ docker compose up -d[+] Running 1/1 ✔ Container app-1  Started$ docker network inspect production-network[  {    "Name": "production-network",    "Containers": {      "abc123...": {        "Name": "app-1"      }    }  }]
```

-   External networks must exist before docker compose up
-   Useful for multi-compose-file deployments

### DNS & Service Discovery

Configure DNS and internal service discovery

#### Accessibility

Intermediate

#### Keywords

dnsservice discoveryhostnameresolution

#### Service DNS Resolution

Services can discover each other using service name or hostname

Code

```
1version: '3.9'2services:3  web:4    image: nginx:latest5    hostname: webserver6  api:7    image: node:188    hostname: apiserver
```

Execution

Terminal window

```
$ docker compose exec api curl http://webserver<!DOCTYPE html><html><head><title>Welcome to nginx!</title></head>
```

-   Default: service name is used for DNS
-   Hostname overrides service name if specified

#### Custom DNS Servers

Override default DNS servers and search domains

Code

```
1version: '3.9'2services:3  app:4    image: node:185    dns:6      - 8.8.8.87      - 8.8.4.48    dns_search:9      - example.com10      - internal.local
```

Execution

Terminal window

```
$ docker compose exec app cat /etc/resolv.confnameserver 8.8.8.8nameserver 8.8.4.4search example.com internal.local
```

-   Useful for internal DNS or custom resolvers
-   Multiple servers provide redundancy

## Volumes & Storage

### Volume Types & Mounting

Work with named volumes, anonymous volumes, and bind mounts

#### Accessibility

Intermediate

#### Keywords

volumesnamed volumebind mountstorage

#### Named Volumes for Data Persistence

Create named volumes for persistent data that survives container removal

Code

```
1version: '3.9'2services:3  db:4    image: postgres:155    volumes:6      - db_data:/var/lib/postgresql/data7  cache:8    image: redis:79    volumes:10      - cache_data:/data11volumes:12  db_data:13  cache_data:
```

Execution

Terminal window

```
$ docker compose up -d$ docker volume lsDRIVER    VOLUME NAMElocal     my-app_db_datalocal     my-app_cache_data
```

-   Named volumes are managed by Docker
-   Data persists when containers are removed
-   Can be used across containers

#### Bind Mounts for Development

Mount local directories into container for live development

Code

```
1version: '3.9'2services:3  app:4    image: node:185    working_dir: /app6    volumes:7      - ./src:/app/src8      - ./package.json:/app/package.json9      - ./package-lock.json:/app/package-lock.json10    ports:11      - "3000:3000"
```

Execution

Terminal window

```
$ docker compose up -d$ ls /appsrc  package.json  package-lock.json
```

-   Changes on host immediately visible in container
-   Suited to development workflows
-   Use relative paths for portability

#### Anonymous Volumes and Read-Only Volumes

Use anonymous volumes, read-only mounts, and shared writable volumes

Code

```
1version: '3.9'2services:3  app:4    image: node:185    volumes:6      - /tmp7      - ./config.json:/app/config.json:ro8      - shared_data:/shared:rw9volumes:10  shared_data:
```

-   Anonymous volumes are cleaned on down
-   ro = read-only, rw = read-write
-   :ro prevents accidental modifications

#### Volume Mount Options

Use long-form volume syntax for granular control

Code

```
1version: '3.9'2services:3  db:4    image: postgres:155    volumes:6      - type: volume7        source: db_data8        target: /var/lib/postgresql/data9        volume:10          nocopy: true11      - type: bind12        source: ./init-scripts13        target: /docker-entrypoint-initdb.d14        read_only: true15volumes:16  db_data:
```

Execution

Terminal window

```
$ docker compose up -d$ docker compose exec db ls /var/lib/postgresql/database global pg_hba.conf
```

-   nocopy: don't copy volume content from existing data
-   read\_only: mount as read-only
-   More explicit than shorthand

### Volume Management & Cleanup

Manage and maintain Docker Compose volumes

#### Accessibility

Intermediate

#### Keywords

volume managementcleanuppruneremoval

#### List and Inspect Volumes

List volumes created by Compose and inspect their properties

Code

Terminal window

```
docker compose volume lsdocker volume inspect my-app_db_datadocker volume inspect my-app_db_data --format='{{json .Mountpoint}}'
```

Execution

Terminal window

```
DRIVER    VOLUME NAMElocal     my-app_db_data
[  {    "Name": "my-app_db_data",    "Driver": "local",    "Mountpoint": "/var/lib/docker/volumes/my-app_db_data/_data"  }]
```

-   Volumes persist after docker compose down
-   Mountpoint shows where data is stored

#### Clean Up Volumes

Remove volumes when stopping containers or clean unused volumes

Code

Terminal window

```
docker compose down -vdocker volume rm my-app_db_datadocker volume prune -f
```

Execution

Terminal window

```
Removing stopped containers...Removing named volumes...Deleted Volumes:my-app_db_data
Deleted Volumes:my-app_cache_data
```

-   down -v removes named volumes declared in compose file
-   prune removes all unused volumes
-   Use force flag to skip confirmation

## Environment & Configuration

### Environment Variables

Set and manage environment variables for services

#### Accessibility

Beginner

#### Keywords

environment variablesenv varsconfigurationsettings

#### Environment Variables in Compose File

Define environment variables directly in compose.yml

Code

```
1version: '3.9'2services:3  app:4    image: node:185    environment:6      NODE_ENV: production7      LOG_LEVEL: debug8      DATABASE_URL: postgres://user:pass@db:5432/mydb9      API_PORT: 3000
```

Execution

Terminal window

```
$ docker compose exec app envNODE_ENV=productionLOG_LEVEL=debugDATABASE_URL=postgres://user:pass@db:5432/mydbAPI_PORT=3000
```

-   Variables are set when container starts
-   Application code reads these variables

#### Environment Files (.env)

Load environment variables from .env files and reference them in compose

Code

```
1version: '3.9'2services:3  db:4    image: postgres:155    env_file:6      - .env.database7      - .env.common8  app:9    image: node:1810    env_file: .env11    environment:12      NODE_ENV: ${NODE_ENV}
```

Execution

Terminal window

```
$ cat .envNODE_ENV=productionAPI_KEY=sk-12345$ docker compose up -d$ docker compose exec app echo $NODE_ENVproduction
```

-   Files are loaded in order, later overrides earlier
-   Use ${VAR} syntax to reference variables
-   .env in current directory loaded automatically

#### Variable Substitution and Defaults

Substitute variables with defaults using ${VAR:-default} syntax

Code

```
1version: '3.9'2services:3  web:4    image: nginx:${NGINX_VERSION:-latest}5    ports:6      - "${HOST_PORT:-80}:80"7  api:8    image: node:189    environment:10      DATABASE_HOST: ${POSTGRES_HOST}11      DATABASE_PORT: ${POSTGRES_PORT:-5432}12      SECRET_KEY: ${SECRET_KEY}
```

Execution

Terminal window

```
$ NGINX_VERSION=1.24 docker compose up$ docker compose config --resolve-image-digestsversion: '3.9'services:  web:    image: 'nginx:1.24'    ports:      - mode: ingress        target: 80        published: "80"
```

-   :- provides default if variable not set
-   Define in .env or export before docker compose
-   Use in any field

#### Per-Service Environment Variables

Set different environment variables for each service with .env files

Code

```
1version: '3.9'2services:3  app:4    image: node:185    env_file: .env.app6    environment:7      NODE_ENV: ${NODE_ENV:-development}8  db:9    image: postgres:1510    env_file: .env.database11    environment:12      POSTGRES_DB: ${DB_NAME:-mydb}13      POSTGRES_USER: ${DB_USER}14      POSTGRES_PASSWORD: ${DB_PASSWORD}
```

Execution

Terminal window

```
$ docker compose exec db psql -U ${DB_USER} -d ${DB_NAME}psql (15.1)Type "help" for help.
```

-   Each service can have its own .env file
-   Can mix env\_file and environment directives

### Configuration Files & Secrets

Manage configuration files and sensitive data

#### Accessibility

Intermediate

#### Keywords

configurationsecretsfilessensitive data

#### Mount Configuration Files as Volumes

Mount configuration files into containers as read-only volumes

Code

```
1version: '3.9'2services:3  nginx:4    image: nginx:latest5    volumes:6      - ./nginx.conf:/etc/nginx/nginx.conf:ro7      - ./conf.d:/etc/nginx/conf.d:ro8  app:9    image: node:1810    volumes:11      - ./config/app.json:/app/config/app.json:ro
```

Execution

Terminal window

```
$ docker compose exec nginx cat /etc/nginx/nginx.conf# nginx configuration
```

-   :ro makes mount read-only
-   Prevents accidental modifications

#### Use Environment Files for Secrets

Store secrets in separate .env files and load them securely

Code

```
1version: '3.9'2services:3  app:4    image: node:185    env_file:6      - .env7      - .env.secrets8    environment:9      DATABASE_PASSWORD: ${DB_PASSWORD}10      API_KEY: ${API_KEY}
```

Execution

Terminal window

```
$ cat .env.secretsDB_PASSWORD=super_secret_password_123API_KEY=sk-abc123def456
```

-   Add .env.secrets to .gitignore
-   Keep secrets out of version control
-   Consider using Docker secrets for production

## Build Configuration

### Build from Dockerfile

Build custom images from Dockerfile during compose up

#### Accessibility

Intermediate

#### Keywords

buildDockerfilecustom imagebuild context

#### Basic Build Configuration

Build Docker image from Dockerfile in current directory

Code

```
1version: '3.9'2services:3  app:4    build: .5    ports:6      - "3000:3000"7    environment:8      NODE_ENV: development
```

Execution

Terminal window

```
$ docker compose build[+] Building 12.3s (15/15) FINISHED => [internal] load build definition from Dockerfile => [stage-0 1/5] FROM node:18 => [stage-0 2/5] WORKDIR /app => [stage-0 3/5] COPY package*.json ./ => [stage-0 4/5] RUN npm ci => [stage-0 5/5] RUN npm run build => exporting to imageSuccessfully tagged my-app-app:latest
```

-   build: . uses Dockerfile in current directory
-   Image tagged as project\_service:latest

#### Build with Specific Dockerfile and Context

Build from different Dockerfile with custom context and build arguments

Code

```
1version: '3.9'2services:3  app:4    build:5      context: ./src6      dockerfile: Dockerfile.prod7      args:8        NODE_ENV: production9        BUILD_VERSION: 1.0.010  api:11    build:12      context: ./api-service13      dockerfile: Dockerfile
```

Execution

Terminal window

```
$ docker compose build[+] Building 25.1s (20/20) FINISHED => [internal] load build definition from ./src/Dockerfile.prod => [stage-0 1/8] FROM node:18 => Setting build args: NODE_ENV=production, BUILD_VERSION=1.0.0Successfully tagged my-app-app:latest
```

-   context: directory with Dockerfile
-   dockerfile: specify non-standard Dockerfile name
-   args: pass build-time arguments

#### Multi-Stage Build with Compose

Use multi-stage build to create smaller final images

Code

```
1version: '3.9'2services:3  app:4    build:5      context: .6      dockerfile: Dockerfile.multistage7      target: runtime8      args:9        PYTHON_VERSION: 3.11
```

Execution

Terminal window

```
$ docker compose build[+] Building 15.2s (25/25) FINISHED => [builder 1/8] FROM python:3.11 => [builder 2/8] WORKDIR /build => [builder 3/8] COPY . . => [builder 4/8] RUN pip install -r requirements.txt => [runtime 1/3] FROM python:3.11-slim => [runtime 2/3] COPY --from=builder /build/app /appSuccessfully tagged my-app-app:latest
```

-   target: build specific stage
-   Copy artifacts from builder stage to reduce size

### Build Arguments and Cache

Pass arguments to builds and manage build cache

#### Accessibility

Intermediate

#### Keywords

build argscacheno-cachebuild-time

#### Build Arguments in Dockerfile

Pass build-time arguments that become available as ARG in Dockerfile

Code

```
1version: '3.9'2services:3  app:4    build:5      context: .6      args:7        - BUILD_DATE=2026-02-288        - VCS_REF=abc123def4569        - VERSION=1.0.0
```

Execution

Terminal window

```
$ docker compose build[+] Building 10.5s (8/8) FINISHED => [internal] load build definition => [stage-0 1/3] FROM node:18 => [stage-0 2/3] RUN echo "Version: 1.0.0" => [stage-0 3/3] RUN echo "Built: 2026-02-28"
```

-   Args are passed during build phase only
-   Use ARG instruction in Dockerfile
-   Environment-specific configuration

#### Cache Management

Skip Docker layer cache or force rebuilding with fresh images

Code

Terminal window

```
docker compose build --no-cachedocker compose build --no-cache appdocker compose build --pull
```

Execution

Terminal window

```
$ docker compose build --no-cache[+] Building 30.2s (15/15) FINISHED => [stage-0 1/5] FROM node:18 => [stage-0 2/5] WORKDIR /app => [stage-0 3/5] COPY . .  [cached] => [stage-0 4/5] RUN npm ci [not cached]Successfully tagged my-app-app:latest
```

-   \--no-cache: rebuild all layers
-   \--pull: always pull base images
-   Useful when dependencies change

## Advanced Features

### Health Checks & Monitoring

Configure health checks to monitor container status

#### Accessibility

Advanced

#### Keywords

healthcheckmonitoringlivenessreadiness

#### Implement Health Checks

Define health checks to verify container is running correctly

Code

```
1version: '3.9'2services:3  web:4    image: nginx:latest5    healthcheck:6      test: ["CMD", "curl", "-f", "http://localhost"]7      interval: 30s8      timeout: 10s9      retries: 310      start_period: 40s11  api:12    image: node:1813    healthcheck:14      test: ["CMD-SHELL", "curl -f http://localhost:3000/health || exit 1"]15      interval: 30s16      timeout: 10s17      retries: 3
```

Execution

Terminal window

```
$ docker compose up -d$ docker compose psNAME    IMAGE         STATUSweb-1   nginx:latest  Up 30s (health: starting)api-1   node:18       Up 25s (health: healthy)
```

-   test: command to run (CMD or CMD-SHELL)
-   start\_period: grace period before health checks
-   Exit code 0 = healthy, non-zero = unhealthy

#### Depends On with Health Checks

Wait for dependent service to pass health check before starting

Code

```
1version: '3.9'2services:3  db:4    image: postgres:155    healthcheck:6      test: ["CMD-SHELL", "pg_isready -U postgres"]7      interval: 10s8      timeout: 5s9      retries: 510  app:11    image: node:1812    depends_on:13      db:14        condition: service_healthy
```

Execution

Terminal window

```
$ docker compose updb-1 | PostgreSQL accepting connectionsapp-1 | Waiting for service_healthy condition on db
```

-   condition: service\_healthy waits for passing health check
-   Prevents startup order issues

### Service Dependencies

Define startup order and dependencies between services

#### Accessibility

Intermediate

#### Keywords

depends\_onstartup orderdependenciesconditions

#### Basic Service Dependencies

Specify that app depends on db and cache services

Code

```
1version: '3.9'2services:3  db:4    image: postgres:155  cache:6    image: redis:77  app:8    image: node:189    depends_on:10      - db11      - cache
```

Execution

Terminal window

```
$ docker compose up[+] Running 3/3 ✔ Container pg-1     Started ✔ Container redis-1  Started ✔ Container app-1    Started
```

-   Services listed as dependencies start first
-   Does not wait for service to be ready, only for container to start

#### Conditional Dependency with Service Ready

Wait for service to be healthy before starting dependent service

Code

```
1version: '3.9'2services:3  db:4    image: postgres:155    healthcheck:6      test: ["CMD-SHELL", "pg_isready -U postgres"]7      interval: 5s8      timeout: 5s9      retries: 510  api:11    image: node:1812    depends_on:13      db:14        condition: service_healthy
```

Execution

Terminal window

```
$ docker compose up -ddb-1 | PostgreSQL startedapi-1 waiting for db...api-1 | Connected to database
```

-   Requires health check on dependency
-   Prevents connection errors at startup

### Labels & Metadata

Add metadata labels to containers and services

#### Accessibility

Intermediate

#### Keywords

labelsmetadatataggingorganization

#### Add Labels to Services

Attach metadata labels to services for organization and tooling

Code

```
1version: '3.9'2services:3  web:4    image: nginx:latest5    labels:6      com.example.description: "Web server"7      com.example.version: "1.0"8      com.example.tier: "frontend"9  app:10    image: node:1811    labels:12      com.example.description: "API server"13      com.example.version: "2.0"14      com.example.tier: "backend"
```

Execution

Terminal window

```
$ docker inspect my-app-web-1 --format='{{json .Config.Labels}}'{"com.example.description":"Web server","com.example.tier":"frontend","com.example.version":"1.0"}
```

-   Use reverse domain notation for label keys
-   Can be inspected with docker inspect
-   Used by monitoring and orchestration tools

### Override Entrypoint & Command

Override default container command and entrypoint

#### Accessibility

Intermediate

#### Keywords

entrypointcommandoverridecmd

#### Override Command

Override default CMD with custom commands

Code

```
1version: '3.9'2services:3  app:4    image: node:185    working_dir: /app6    command: npm start7    volumes:8      - ./app:/app9  worker:10    image: node:1811    working_dir: /app12    command: npm run worker13    volumes:14      - ./app:/app
```

Execution

Terminal window

```
$ docker compose up -dapp-1 | npm startapp-1 | Server listening on port 3000
```

-   command: overrides CMD from Dockerfile
-   Each service can have different command

#### Override Entrypoint

Completely override container entrypoint

Code

```
1version: '3.9'2services:3  app:4    image: myapp:latest5    entrypoint: /bin/bash6    command: -c "npm install && npm start"
```

Execution

Terminal window

```
$ docker compose upapp-1 | /bin/bash -c npm install && npm start
```

-   entrypoint: completely replaces ENTRYPOINT from Dockerfile
-   Use for different execution paths

## Docker Compose Commands

### Lifecycle Management (up/down/stop)

Start, stop, and manage container lifecycle

#### Accessibility

Beginner

#### Keywords

updownstopstartrestart

#### Start Services (docker compose up)

Start services defined in compose file

Code

Terminal window

```
docker compose updocker compose up -ddocker compose up --builddocker compose up -f compose.yml -f docker-compose.prod.yml
```

Execution

Terminal window

```
[+] Running 3/3 ✔ Container pg-1      Started ✔ Container redis-1   Started ✔ Container app-1     Started
```

-   up: creates and starts services
-   \-d: detached mode (background)
-   \--build: build before starting

#### Stop and Remove Services (docker compose down)

Stop services or remove containers, networks, and optionally volumes

Code

Terminal window

```
docker compose stopdocker compose downdocker compose down -vdocker compose down --rmi all
```

Execution

Terminal window

```
Stopping my-app-app-1 ... doneRemoving my-app-app-1 ... doneRemoving network my-app_default
```

-   stop: stops containers (can restart)
-   down: removes containers, networks
-   \-v: also remove named volumes
-   \--rmi all: remove created images

#### Pause and Resume Services

Pause containers or forcefully kill them

Code

Terminal window

```
docker compose pausedocker compose unpausedocker compose kill
```

Execution

Terminal window

```
Pausing my-app-app-1 ... doneUnpausing my-app-app-1 ... doneKilling my-app-app-1 ... done
```

-   pause: freezes containers (keeps in memory)
-   unpause: resumes paused containers
-   kill: sends SIGKILL (force termination)

### Execution & Interaction (exec/run/logs)

Run commands in containers and view logs

#### Accessibility

Intermediate

#### Keywords

execrunlogsinteractiondebugging

#### Execute Commands in Running Container

Run commands in already running containers

Code

Terminal window

```
docker compose exec app npm testdocker compose exec -u root app apt-get updatedocker compose exec db psql -U postgres -d mydbdocker compose exec -it app /bin/bash
```

Execution

Terminal window

```
> npm test
PASS __tests__/app.test.js  App    ✓ should start successfully (142ms)
Test Suites: 1 passedTests: 1 passed
```

-   \-i: interactive
-   \-t: allocate pseudo-terminal
-   \-u: run as specific user

#### Run One-Off Container

Run temporary containers to execute commands

Code

Terminal window

```
docker compose run app npm installdocker compose run --rm worker node scripts/migrate.jsdocker compose run -e NODE_ENV=test app npm test
```

Execution

Terminal window

```
> npm installadded 150 packages in 45s
```

-   run: starts new container for command
-   \--rm: automatically remove container after exit
-   \-e: set environment variables

#### View Container Logs

View output logs from containers

Code

Terminal window

```
docker compose logsdocker compose logs appdocker compose logs -f appdocker compose logs --tail=100 appdocker compose logs --timestamps app
```

Execution

Terminal window

```
app-1     | npm startapp-1     | Server listening on port 3000app-1     | GET /api/health 200 12msapp-1     | POST /api/data 201 45ms
```

-   \-f: follow logs in real-time
-   \--tail: show last N lines
-   \--timestamps: add timestamps to logs

### Status & Information (ps/config/port)

Check container status and view configurations

#### Accessibility

Beginner

#### Keywords

psconfigportstatusinformation

#### List Running Containers (docker compose ps)

List all containers defined in compose file

Code

Terminal window

```
docker compose psdocker compose ps --alldocker compose ps --format jsondocker compose ps -a
```

Execution

Terminal window

```
NAME      IMAGE            PORTS                    STATUSapp-1     node:18          0.0.0.0:3000->3000/tcp   Up 2 minutes (healthy)db-1      postgres:15      0.0.0.0:5432->5432/tcp   Up 3 minutescache-1   redis:7          6379/tcp                 Up 2 minutes 45s
```

-   Shows running containers by default
-   \-a: include stopped containers
-   \--format json: output JSON

#### View Merged Configuration

Display merged compose configuration from all files

Code

Terminal window

```
docker compose configdocker compose config --resolve-image-digestsdocker compose config --format json
```

Execution

Terminal window

```
name: my-appservices:  app:    image: 'node:18'    ports:      - mode: ingress        target: 3000        published: "3000"        protocol: tcpversion: '3.9'
```

-   Shows final resolved configuration
-   Useful for debugging variable substitution
-   \--format json: output as JSON

#### Get Service Port Mappings

Show public port for specific container port

Code

Terminal window

```
docker compose port app 3000docker compose port db 5432docker compose port --index=2 app 3000
```

Execution

Terminal window

```
0.0.0.0:30000.0.0.0:5432
```

-   Useful for discovering mapped ports
-   \--index: for multiple instances

### Build & Push Commands

Build and manage Docker images

#### Accessibility

Intermediate

#### Keywords

buildpushpullimage management

#### Build Services

Build Docker images from specified Dockerfiles

Code

Terminal window

```
docker compose builddocker compose build appdocker compose build --no-cachedocker compose build --pull
```

Execution

Terminal window

```
[+] Building 12.3s (15/15) FINISHED => [app internal] load build definition from Dockerfile => [app stage-0 1/5] FROM node:18 => [app stage-0 2/5] WORKDIR /app => [app stage-0 3/5] COPY package*.json ./ => [app stage-0 4/5] RUN npm ci => [app stage-0 5/5] RUN npm run build => [app] exporting to imageSuccessfully tagged my-app-app:latest
```

-   Builds all services with build context by default
-   \--no-cache: skip layer cache
-   \--pull: always update base images

#### Push Images to Registry

Push images to Docker registry

Code

Terminal window

```
docker compose pushdocker compose push appdocker compose push myregistry.azurecr.io/myapp:v1.0
```

Execution

Terminal window

```
Pushing app (myregistry.azurecr.io/myapp:v1.0)...The push refers to repository [myregistry.azurecr.io/myapp]abc123: Pusheddef456: Pushedghi789: Pushedv1.0: digest: sha256:1234567890abcdef
```

-   Requires image to be built first
-   Authenticate to the registry before pushing

## Network & Security

### Network Modes & Links

Configure network modes and inter-service communication

#### Accessibility

Advanced

#### Keywords

network modelinksbridgehostcommunication

#### Service Discovery via Service Name

Services communicate automatically using service names as hostnames

Code

```
1version: '3.9'2services:3  app:4    image: node:185    environment:6      DATABASE_URL: postgresql://postgres:5432/mydb7  postgres:8    image: postgres:159    environment:10      POSTGRES_DB: mydb11      POSTGRES_PASSWORD: password
```

Execution

Terminal window

```
$ docker compose up -d$ docker compose exec app ping postgresPING postgres (172.18.0.2): 56 data bytes64 bytes from 172.18.0.2: seq=0 ttl=64 time=0.123 ms
```

-   Service names resolve to container IPs
-   Works across custom networks
-   Default bridge network

#### Legacy Service Links

Create DNS aliases for services (legacy feature)

Code

```
1version: '3.9'2services:3  app:4    image: node:185    links:6      - postgres:database7      - redis:cache8    environment:9      DATABASE_URL: postgresql://database:543210  postgres:11    image: postgres:1512  redis:13    image: redis:7
```

Execution

Terminal window

```
$ docker compose exec app cat /etc/hosts127.0.0.1   localhost172.18.0.2  database172.18.0.3  cache
```

-   Deprecated in favor of custom networks
-   Still works for backwards compatibility
-   Not recommended for new projects

### User Permissions & Security

Configure user context and security options

#### Accessibility

Advanced

#### Keywords

userpermissionssecurityuidgid

#### Run Services as Specific User

Run containers as specific user instead of root

Code

```
1version: '3.9'2services:3  app:4    image: node:185    user: "1000:1000"6    working_dir: /app7    volumes:8      - ./src:/app/src9  worker:10    image: node:1811    user: node12    working_dir: /app
```

Execution

Terminal window

```
$ docker compose exec app iduid=1000 gid=1000 groups=1000
```

-   Format: uid:gid or username
-   Improves security and file permissions
-   Prevents permission issues with mounted volumes

#### Security Options

Configure security options and capabilities

Code

```
1version: '3.9'2services:3  app:4    image: node:185    security_opt:6      - no-new-privileges:true7  privileged:8    image: ubuntu:latest9    privileged: false10    cap_add:11      - NET_ADMIN12    cap_drop:13      - ALL
```

Execution

Terminal window

```
$ docker compose exec app iduid=0(root) gid=0(root) groups=0(root)
```

-   no-new-privileges: prevent privilege escalation
-   CAP\_ADD: add specific Linux capabilities
-   CAP\_DROP: remove capabilities

### External Networks & Scaling

Connect to external networks and scale services

#### Accessibility

Advanced

#### Keywords

external networksscalingreplicasmulti-container

#### Scale Services

Run multiple instances of a service for horizontal scaling

Code

Terminal window

```
docker compose up -d --scale app=3docker compose up -d --scale worker=5 --scale app=2
```

Execution

Terminal window

```
[+] Running 8/8 ✔ Container app-1       Started ✔ Container app-2       Started ✔ Container app-3       Started ✔ Container worker-1    Started ✔ Container worker-2    Started ✔ Container worker-3    Started ✔ Container worker-4    Started ✔ Container worker-5    Started
```

-   \--scale service=count
-   Each instance gets unique name (app-1, app-2, etc.)
-   Use with load balancer for traffic distribution

#### Connect Multiple Compose Projects

Connect services to external networks shared across projects

Code

```
1version: '3.9'2services:3  app:4    image: node:185    networks:6      - monolith7      - external-network8networks:9  monolith:10    driver: bridge11  external-network:12    external: true13    name: company-network
```

Execution

Terminal window

```
$ docker compose up -d[+] Running 1/1 ✔ Container app-1  Started$ docker network inspect company-network[  {    "Containers": {      "abc123": {"Name": "app-1"}    }  }]
```

-   External networks must be created beforehand
-   Multiple compose files can share networks
-   Enables multi-service orchestration

Was this useful?

## Share

[Facebook](https://facebook.com/sharer/sharer.php?u=https%3A%2F%2Fmkabumattar.com%2Fcheatsheets%2Fdocker-compose "Share on Facebook")[Twitter](https://twitter.com/intent/tweet/?text=Docker%20Compose&url=https%3A%2F%2Fmkabumattar.com%2Fcheatsheets%2Fdocker-compose "Share on Twitter")[LinkedIn](https://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Fmkabumattar.com%2Fcheatsheets%2Fdocker-compose&title=Docker%20Compose&summary=Docker%20Compose%20reference%20guide%20covering%20services%2C%20volumes%2C%20networks%2C%20ports%2C%20environment%20variables%2C%20commands%2C%20configurations%2C%20and%20container%20orchestration%20best%20practices.&source=https://mkabumattar.com "Share on LinkedIn")[WhatsApp](https://wa.me/?text=Docker%20Compose%20https%3A%2F%2Fmkabumattar.com%2Fcheatsheets%2Fdocker-compose "Share on WhatsApp")[Telegram](https://t.me/share/url?url=https%3A%2F%2Fmkabumattar.com%2Fcheatsheets%2Fdocker-compose&text=Docker%20Compose "Share on Telegram")[Reddit](https://www.reddit.com/submit?url=https%3A%2F%2Fmkabumattar.com%2Fcheatsheets%2Fdocker-compose&title=Docker%20Compose "Share on Reddit")[Hacker News](http://news.ycombinator.com/submitlink?u=https%3A%2F%2Fmkabumattar.com%2Fcheatsheets%2Fdocker-compose&t=Docker%20Compose "Share on Hacker News")[Pinterest](https://pinterest.com/pin/create/button/?url=https%3A%2F%2Fmkabumattar.com%2Fcheatsheets%2Fdocker-compose&media=&description=Docker%20Compose%20reference%20guide%20covering%20services%2C%20volumes%2C%20networks%2C%20ports%2C%20environment%20variables%2C%20commands%2C%20configurations%2C%20and%20container%20orchestration%20best%20practices. "Share on Pinterest")[Email](<mailto:?subject=Docker%20Compose&body=Check out this article: https%3A%2F%2Fmkabumattar.com%2Fcheatsheets%2Fdocker-compose>)

## Comments

## You might also enjoy

More posts on similar topics

## [Dockerfile](/cheatsheets/dockerfile)

-   [Mohammad Abu Mattar](/authors/mohammad-abu-mattar)
-   Reference

This cheat sheet covers the core Dockerfile instructions, best practices, and common pitfalls for building small, secure Docker images. Each section pairs a Dockerfile snippet with the build output it

[read more](/cheatsheets/dockerfile)

## [Docker Swarm](/cheatsheets/docker-swarm)

-   [Mohammad Abu Mattar](/authors/mohammad-abu-mattar)
-   DevOps
-   Docker
-   Containers
-   Orchestration
-   Deployment

This cheatsheet is a reference for managing Docker Swarm clusters, services, and stacks. It covers the commands and best practices for scaling, updating, and monitoring your swarm applications.

#Docker Swarm#Orchestration#Containers+4 tags

[read more](/cheatsheets/docker-swarm)

## [kubectl](/cheatsheets/kubectl)

-   [Mohammad Abu Mattar](/authors/mohammad-abu-mattar)
-   DevOps
-   Kubernetes
-   CLI
-   Container Orchestration
-   Cloud Native

kubectl is the command-line tool you use to talk to a Kubernetes cluster. Whatever you can do through a dashboard, you can do faster here: deploy apps, inspect resources, stream logs, run commands ins

#Kubectl#Kubernetes#K8s+5 tags

[read more](/cheatsheets/kubectl)

## [Docker](/cheatsheets/docker)

-   [Mohammad Abu Mattar](/authors/mohammad-abu-mattar)
-   DevOps
-   Docker
-   Containers
-   Deployment

Docker is a containerization platform that packages applications with their dependencies into isolated, portable environments called containers. It enables developers to build, ship, and run applicati

#Docker#Containers#Images+3 tags

[read more](/cheatsheets/docker)

## [Helm](/cheatsheets/helm)

-   [Mohammad Abu Mattar](/authors/mohammad-abu-mattar)
-   DevOps
-   Kubernetes
-   Helm
-   Package Management
-   Cloud Native

Helm is the package manager for Kubernetes that simplifies the deployment, management, and upgrade of applications. It uses charts, which are templated Kubernetes manifests, to build reusable, configu

#Helm#Kubernetes#Package Manager+5 tags

[read more](/cheatsheets/helm)

## [Kubernetes](/cheatsheets/kubernetes)

-   [Mohammad Abu Mattar](/authors/mohammad-abu-mattar)
-   DevOps
-   Kubernetes
-   Container Orchestration
-   Cloud Native
-   Cluster Management

Kubernetes is the de facto standard for container orchestration. It automates deployment, scaling, and management of containerized applications across clusters of machines. Configuration is declarativ

#Kubernetes#Kubectl#Containers+5 tags

[read more](/cheatsheets/kubernetes)

6 related posts
