Docker Compose

Table of contents
  1. Why use Docker Compose?
  2. Dockerfile / docker-compose.yml
    1. Dockerfile
    2. docker-compose.yml
  3. Example usage
  4. Useful commands
  5. Itty Bitties
    1. Build context
    2. Default network

Why use Docker Compose?

Compose is a tool to help define and run containers/services.

It basically packs all those docker bulid ..., docker run ... commands into a single yaml.


Dockerfile / docker-compose.yml

Dockerfile

Dockerfile defines the recipe to create an image.

docker-compose.yml

docker-compose.yml defines services or containers that run images.


Example usage

version: '3.9'

services:
  my-service:
    container_name: my-container
    build:
      context: ./src
      dockerfile: Dockerfile
    ports:
      - 1234:1234
    volumes:
      - ./src:/www

For ports and volumes the order of syntax is <host>:<container>.


Useful commands

# Create and start containers
docker-compose up

# Build images and start containers
docker-compose up --build

# Start the containers in detached mode
docker-compose up --d

# Stop and remove containers and default networks
docker-compose down

# Lists containers (even the ones that are exited)
docker-compose ps

Itty Bitties

Suppose the project root directory is called proj.

proj
├── docker-compose.yml
└── src
   ├── Dockerfile
   └── ...
# docker-compose.yml
services:
  my-service:
    container_name: my-container
    build:
      context: ./src
      dockerfile: Dockerfile

Build context

With docker build -f ../Dockerfile ., it is possible for the Dockerfile to be outside of the build context.

However, it seems that with Compose, the Dockerfile must be within the build context.

So in the example case Dockerfile must be under src, otherwise it will produce an error:

failed to solve: rpc error: code = Unknown desc = failed to solve with frontend dockerfile.v0: failed to read dockerfile: open /var/lib/docker/tmp/your-build-context/Dockerfile: no such file or directory

Default network

Compose automatically creates a bridge network of name proj_default, and adds all service containers to it.

Check that is is true by,

# Locate the created default network
docker network ls

# Inspect the containers in it
docker inspect proj_default

Then you will see my-container listed under network proj_default.