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

References

Docker Compose Overview


Last modified February 19, 2025: Update azure-point-to-site-vpn.md (a9c807a)