Docker (Guide to Containerization) Part 3

Docker (Guide to Containerization) Part 3

Docker compose

Docker Compose is a powerful tool that allows you to define and manage multi-container Docker applications. It provides a simple and efficient way to describe the relationships and configurations of your application's services using a YAML file called a "docker-compose.yml"

Let's take an instance:

Imagine you're having a picnic with your friends, and you need to prepare different things like sandwiches, drinks, and desserts. Each friend is responsible for one thing, and together, you create a fantastic picnic experience.

Now, think of Docker Compose as a magic picnic planner. It helps you organize your picnic by keeping track of who is responsible for what and how everything should work together. Instead of just one person handling everything, Docker Compose lets you divide the work among different containers (similar to friends in our picnic analogy).

Each container represents a specific task or service, like making sandwiches or mixing drinks. Docker Compose makes sure that these containers can communicate and work together seamlessly, just like your friends at the picnic. It sets up a system where they can share resources, talk to each other, and do their jobs efficiently.

In our picnic, Docker Compose would be like a list that says, "Friend A, you're in charge of sandwiches, use these ingredients and make them this way. Friend B, you handle drinks, use these recipes and make them refreshing. Friend C, you're the dessert expert, follow this recipe and make everyone's sweet tooth happy."

With Docker Compose, you don't have to worry about managing each friend's work individually or making sure they collaborate smoothly. It takes care of everything, making the whole picnic organization much easier. You can focus on enjoying the picnic without getting overwhelmed by the details.

So, in simple terms, Docker Compose is like a magical picnic planner that assigns tasks to different friends (containers), ensures they can work together effectively, and makes your picnic experience enjoyable and hassle-free.

Creating a Docker Compose File

A Docker Compose file is written in YAML (YAML Ain't Markup Language), which is a human-readable data serialization format (You can refer to my article on YAML). YAML is often used for configuration files due to its simplicity and readability.

To create a Docker Compose file (docker-compose.yml), you start by defining the version of Docker Compose you're using, followed by the services and their configurations. Each service represents a container in your application. Here's an example of a simple Docker Compose file:

version: '3'

services:

  web:

    image: nginx:latest

    ports:

      - 80:80

    volumes:

      - ./html:/usr/share/nginx/html

  db:

    image: mysql:latest

    environment:

      - MYSQL_ROOT_PASSWORD=secret

      - MYSQL_DATABASE=mydb

      - MYSQL_USER=user

      - MYSQL_PASSWORD=password

In this example, we have two services: web and db. The web service uses the nginx:latest image, maps port 80 on the host to port 80 in the container, and mounts the html directory from the current directory as the NGINX web server's document root. The db service uses the mysql:latest image and sets some environment variables for configuration.

Networks in Docker Compose

Docker Compose allows you to define networks to enable communication between containers. Networks can be created explicitly in the Docker Compose file (docker-compose.yml ) or created implicitly by Docker Compose.

Here's an example of how to define an explicit network in a Docker Compose file:

version: '3'

services:

  web:

    image: nginx:latest

    networks:

      - frontend

  db:

    image: mysql:latest

    networks:

      - backend


networks:

  frontend:

  backend:

In this example, we define two networks, frontend and backend, and assign each service to its respective network. The explicit network definition allows containers within the same network to communicate with each other using their service names as hostnames.

In Docker Compose, the "links" feature allows containers to communicate with each other by establishing network connections. It helps in creating dependencies and enabling seamless interaction between services. Let's explore this concept with an extensive example.

Consider a scenario where you are building a web application that consists of two containers: a web server and a database. The web server container needs to connect to the database container to retrieve and store data. This is where the "links" feature in Docker Compose comes into play.

Here's an example Docker Compose file (docker-compose.yml) that demonstrates the usage of links:

version: '3'

services:

  web:

    image: mywebapp:latest

    ports:

      - 80:80

    links:

      - db

  db:

    image: mysql:latest

    environment:

      - MYSQL_ROOT_PASSWORD=secret

      - MYSQL_DATABASE=mydb

      - MYSQL_USER=user

      - MYSQL_PASSWORD=password

In this example, we have two services defined: web and db. The web service represents the web server container, and the db service represents the database container.

Within the web service, we specify the links key, followed by the name of the service it needs to connect to (db in this case). This establishes a network link between the two containers.

By using links, Docker Compose sets up the necessary connectivity between the containers. It ensures that the web server container can access the database container using the service name (db) as the hostname. This means that within the web container, you can refer to the database using the hostname db, and Docker Compose will handle the network configuration behind the scenes.

For example, in your web application's configuration, you can specify the database host as db. The web server container will automatically resolve this hostname to the IP address of the linked database container, enabling seamless communication between the two.

Using links in Docker Compose simplifies the process of connecting containers and eliminates the need to manage complex network configurations manually. It allows services to interact with each other effortlessly, making it easier to build multi-container applications.

It's important to note that while links were a common feature in earlier versions of Docker Compose, they have been deprecated in recent versions. However, understanding the concept of links helps in comprehending the historical context and the evolution of container networking in Docker Compose.

Docker Compose Versions

Docker Compose supports different versions, denoted by the version key in the Docker Compose file. Each version introduces new features and syntax. It's important to specify the appropriate version for compatibility.

The examples above use version 3. The choice of version depends on the Docker Compose features you need and the Docker Engine version you're using. You can find the available versions and their corresponding syntax in the Docker Compose documentation.

Deploying An Application Stack with Docker Compose

Here's an example of using a Docker Compose file (docker-compose.yml) with the 'networks and links' features to deploy an application stack:

version: '3'

services:

  frontend:

    build:

      context: ./frontend

      dockerfile: Dockerfile

    ports:

      - 80:80

    networks:

      - app-network

    depends_on:

      - database


  backend:

    build:

      context: ./backend

      dockerfile: Dockerfile

    networks:

      - app-network

    depends_on:

      - database


  worker:

    build:

      context: ./worker

      dockerfile: Dockerfile

    networks:

      - app-network

    depends_on:

      - frontend

      - backend

    links:

      - database


  database:

    image: mysql:latest

    environment:

      - MYSQL_ROOT_PASSWORD=secret

      - MYSQL_DATABASE=mydb

    networks:

      - app-network


networks:

  app-network:

In this example, we define four services: frontend, backend, worker, and database. We also define a network called app-network to connect the services.

The frontend, backend, and worker services are built using their respective Dockerfiles, and they are all connected to the app-network. The frontend service exposes port 80 to the host machine, allowing access to the front-end application.

The backend service and worker service both depend on the database service. Docker Compose ensures that the database service is started before the other two.

The worker service also uses the links property to establish a connection with the database service. This allows the worker to access the database using the service name (database) as the hostname.

The database service is configured with the necessary environment variables, such as the root password and the name of the database.

By utilizing a single Docker Compose file with networks and links, the application stack can be deployed and the containers can communicate with each other. The front-end, back-end, and worker services can connect to the database service, enabling data interaction and processing between them.

Running The Application Stack

To run the application stack and access the services through a web application:

First, Make sure you have Docker and Docker Compose installed on your machine. You can download and install them from the official Docker website (https://www.docker.com/get-started).

Create a new directory for your project and navigate to that directory in your terminal or command prompt.

Create the necessary directories and files for your application stack. For example:

  • Create a directory called frontend and place your front-end application files inside it.

  • Create a directory called backend and place your back-end application files inside it.

  • Create a directory called worker and place your worker application files inside it.

  • Create Dockerfiles for each of these directories (frontend/Dockerfile, backend/Dockerfile, worker/Dockerfile) to specify how the containers should be built. The contents of these files will depend on the technologies you are using for each component.

Once your application files and Dockerfiles are in place. Run the following command to start the application stack:

docker-compose up -d

This command will start building and launching the containers defined in the docker-compose.yml file in detached mode (in the background). Wait for Docker to download the necessary images, build the containers, and start them. You should see logs and output indicating the progress.

Once the containers are up and running, you can access the services through a web browser.

  • The front-end application should be accessible at http://localhost. Open your web browser and navigate to this address. You should see your front-end application.

Stay patient, we've only just begun our journey. There's still a considerable distance to cover.