Skip to content

Docker: Docker Compose

Rayan edited this page Mar 21, 2024 · 6 revisions

Docker Compose

Docker Compose is a tool that allows you to define and manage multi-container Docker applications using a simple YAML file to specify the services, networks, and volumes required for your application's setup.

Definition

Docker Compose is a tool that allows you to define and manage multi-container Docker applications using a simple YAML file to specify the services, networks, and volumes required for your application's setup.

This sentence certainly describes Docker Compose however this describes Docker Compose as a powerful tool that simplifies the management of multi-container Docker applications by allowing you to define, configure, and manage your application's services, networks, and volumes in a single YAML file, known as the docker-compose.yml file. With Docker Compose, you can specify the services your application requires, such as databases, web servers, or other dependencies, along with their configuration options, dependencies, and relationships. Additionally, Docker Compose provides commands to easily build, start, stop, and scale your application and its services, streamlining the development, testing, and deployment process. By abstracting away the complexities of container orchestration, Docker Compose enables developers to focus on building and iterating on their applications efficiently, while also providing consistency and portability across different environments.

YAML

What is YAML?

YAML, which stands for "YAML Ain't Markup Language," is a human-readable data serialization format commonly used for configuration files, data exchange, and structuring data in a way that is easy for both humans and machines to read and write. It is often used in conjunction with tools like Docker Compose, Kubernetes, and Ansible for defining configuration files.

YAML syntax primarily consists of key-value pairs, lists, and nested structures. It uses indentation to define the hierarchy of data. To showcase this, I have written a simple YAML configuration file

database:
  name: my_database
  host: localhost
  port: 3306
  credentials:
    username: user
    password: password
webserver:
  name: my_web_server
  host: localhost
  port: 80

The explanation of the YAML-Config file is the following

  • Keys and Values: YAML uses key-value pairs, where keys are followed by a colon and space, and values are indented below keys. In the example above, database and webserver are keys, and their corresponding values are dictionaries.

  • Indentation: YAML relies on indentation to define structure and hierarchy. Children nodes are indented further than their parent nodes. In the example, the keys name, host, port, and credentials are indented under database and webserver, indicating they are part of these parent structures.

  • Lists: YAML supports lists using hyphens (-). Lists are indicated by a hyphen followed by a space, with each item indented at the same level. However, the example provided does not include lists.

  • Comments: Comments in YAML start with the # symbol and continue until the end of the line. They are used for adding explanatory notes or annotations to the configuration file.

YAML's simplicity and readability make it an ideal choice for configuration files, allowing developers to define complex structures with ease while maintaining clarity and human readability.

Use Case

YAML files serve as versatile configuration files in a variety of use cases, from defining infrastructure configurations in tools like Docker Compose and Kubernetes to specifying settings in software applications. Their human-readable format facilitates easy collaboration and understanding among team members, while their hierarchical structure and support for key-value pairs enable the concise representation of complex data structures, making them ideal for configuring and managing diverse systems and applications. YAML's flexibility, readability, and portability make it a popular choice for defining configurations in a wide range of environments, including DevOps, software development, and system administration.

Example

Below is an example of a Docker Compose YAML file for a simple web application consisting of two services: a web server (using the Nginx image) and a database server (using the MySQL image).

version: '3.8'

services:
  webserver:
    image: nginx:latest
    ports:
      - "80:80"
    volumes:
      - ./html:/usr/share/nginx/html
    depends_on:
      - database

  database:
    image: mysql:latest
    environment:
      MYSQL_ROOT_PASSWORD: example
      MYSQL_DATABASE: my_database
      MYSQL_USER: user
      MYSQL_PASSWORD: password
    volumes:
      - db_data:/var/lib/mysql

volumes:
  db_data:

Explanation:

  • version: Specifies the version of Docker Compose syntax being used. In this case, version 3.8 is used.

  • services: Defines the services that make up your application. Each service represents a container.

    • webserver: Defines the configuration for the web server service.

      • image: Specifies the Docker image to be used for the service (nginx:latest in this case).
      • ports: Maps the host port 80 to the container port 80.
      • volumes: Mounts the ./html directory on the host to /usr/share/nginx/html in the container, allowing you to serve static files.
      • depends_on: Specifies that the webserver service depends on the database service.
    • database: Defines the configuration for the database service.

      • image: Specifies the Docker image to be used for the service (mysql:latest in this case).
      • environment: Sets environment variables required for configuring MySQL.
      • volumes: Mounts the named volume db_data to /var/lib/mysql in the container, ensuring persistent data storage.
  • volumes: Defines named volumes used by the services. In this case, only one named volume db_data is defined, which is used by the database service for persistent data storage.

Basic Setup: Persistent data with docker volumes

Giving a docker container persistent data with docker volumes is best done over another docker related file. Here we will use docker-compose.yaml You can read more to docker-compose here in my Wiki 📄Docker: Docker-Compose

Step 1: Create a Dockerfile for Apache Image

Create a Dockerfile with the following content in your project directory:

FROM httpd:latest

This will use the latest version of Apache HTTP Server available on Docker Hub.

Step 2: Create a Docker Compose File

Create a docker-compose.yml file in the same directory with the following content:

version: '3'

services:
  apache:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - docker-volume-setup-example:/usr/local/apache2/htdocs
    ports:
      - "80:80"

volumes:
  docker-volume-setup-example:
    driver: local

In this Compose file:

  • We define a service named apache using the image built from the Dockerfile we created.
  • We mount the volume docker-volume-setup-example to the Apache container at /usr/local/apache2/htdocs. This is where Apache typically serves files from.
  • Port 80 of the container is exposed to port 80 on the host.
  • We define a named volume docker-volume-setup-example using the local driver.

Step 3: Build and Run the Environment

Open your terminal and navigate to the directory where your docker-compose.yml and Dockerfile are located.

Run the following command to build and run the Docker environment:

docker-compose up -d

This command will build the Apache image using the Dockerfile and start the container based on the configuration in the docker-compose.yml file. The -d flag runs the containers in detached mode, meaning they will run in the background.

Step 4: Test the Setup

You can now access your Apache server in your browser by navigating to http://localhost. Any files you place in the docker-volume-setup-example volume will be served by Apache.

Step 5: Stopping and Removing the Environment

When you're done testing, you can stop and remove the Docker environment using the following command:

docker-compose down

This will stop and remove the containers defined in the docker-compose.yml file, but it will preserve the named volume docker-volume-setup-example, keeping your data intact for future use.