Docker Compose: Creating Multi-Container Applications


Simply deploying apps to Docker is not an architectural shift that will bring the agility, isolation and DevOps automated capabilities that a microservices approach can offer. You can always deploy a monolithic application into a Docker container.

The microservice architecture is an approach to decompose a single app as a suite of small independently deployable services communicating with each other.

There should be a bare minimum of centralized management of these services.

What is Docker Compose?

Docker Compose is an orchestration tool that makes spinning up multi-container applications effortless.

With Compose, you define a multi-container application in a single file, then spin your application up in a single command that takes care of everything to get it running.


While Compose is not yet considered production-ready, it is great for dev environments, staging, learning and experimenting.

Installing Docker Compose

Once we have the VM running with Docker (Check out the ways to create the Docker VM in Azure), you can proceed to install Docker Compose by following these steps:

  • Connect to the VM through SSH; for example running Putty and connect to the VM specifying the host name and port:

Docker Compose_1-Putty


Do not forget to create an endpoint to allow SSH connections (You can choose any port other than the default: port=22)

  • After logging into the VM (you’ll be prompted for the credentials provided during the VM creation), download and install Docker Compose using the commands shown below:
curl -L`uname -s`-`uname -m` > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

However, if the /usr/local/bin directory isn’t writable for the user that is logged in, a “Permission Denied” error could appear.

Docker Compose_3-Permission Denied

In order to resolve this, you should run “sudo -i” to run the commands as a superuser.

Docker Compose_4-sudo

Once you have finished running both commands, run “exit” to exit the superuser mode.


  • Finally, to check if Compose was installed correctly, run:
docker-compose --version


The Docker Compose version should be displayed in the console.

Docker Compose_5-version


Overview of Docker Compose

Once Docker Compose is installed in your Docker VM, you can start using Compose to run multi-component applications. You’ll find a nice sample in the Docker documentation Overview of Docker Compose which includes steps to build a simple two-container app.


Validation and troubleshooting

The first step is to connect to the VM through SSH using an SSH client such as Putty. Once you are connected to the VM and have entered your credentials, you need to set the DOCKER_HOST variable as follows:

export DOCKER_HOST="tcp://localhost:2376"

Now, before starting to work with Docker Compose, it would be a good idea to check if we have everything in place to work with Docker. A good test would be to run the following command:

docker --tls ps.

This command should list the Docker containers that are running on the host. If this command does not throw any errors, you are good to go. In our case, we experienced some issues at this point.

Depending on how you created the Virtual Machine you may have some certificate issues. In our case, we created the Virtual Machine in Azure directly from Visual Studio 2015 RC by deploying a .NET 5 application, and when we ran the previous command we got a certificate issue.

Docker Compose_6-bad certificate


In order to fix this issue, we copied the certificates files that Visual Studio generated in our dev environment to the VM. By default, Docker expects to find the certificates in a folder called “.docker” located in the home directory. However, if you want the certificates in a different folder, you can use the DOCKER_CERT_PATH variable. So, after we copied the certificates, we ran the following command:

export DOCKER_CERT_PATH=~/<path-to-certificates>

After running this command, we were able to successfully run the “docker –tls ps” command.


Testing sample

To make things ever simpler we uploaded the resulting sample files in the following public GitHub repository:


The files in the repo include:

    The simple python application described in the sample. It just displays the amount of times the site has been accessed:
from flask import Flask
from redis import Redis
import os
app = Flask(__name__)
redis = Redis(host='redis', port=6379)

def hello():
    return 'Hello World! I have been seen %s times.' % redis.get('hits')
if __name__ == "__main__":"", debug=True)
  • requirements.txt:
    Indicates the requirements to run the application (flask and redis)
  • Dockerfile:
    Specifies how to build the app image.
FROM python:2.7
ADD . /code
RUN pip install -r requirements.txt
CMD python
  • docker-compose.yml:
    Defines the set of services required to run the multi-container application. In this case, the required services are the web app and Redis.
  build: .
   - "5000:5000"
   - .:/code
   - redis
  image: redis

Simply clone the repo in you Docker Linux VM typing:

git clone

Docker Compose_7-clone

After cloning the repository, it would be a good idea to check if the application can be successfully built. This can be achieved by running the following command:

docker build -t web .

If the previous command runs successfully, you should be able to start the web site and the redis service by simply running the following command:

docker-compose up -d


In our environment (Azure VM created from Visual Studio) we received an error when we ran this command.

Docker Compose_8-compose up error


Fortunately, this error can be fixed by setting the DOCKER_TLS_VERIFY variable value as follows:


After running the previous command, we were able to run the “docker-compose up -d” command without errors.


Once the previous command finishes executing, you can check the existing containers by running:
docker-compose ps

Docker Compose_9-compose ps

Finally, in order to have the multi-container application publicly accessible, you may need to set the proper endpoints. In our case, the VM is running in Azure, so we used the Azure CLI to map a port to the private web app container port (in this case 5000). So, in the command line you should run:

azure vm endpoint create <machine-name> <public-port> <container-private-app>

In order to run the previous command, you would need be have the Azure credentials in place.

After setting the endpoint, you should be able to access the web application through the public port.

Further reading


Leave a Reply