Docker Compose Tutorial for Beginners

In this tutorial, we will learn about Docker Compose. Docker Compose is a tool that helps us when we work with Docker. If you use Docker to make your software, Docker Compose can make your work easier. Let’s start our learning journey.

To learn more about Docker, please check Docker Tutorials page.

What is Docker Compose?

Docker Compose is your one-stop tool for managing multiple Docker containers. Think of it as a conductor that orchestrates a group of musicians (Docker containers). Docker Compose lets you define and run multi-container Docker applications, making it easier to manage complex applications.

When and why to use Docker Compose?

Picture this: you’re developing an application that needs a web server, a database, and a backend application. Starting each service manually sounds like a chore, doesn’t it? Docker Compose comes to your rescue here. With it, you can start all your services at once. It’s particularly useful for development, testing, staging environments, and continuous integration workflows. All your services can be defined in a YAML file, and with a single command, your whole stack is up and running.

Docker Compose vs Docker CLI

Now, you might be wondering about Docker CLI. Can’t it do the job? Well, yes and no. Docker CLI is great when you’re dealing with one or two containers. However, when you need to manage multiple containers that interact, Docker CLI might give you a hard time. Docker Compose, on the other hand, simplifies managing multiple containers. It’s like the difference between manually dialing each contact in your phone and sending a group text. Docker Compose is all about streamlining and simplifying your Docker experience.

Docker Compose Installation

In this section, we’ll learn how to install Docker Compose on your computer. We’ll cover both MacOS and Windows.

How to install Docker Compose on MacOS?

  1. Install Docker Desktop: Docker Compose comes with Docker Desktop. So, the first step is to download Docker Desktop. You can download it from Docker’s official website.
  2. Check the Installation: After you install Docker Desktop, you can check if Docker Compose is also installed. Open the Terminal application (you can find it in the Utilities folder). In the Terminal, type docker-compose --version and then press the Enter key. If Docker Compose is installed, you’ll see a message with the Docker Compose version number.

How to install Docker Compose on Windows

  1. Install Docker Desktop: Just like on MacOS, Docker Compose comes with Docker Desktop on Windows too. To get Docker Desktop, go to Docker’s official website and download it.
  2. Check the Installation: To check if Docker Compose is installed on your Windows machine, you need to open Command Prompt. You can do this by clicking the Start button, typing ‘Command Prompt’ and then clicking on it. In the Command Prompt, type docker-compose --version and press the Enter key. If Docker Compose is installed, you’ll see a message with the Docker Compose version number.

Remember, Docker Compose is a helper tool for Docker. So, you need to have Docker installed on your computer to use Docker Compose. If you see the version number after typing docker-compose --version, you’re good to go!

Understanding Docker Compose Files

In this section, we’ll dive into Docker Compose files. These files are the core of Docker Compose. They tell Docker Compose what to do.

Docker Compose file structure and syntax (version, services, etc.)

A Docker Compose file is a text file written in YAML format. It usually has the name docker-compose.yml. The file contains instructions for Docker Compose. Here’s a simple example of what it looks like:

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

Let’s break it down:

  • version: This tells Docker Compose which version of the Docker Compose file format to use. In this case, it’s version 3.
  • services: This is where you list the containers you want Docker Compose to manage. In this case, there are two services: “web” and “redis”.
  • build: This tells Docker Compose how to build the Docker image for the “web” service. The dot (.) means Docker should look in the current directory for a file named “Dockerfile”. It will use this file to build the image.
  • ports: This maps ports between the Docker host and the Docker containers. In this case, port 5000 on the host is mapped to port 5000 on the “web” container.
  • image: This tells Docker Compose what Docker image to use for the “redis” service. In this case, it’s using the “redis:alpine” image from Docker Hub.

Docker Compose file versions and differences

Docker Compose files have different versions, like version 1, 2, and 3. The version you use depends on the features you need. Each version has different features and syntax. For example, version 1 does not support networks or volumes, but version 2 and 3 do. Version 3 also added support for deploying services to a Docker swarm. For most uses, version 3 is a good choice because it has the most features.

An overview of the YAML format

YAML stands for “YAML Ain’t Markup Language”. It’s a human-friendly data format. In Docker Compose files, we use YAML to describe our services, networks, and volumes. Here’s a few things to know about YAML:

  • It’s case sensitive: “web” and “Web” would be two different things.
  • Indentation matters: Spaces are used to show the structure in the file. In the example above, build: and ports: are indented to show they belong to the “web” service.
  • Colons (:) are used to map keys to values: In build: ., “build” is the key and “.” is the value.
  • Dashes (-) are used to create lists: In - "5000:5000", the dash shows it’s a list of ports.

That’s the basics of Docker Compose files and YAML. Remember, the most important part of a Docker Compose file is the services: section. This is where you tell Docker Compose what containers to run and how to run them.

Writing Your First Docker Compose File

In this section, we will create a Docker Compose file from scratch. We’ll make a simple web application with two services: a Java web server and a MySQL database.

Here’s what our Docker Compose file will look like:

version: '3'
services:
  app:
    build: ./app
    ports:
     - "8080:8080"
    depends_on:
     - db
  db:
    image: "mysql:8.0"
    environment:
      MYSQL_ROOT_PASSWORD: password

Now, let’s break it down:

  • version: '3': This tells Docker Compose we’re using version 3 of the Docker Compose file format.

Under services:, we define our two services: app and db.

  • app:: This is our Java web application.
    • build: ./app: This tells Docker Compose to look in the app directory for a Dockerfile. It will use this Dockerfile to build the Docker image for our Java application.
    • ports: - "8080:8080": This maps port 8080 of the container to port 8080 of our Docker host. This means our application will be accessible on port 8080.
    • depends_on: - db: This tells Docker Compose that our application depends on the db service. Docker Compose will make sure to start the db service before it starts the app service.
  • db:: This is our MySQL database service.
    • image: "mysql:8.0": This tells Docker Compose to use the mysql:8.0 image from Docker Hub for this service.
    • environment: MYSQL_ROOT_PASSWORD: password: This sets an environment variable in the MySQL container. The MySQL image uses this environment variable to set the root password for MySQL.

That’s it! With this file, Docker Compose can start our Java application and MySQL database with one command: docker-compose up. Docker Compose will take care of building the Docker image for our application, starting the services, and setting up the network connections between them.

Basic Docker Compose Commands

Docker Compose has a set of simple commands that let you manage your application. They’re similar to Docker commands, but they work on your whole application instead of individual containers.

Docker Compose up

The docker-compose up command starts your entire application. Docker Compose will read your docker-compose.yml file, start all the services you defined, and create any networks or volumes that your services need. If Docker needs to build any images (like for our Java application in the previous section), docker-compose up will do that too.

Docker Compose down

When you’re done with your application, you can stop it with docker-compose down. This command stops all the services and removes the networks and volumes Docker Compose created. It’s the opposite of docker-compose up.

Docker Compose ps

To see the status of your services, use docker-compose ps. This command is similar to docker ps, but it only shows the services defined in your docker-compose.yml file.

Docker Compose logs

If you want to see the logs from your services, you can use docker-compose logs. This command is like docker logs, but it shows the logs from all your services. You can also use docker-compose logs <service> to see logs from a specific service.

Differences and similarities with Docker commands

Docker Compose commands are similar to Docker commands, but there are a few differences. Docker commands work on individual containers, while Docker Compose commands work on your entire application. For example, docker start <container> starts a single container, while docker-compose up starts all the services in your application.

Another difference is that Docker Compose commands use the docker-compose.yml file in your current directory. Docker commands don’t use this file. They use the options you provide on the command line.

Despite these differences, Docker Compose commands are very similar to Docker commands. If you’re familiar with Docker, you’ll find Docker Compose easy to use. The main thing to remember is that Docker Compose is about managing your whole application, not just individual containers.

Managing Environment Variables with Docker Compose

Environment variables are key to many applications. They allow you to change the behavior of your application without changing your code. Docker Compose provides two main ways to manage environment variables: .env files and variable substitution in Docker Compose files.

How to use .env files

An .env file is a simple text file where you can define environment variables. Each line in the file is a key-value pair in the format KEY=VALUE. Here’s an example:

DB_USER=root
DB_PASS=password

To use these variables in your Docker Compose file, you can add them under the environment key for a service:

services:
  db:
    image: "mysql:8.0"
    environment:
      MYSQL_USER: ${DB_USER}
      MYSQL_PASSWORD: ${DB_PASS}

When Docker Compose reads your docker-compose.yml file, it also reads the .env file in the same directory. It replaces ${DB_USER} and ${DB_PASS} with the values from the .env file.

Variable substitution in Docker Compose files

Docker Compose also supports variable substitution directly in the docker-compose.yml file. This means you can use environment variables in the values of your Docker Compose file.

For example, let’s say you have an environment variable VERSION set to 3.8 in your shell. You can use this variable in your Docker Compose file like this:

version: '${VERSION}'

When Docker Compose reads this file, it replaces ${VERSION} with 3.8.

You can also use default values in your variable substitutions. If VERSION is not set in your environment, Docker Compose uses the default value:

version: '${VERSION:-3}'

In this case, if VERSION is not set, Docker Compose uses 3.