Skip to content

Using Docker Compose

Important

There are two ways to call docker compose.

  1. docker compose [options] (new; recommended)
  2. docker-compose [options] (legacy; not recommended)

Docker compose allows you to start a suite of applications with a single command. Docker compose is the declarative version of the Docker CLI. It is capable of starting one or more containers, attaching networks to containers, mounting volumes to containers, and more.

Docker compose simplifies the process of connecting containers together using a shared network. However, it can only do this for one host. If you need the deploy containers across multiple hosts, see Using Kubernetes.

Important Commands

docker compose up --build

Run the services in the compose file, building images if needed. -d/--detach: Start containers in background

docker compose down

Stop the applications and containers (but don't remove them)

docker compose ps

Show information about the running docker compose containers

docker compose build

Build the apps in the compose file --no-cache: Don't use the cache when building --pull: Always pull a newer version of the image

The docker-compose.yml file

In the docker-compose.yml file you use declare the commands that would otherwise be typed out with the Docker CLI. Docker compose will start the containers under the hood.

yaml
version: "3.8" # use up-to-date compose file format version

services: # configure the services here
  frontend: # Here is the 'frontend' service
    build: ./frontend # This should be the path to a Dockerfile
    ports:
      - 3000:3000 # Map port 3000 in container to 3000 on host
    environment:
      - VARIABLE="value" 
      - VARIABLE2 # This environment variable is taken from the host
  backend:
	restart: always # Set the restart policy (see Restart Policies below)
    build: ./backend
    ports:
      - 3001:3001
  database:
    image: redis # Use image from DockerHub instead of building a Dockerfile
    volumes:
      - project:/data/db # Map local `project` directory to `/data/db` in container

volumes: # Define any/all volumes used in the compose file
  project:
version: "3.8" # use up-to-date compose file format version

services: # configure the services here
  frontend: # Here is the 'frontend' service
    build: ./frontend # This should be the path to a Dockerfile
    ports:
      - 3000:3000 # Map port 3000 in container to 3000 on host
    environment:
      - VARIABLE="value" 
      - VARIABLE2 # This environment variable is taken from the host
  backend:
	restart: always # Set the restart policy (see Restart Policies below)
    build: ./backend
    ports:
      - 3001:3001
  database:
    image: redis # Use image from DockerHub instead of building a Dockerfile
    volumes:
      - project:/data/db # Map local `project` directory to `/data/db` in container

volumes: # Define any/all volumes used in the compose file
  project:

Docker compose will create a network when starting a compose session.

Connecting containers in application code

In the above example, when you connect to the redis-server in code, use the hostname redis-server instead of a conventional IP or endpoint. For example with Express.js, use

javascript
const client = redis.createClient({
const client = redis.createClient({

host: 'redis-server', port: 6379 });

Restart Policies

Use the restart declaration to signal how each container responds to a stoppage or crash.

PolicyDescription
"no"Never restart the container if it crashes
alwaysRestart the container for any reason if it crashes
on-failureOnly restart the container stops with an error code
unless-stoppedAlways restart unless it is forcibly stopped

Tips 'n Tricks

Rebuilding a docker compose container and image

sh
docker-compose up --build --force-recreate --no-deps [<service_name>..]

# Force rebuild ignoring any cached layers
docker-compose build --no-cache [<service_name>..]
docker-compose up --build --force-recreate --no-deps [<service_name>..]

# Force rebuild ignoring any cached layers
docker-compose build --no-cache [<service_name>..]

Troubleshooting

If you see the following error when issuing docker-compose up

sh
ERROR: Couldn't connect to Docker daemon at http+docker://localhost - is it running?
ERROR: Couldn't connect to Docker daemon at http+docker://localhost - is it running?
  1. Add your user to the docker group sudo usermod -aG docker $USER
  2. Create a symbolic link to /usr/bin using the following command sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
  3. Restart the Docker service with systemctl restart docker.service (or something very close to that)

ADDITIONAL RESOURCES