arrow_back
Back

Docker Compose: services, networks, volumes, and compose.yml

Andrew Dorokhov Andrew Dorokhov schedule 3 min read
menu_book Table of Contents

Docker Compose is a tool for defining and running multi-container applications. It uses YAML files to configure service groups and is designed for quickly setting up development environments.

open_in_new Official documentation

Installation

sudo curl -L "https://github.com/docker/compose/releases/download/1.25.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version

See open_in_new docs.docker.com/compose/install for current versions.

docker-compose.yml

Be careful not to use unescaped $ characters — escape them as $$ if needed.

Example:

version: '3'
services:
    web:
        image: nginx
        ports:
        - "8080:80"
        volumes:
        - nginx_html:/usr/share/nginx/html/
        links:
        - redis
    redis:
        image: redis
volumes:
    nginx_html: {}

Four top-level keys: version, services, networks, volumes.

services

Each service definition represents one container. The service name becomes part of the container name.

version: '3'
services:
    weather-app:
        build:
            context: .
            args:
            - VERSION=v2.0
        ports:
            - "8081:3000"
        environment:
            - NODE_ENV=production

Key service options:

  • container_name — explicit container name.
  • build — build from a Dockerfile in the given context (.). Each service needs either build or image.
  • image — image tag or ID, like the image argument in docker run.
  • ports — same as -p in docker run. Use quotes to avoid YAML parsing issues (e.g., 56:56 as hex).
  • environment — same as -e in docker run.
  • volumes — same as -v in docker run.
  • networks — attach to named networks:
services:
    test:
        networks:
            - my_network
            - another_network
  • depends_on — declare service dependencies:
services:
    test:
        depends_on:
            - mysql
  • links — legacy container linking (prefer networks):
identidock:
  links:
    - dnmonster
  • extends — inherit configuration from a shared file. Values in links and volumes-from are not inherited.

networks

Define networks managed by Compose:

networks:
  my_network:
  my_second_network:

volumes

Define volumes managed by Compose:

volumes:
  my_volume:
  my_second_volume:

Driver options can be added as needed.

Restart option

no is the default restart policy, and it does not restart a container under any circumstance.

restart: "no"
restart: always
restart: on-failure
restart: unless-stopped

When always is specified, the container always restarts.

unless-stopped always restarts a container, except when the container is stopped (manually or otherwise).

The on-failure policy restarts a container if the exit code indicates an on-failure error. Optionally, limit retries with :max-retries:

restart: on-failure:10

open_in_new Documentation page .

Compose commands

up

Create and start all containers defined in the Compose file. Logs are merged into one stream. Use -d for detached mode.

docker-compose up
docker-compose up -d

Set a custom compose file via environment variable:

COMPOSE_FILE=prod.yml docker-compose up -d

ps

List containers created by Compose.

docker-compose ps

stop / start / restart / down

docker-compose stop      # stop without removing
docker-compose start     # start stopped services
docker-compose restart
docker-compose down      # stop and remove containers, networks, images, volumes

build

Rebuild all images from Dockerfiles. up only builds if images do not exist — run build explicitly when source changes.

docker-compose build

run

Run a one-off command in a service container (not as a long-running service). Dependent services start unless --no-deps is set. Commands passed via run override the service command. By default, run does not create the ports defined in the service config.

docker-compose run <service> <command>

logs

Show colorized, merged logs from all Compose-managed containers.

docker-compose logs

rm

Remove stopped containers. Use -v to also remove volumes managed by Docker.

docker-compose rm
docker-compose rm -v

Lifecycle

After changing source code, run docker-compose build then docker-compose up -d. Compose rebuilds the image and replaces the running container. Existing volumes from old containers are preserved — databases and caches survive upgrades (which can cause stale data; be careful when replacing containers).

If only the Compose YAML changed (no image rebuild needed), run docker-compose up -d to recreate containers with new settings. Use --force-recreate to stop everything and recreate all containers.

After a work session, run docker-compose stop. The same containers restart with docker-compose start or up if source code has not changed. Use docker-compose rm to permanently remove the application’s containers.

code

Need Help with Development?

Happy to help — reach out via the contacts or go straight to my Upwork profile.

work View Upwork Profile arrow_forward
Next Article

Connecting Docker containers: links, hosts, and environment

arrow_forward