Run multi-container Docker applications with a single command

Photo by Pixabay from Pexels

What is docker?

Docker is a platform to develop, deploy, and run applications inside independent and isolated environments. These environments are then called containers. This will let the developer run a container on any machine.

Simply docker solves the problem of ‘’It works on my machine’’.

As you can see, with Docker, there are no more dependency or compilation problems. All you have to do is launch your container, and your application will launch immediately.

If you want to learn more about this excellent platform, the “Get Started” section of Docker Docs is a great place to start.


Let’s move onto the topic.

If your application is containing more than one component (multiple containers), how do you manage such a situation easily? It means you need to run those multiple containers separately. How do you manage their network connectivity, volume binding, port binding, etc. from a central point?

When using Docker widely, the management of several different containers quickly becomes cumbersome.

Introducing docker-compose

Docker Compose is a tool that helps us overcome this problem and efficiently handle multiple containers at once. Also used to manage several containers at the same time for the same application.

This tool can become very powerful and allow you to deploy applications with complex architectures very quickly.

Docker (individual container) VS Docker-Compose (several containers)

With Compose, you use a Compose file to define and configure your application’s components as services. Then, using a single command, you can create and start all the services according to your configurations.

Compose works in all environments: production, staging, development, testing, as well as CI workflows.

In short, Docker Compose works by applying many rules declared within a single docker-compose.yaml configuration file.

Let’s go step by step.

First of all, you need to install docker-compose in your environment.

Create a docker-compose.yaml file that defines the services (containers) that make up your application. So they can be run together in an isolated environment. In this compose file, we define all the configurations that need to build and run the services as docker containers.

There are several steps to follow to use docker-compose.

1. Split your app into services

The first thing to do is to think about how you’re going to divide the components of your application into different services(containers).

In a simple client-server web application, it could contain three main layers (frontend, backend, and the database). So we can split the app in that way. Likewise, you will have to identify your services of the application, respectively.

2. Pull or build images

For some of your services, you may not need to build from a custom Dockerfile , and a public image on DockerHub will suffice.

For example, if you have a MySQL database in your application, you can pull MySQL image from the hub instead of building it. For others, you will have to create a Dockerfile and build them.

3. Configure environment variables, declare dependencies

Most applications use environment variables for initialization and startup. And also, after we divide the application into services, they have dependencies on each other. So we need to identify those things before we declare the compose file.

4. Configure networking

Docker containers communicate with each other through their internal network that is created by compose (eg service_name:port). If you want to connect from your host machine, you will have to expose the service to a host port.

5. Set up volumes

In most cases, we would not want our database contents to be lost each time the database service is brought down. A simple way to persist our DB data is to mount a volume.

6. Build & Run

Now, you are set to go and create the compose file and build the images for your services and generate containers from those images.

A sample docker-compose.yaml file is shown below with all the configurations discussed before. Get detailed service configuration reference from the docker-compose file reference.

These YAML rules, both human-readable and machine-optimized, provide us an efficient way to snapshot the entire project within a few minutes.

After all those, in the end, we just need to run:

$  docker-compose up [options]

And compose will start and run your entire app. along with the above command, you can use the following options,

-d, --detach      Detached mode: Run containers in the background, print new container names.--no-deps         Don't start linked services.--no-build        Don't build an image, even if it's missing.--build           Build images before starting containers.--no-start        Don't start the services after creating them.--no-recreate     If containers already exist, don't recreate  them.--force-recreate  Recreate containers even if their configuration and image haven't changed.

Other useful commands with compose

Compose has commands for managing the whole lifecycle of your application:

  • $ docker-compose build : build or rebuild services
  • $ docker-compose config : validate and view the Compose file
  • $ docker-compose down : stop and remove containers, networks, images, and volumes
  • $ docker-compose bundle : generate a Docker bundle from the compose file
  • $ docker-compose logs <service_name> : stream the log output of running services
  • $ docker-compose exec <service_name> <command> : execute a command in a running container
  • $ docker-compose run <service_name> <command> : run a one-off command
  • $ docker-compose stop <service_name(s)> : stop running containers without removing them
  • $ docker-compose start <service_name(s)> : start existing containers for a service.
  • $ docker-compose pull/ push <service_name(s)> : pull/ push service images
  • $ docker-compose kill <service_name(s)> : kill containers
  • $ docker-compose rm <service_name(s)> : remove stopped containers
  • $ docker-compose ps : list containers
  • $ docker-compose images : list images
Photo by Andrew Neel on Unsplash

So in this article, you’ve learned about docker-compose and how it works.

With this tool, any developer will be able to run these services without even cloning the repositories. They would just need Docker installed on their machine. The “build once, run wherever” nature of Docker & compose will be beneficial for development and testing.

Thanks for reading! Let’s take a break and have a cup of tea. ;-) See you the next time.


Osanda Deemantha Hemachandra

Written by

Software Engineering Intern @ Virtusa | Undergraduate | Computer Science and Engineering | University Of Moratuwa | Sri Lanka

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade