Docker Compose
Overview
If you're using Docker extensively, you'll quickly find that managing multiple containers can be a bit of a hassle. Luckily, Docker Compose is a great tool that can help you easily manage multiple containers at once.
What is Docker Compose?
Docker Compose is a powerful tool for orchestrating multiple containers that need to work together. If you're using the microservices model for your app development, Docker Compose can help you factor your app code into several independently running services that communicate with each other using web requests.
The YAML Configuration
A docker-compose YAML file is used to configure the services that make up an application. This file format is both human-readable and machine-optimized and provides an easy way to summarise the configuration of an entire project with just a few lines of code. By specifying the version of the Compose file format, at least one service, and optionally volumes and networks, we can get dozens of configurations applied by Compose under the hood, saving us the hassle of scripting them with Bash or another similar language.
Services
Services in a docker-compose YAML file refer to a container configuration that has multiple settings that can be applied.
For example, in a dockerized web application consisting of a front end, a back end, and a database - the docker-compose file would be split into three different services in the configuration.
Volumes & Networks
Volumes are like physical areas of disk space that are shared between the host and a container or even between containers. In other words, a volume is like a shared directory in the host, visible from some or all containers.
Networks are essential for defining the communication rules between containers and between a container and the host. Without them, containers would not be able to communicate with each other or with the host, making them effectively isolated from one another.
Dissecting a Service
Now let's take a look at the main settings of a service.
Pulling an Image
To specify the image, we add the image name and its tag. We can use an existing image from Docker Hub or another Docker Registry if the image we need for our service has already been published there.
For example
Building an Image
If the image we need for our service has not already been published at any docker registry, we can build it on our own by specifying a path to it.
For example
Additionally, we can use the build attribute to specify an image name, which will be used to name the image when it is built.
For example
Configuring the Networking
Docker containers can communicate with one another on the same network by using container names and ports. If you need to make a port accessible, you can use the expose keyword. This way, a service can communicate with another service on the same network by referencing it by the container name and port.
For example
The ports keyword allows us to expose a container's ports to the host, which makes it possible to reach the container from the host. We can also choose to expose the port differently in the host if we want to.
For example - In the below configuration, port 8080 of the container will be available on port 3000 in the host.
Setting Up the Volumes
There are three types of volumes: anonymous, named, and host.
We can configure host volumes at the service level and name volumes at the outer level of the configuration. By doing this, we make the latter visible to other containers rather than only to the one they belong to.
For example - Here, containers will have read/write access to the my-volume shared folder, regardless of which path they've mapped it to. Instead, the two host volumes will be available only to volumes-example-service.
Declaring the Dependencies
We can create a dependency chain between our services using the depends_on keyword. This way, some services get loaded before (and unloaded after) other ones.
For example
Managing Environment Variables
In docker-compose, we can define static environment variables as well as dynamic variables.
We can set them in the OS before calling the command.
Benefits of Docker Compose
The usage of docker-compose comes with these benefits -
-
With docker-compose, you can run everything on a single piece of hardware, i.e. single host deployments.
-
Quick and easy configuration - Because docker-compose uses YAML scripts, configurations are quick and easy to set up.
-
Docker Compose reduces the time it takes to perform tasks and thereby helps increase productivity.
-
In docker-compose, all the containers are isolated from each other, reducing the threat landscape, i.e. Security is enhanced.
Basic Commands in Docker Compose
Start all Services
Stop all Services
Install Docker Compose using Pip
Check the Version of Docker Compose
Run Docker Compose file
List the Entire Process
Scale a Service
Install Docker Compose
Install Docker Compose on MacOS
For using Docker Compose on macOS, we need to just have Docker Desktop for Mac installed and don't need to install Docker Compose separately.
Install Docker Compose on Linux
To run Docker Compose on Linux; we need to download the Docker Compose binary using Github's Compose repository release page.
Follow the given steps:
Install Docker Compose on Windows
For using Docker Compose on Windows, we need to just have Docker Desktop for Windows installed and don't need to install Docker Compose separately.
Create the Compose file
Follow the below steps to create a docker-compose.yml file -
- Create a file called docker-compose.yml at the root of the directory of the project.
- Proceed by defining & mentioning the version of the schema -
- Run as part of our application, we define the list of containers or services -
Define various services -
- Give a name to your service.
- Provide the image name that your service is going to use.
- Specify the ports to expose on the defined service.
- Mount volumes if required.
For example
Run the Application Stack
To start the application stack, using the docker-compose-up command, we need to start the application stack. To run everything in the background, we need to use the -d flag.
App Stack in Docker Dashboard
The Docker Dashboard has a group called "app." This is the Docker Compose "project name." It is used to organize containers together. By default, the project name is the same as the name of the directory where docker-compose.yml is found.
A Real-World Example: Spring Cloud Data Flow
Small experiments can help us understand the single gears, but seeing the real-world code in action will unveil the big picture. Spring Cloud Data Flow is complex but simple enough to be understandable. So let's download its YAML file and run it by going here
Run it using the
Lifecycle Management
There are many options and commands available, but we need to at least know the ones that activate and deactivate the whole system correctly.
Startup
After the first time of starting the services using docker-compose up, we can simply use start to start the services - docker-compose start
Shutdown
To safely stop the active services, we can use stop, which will preserve containers, volumes, and networks, along with every modification made to them - docker-compose stop
Conclusion
In this article, we learned about Docker Compose and how it can help simplify the process of working with containers. We went over some of the basics, like creating a docker-compose file and managing the lifecycle of containers.
By understanding these concepts, you'll be able to use Docker Compose to work more effectively with containers in your projects.