Docker Compose

Docker Compose is a tool for defining and running multi-container Docker applications. It allows you to define all of the services that make up your application in a single YAML file, and then use that file to start and stop your application as a group of interconnected containers.

Docker Compose is particularly useful for complex applications that require multiple containers to work together, such as web applications that require a database and a web server. Instead of manually starting each container and managing their interactions, Docker Compose allows you to define all of the containers that make up your application in a single file, and then start them with a single command.

Here’s an overview of how Docker Compose works:

Define your services: In a Docker Compose YAML file, you define each service that makes up your application, including the Docker image to use, any environment variables or command line arguments to pass, and any network or volume settings.

Start your application: Once you have defined your services, you can start your application by running the docker-compose up command. Docker Compose will start each container and configure the networking and storage as specified in the YAML file.

Manage your application: Once your application is running, you can use Docker Compose commands to manage it. For example, you can use docker-compose stop to stop your application, or docker-compose logs to view the logs for all of your containers.

Docker Compose also provides several other features that make it easier to manage your multi-container application, such as the ability to scale individual services up or down, and the ability to define environment variables and other settings in a separate .env file.

The default name for a Docker Compose file is docker-compose.yaml.

Keys

Keys are values defined within the Docker Compose YAML file that comprise the contents.

version: This specifies the version of the Docker Compose file format. It should match the version of Docker Compose you are using.

services: This is the main part of the Docker Compose file. Under services, you define all the different containers (services) that make up your application.

build: This can be a path to a Dockerfile or an object with the path and context for building an image.

image: This specifies the image to start the container from. It can be an image from Docker Hub or from a local Dockerfile build.

container_name: This sets a custom name for the container rather than a randomly generated one.

ports: This maps the host’s ports to the container’s ports. The syntax is [host-port]:[container-port].

volumes: This is used for mounting host directories into the Docker container.

environment: This allows you to set environment variables inside the container.

depends_on: This can be used to define dependencies between services, ensuring that services are started in dependency order.

networks: This specifies the networks the container should connect to.

Here’s an example of a Docker Compose file:

version: '3'
services:
  web:
    build: .
    ports:
      - "5000:5000"
    volumes:
      - .:/code
    depends_on:
      - db
  db:
    image: postgres
    environment:
      POSTGRES_PASSWORD: example

In this example:

  • There are two services, web and db.
  • The web service is built using the Dockerfile in the current directory, exposes and maps port 5000, and mounts the current directory to /code in the container.
  • The web service also depends on the db service.
  • The db service uses the postgres image and sets an environment variable POSTGRES_PASSWORD.

Create a simple Docker Compose application

This example will create a simple web page comprised of two Docker containers setup by Docker Compose. The result will be a web container and a redis container running as a pair to form a single application. The web application uses Python with Flask and Redis. Flask is a lightweight web framework for Python, and Redis is an in-memory database that persists on disk. The web application will increment a counter in Redis each time the page is visited.

Working directory Setup a working directory so you can create files and generate Docker data. I use GitHub for these projects as I can save them for later.

My working directory is called simple-visitorcounter.

Create the Python app code Create a file called app.py in the working directory and past the code. This code uses the Flask framework to create a web server. Each time the default route (/) is accessed, we increment a value in the Redis database and display a message with the number of hits.

# app.py
from flask import Flask
from redis import Redis

app = Flask(__name__)
redis = Redis(host='redis', port=6379)

@app.route('/')
def hello():
    count = redis.incr('hits')
    return 'Hello World! This page has been visited {} times.\n'.format(count)

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8000, debug=True)

Create a Dockerfile for the application Specify Python 3.7 as our base image. Copy a requirements file and install the Python dependencies (Flask and Redis). Finally, copy the application and set the command to run the application.

FROM python:3.7-alpine
WORKDIR /code
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
COPY . .
CMD ["python", "app.py"]

Create a requirements.txt file in the working directory and paste the following.

flask
redis

Create a docker-compose.yml file In the docker-compose.yml file, define two services: web and redis. The web service is the Flask application, which is built from the Dockerfile in the current directory, and is mapped to port 8000. The redis service uses the official Redis image from Docker Hub.

version: '3'
services:
  web:
    build: .
    ports:
      - "8000:8000"
  redis:
    image: "redis:alpine"

Build and run the application with Docker Compose: You should now be able to visit localhost:8000 in your web browser and see your application running. Each time you refresh the page, the counter should increase.

docker-compose up

Install Docker Compose on Raspbian

To install Docker Compose on Raspbian, you can follow these steps:

  1. Install Docker: First, make sure you have Docker installed. If you haven’t installed it yet, you can do so by running:

    curl -fsSL https://get.docker.com -o get-docker.sh
    sudo sh get-docker.sh
    

    After installation, it’s a good idea to add your user to the docker group to run Docker commands without sudo:

    sudo usermod -aG docker ${USER}
    

    You’ll need to log out and log back in for this to take effect.

  2. Install Docker Compose: Since Raspbian is a 32-bit operating system, you’ll need to install a version of Docker Compose that supports 32-bit architectures. As of my last update in April 2023, Docker Compose is available as a Python package, so you can install it using pip. First, make sure you have pip installed:

    sudo apt-get update
    sudo apt-get install -y python3-pip libffi-dev
    

    Then, install Docker Compose:

    sudo pip3 install docker-compose
    
  3. Verify Installation: Once the installation is complete, you can verify it by checking the version of Docker Compose:

    docker-compose --version
    

    This should output the version of Docker Compose that’s been installed.

References

Docker Compose Overview

Last modified July 21, 2024: update (e2ae86c)