Deployment of multiple Containers in Azure as Container Instance using Docker Compose

azure cloud docker docker-compose multi-container-app aci azurecontainerinstances linux devops

The intention of this post is to explain how deploy multiple Containers in Azure as Container Instance using Docker Compose

cover

1. Introduction

Docker Compose is a tool for running multiple containers by using a dedicated YAML file. This file refers to the container images, which should be used for the deployment. But how can this approach be used for deployments in Azure? Which Azure service will be used for deploying and hosting your containers?

This post explains the necessary steps, if you would like to run your containers in Azure, based on an already existing Docker Compose example. For that approach, the Azure Container Instances service will be used for the deployment.

Therefore, this blog post contains a dedicated chapter, which is about a explaining a Docker Compose example for running multiple containers on a local machine and a dedicated chapter about the deployment for applying Docker Compose in Azure.

2. Containers used for the Deployment in Detail

This section is about explaining the containers, which will be used for the deployment using Docker Compose. I’m going to use two Linux Container, which just print “Hello, I’m your first Linux Container!”, respectively “Hello, I’m your second Linux Container!” at runtime.

The Dockerfile can be seen below:

FROM ubuntu:21.10

ADD "scripts" "/scripts"

RUN apt-get update 

ENTRYPOINT "/scripts/start.sh"

The script “start.sh” contains following lines of code:

#!/bin/sh
echo "Hi, I'm your first Linux Container!"

sleep 5m

exit

Respectively, the second Container prints of course “Hi, I’m your second Linux Container!”.

I’m going to build both ones, by starting a Windows PowerShell, switching to the location of the Dockerfile and using the corresponding docker build command:

docker build -t first-linux-container . 

and

docker build -t second-linux-container . 

After getting the final container images, let’s try to run both container:

This will run the first container…

docker run -it first-linux-container 
04_Docker-Run-Cmd-Local-First-Linux-Container

…and applying the docker run command for the second container image will run the second:

docker run -it second-linux-container 
04_Docker-Run-Cmd-Local-Second-Linux-Container

Conducting docker ps will list both running instances -in that case “first-linux-container” and “second-linux-container”:

docker ps
05_Docker-PS-List-All-Container

So, I’m just used the corresponding docker commands for building and running the containers sequentially. Both containers terminate after 5 minutes.

In contrast to that, using Docker Compose will lead to a fast deployment of both containers, instead of applying the docker run command for each container.

This example is provided at GitHub:

github.com/patkoch - docker-compose-azure example

3. Run multiple Containers using Docker Compose on your local machine

This section is about deploying “first-linux-container” and “second-linux-container” using one specific command (docker compose up) and the mandatory YAML file.

3.1 Prerequisites for the Deployment

Before that, ensure that Docker Compose is available for you. If “Docker Desktop” is already installed, than you are ready to go.

Applying the docker build commands results to two container images, which can be listed after applying the docker images command:

docker images

Ensure, that the “default” context is set by, applying:

docker context ls
01_Ensure-Default-Context-Set

If that’s not the case, then you can set the context to “default” by using the command below:

docker context use default

3.2 The Docker Compose YAML File

Before conducting the proper docker compose command, I need to create the dedicated YAML file, named “docker-compose.yml”, in which both container images are refered:

version: "3.9"
services:
  first-linux-container:
    image: first-linux-container
  second-linux-container:
    image: second-linux-container

Save the file as “docker-compose.yml” in directory of your choice. After that, the docker compose up command can be applied.

3.3 Applying Docker Compose Up for deploying the Containers on your local machine

Start e.g.: a Windows PowerShell, change the directory to the location of the “docker-compose.yml” file and apply following command:

docker compose up

This leads to the deployment of “first-linux-container” and “second-linux-container”:

08_Docker-Compose-Up-Cmd

Applying docker ps, confirms two running instances. So, applying docker compose up, leads to the running instances, defined in your “docker-compose.yml” file:

09_Docker-Compose-Up-Cmd-Docker-PS

Attaching “first-linux-container” enables you to enter the file system and to launch the script “start.sh” in a manual way:

10_Docker-Exec-First-Linux-Container

Deploying both container is quite easy using docker compose. In addition, it is also easy to terminate the containers.

3.4 Applying Docker Compose Down for terminating the Containers on your local machine

Shutting down all instances can be done by using the docker compose down command:

docker compose down
11_Docker-Compose-Down

This will terminate all running container.

That’s the approach of docker compose with regard to run the containers on my local machine.

References

https://docs.docker.com - Overview of Docker Compose

https://docs.docker.com - Install Docker Compose

4. Run multiple Containers in Azure as Container Instance using Docker Compose

In contrast to deploying and running multiple containers on your local machine using docker compose, I’d like to conduct the deployment in Azure. For that, some additional prerequisites are necessary:

4.1 Login to Azure and Push the Container Images to an Azure Container Registry

I’ll start with the login to my Azure subscription using:

az login

After that, I’ll take care of getting the container images pushed to an Azure Container Registry. Either create a new Azure Container Registry or use an existing one. I’ll use an already existing Azure Container Registry, which I’ve used for previous examples. It is named “patricksregistry”.

The container images have to fit for the Azure Container Registry, therefore I’ll tag them properly:

docker tag 5a4ab6b1f86d patricksregistry.azurecr.io/containergroup:first-linux-container

respectively:

docker tag bf4bb14847a6 patricksregistry.azurecr.io/containergroup:second-linux-container

Before pushing them, I need to login to the ACR using:

az acr login --name patricksregistry

After applying that command, “Login succeeded” should be returned:

03_az-acr-login-patricksregistry

Finally, they are ready to be pushed:

docker push patricksregistry.azurecr.io/containergroup:first-linux-container
docker push patricksregistry.azurecr.io/containergroup:second-linux-container

I’ll switch to the Azure Portal and prove that the images are available:

02_Azure-Portal-Container-Registry

4.2 Creating a new Docker Compose YAML File

I’m going to create a new “docker-compose.yml” file, which I save in a different directory. In contrast to the previous file, the container images in line 4 and line 6 refer now to the ones stored at “patricksregistry”:

06_Docker-Compose-YAML-Azure-CR

The new source of “docker-compose.yml” is quite similar, I’ve just changed the images:

version: "3.9"
services:
  first-linux-container:
    image: patricksregistry.azurecr.io/containergroup:first-linux-container
  second-linux-container:
    image: patricksregistry.azurecr.io/containergroup:second-linux-container

4.3 Creating an ACI Context

This is now the last step before applying the final docker compose command. As I’d like to deploy the containers in Azure, I need to set a new context - in that case an “aci” context. I’m going to name it “patricksacicontext” by applying following command:

docker context create aci patricksacicontext

If there are several subscriptions available, you’ve to choose with the arrows at which subscription the new context should be applied. Just press enter to confirm it:

07_Docker-Create-ACI-Context

After that, you can decide whether you’d like to use an already existing resource group or if you’d like to create a new one.

08_Docker-Create-ACI-Context-Create-New

I select the option to create a new one:

09_Docker-Create-ACI-Context-Created

Finally, I’ve to switch to the newly created context by conducting:

docker context use patricksacicontext

As a result, the name of the context will be returned.

10_Docker-Use-Context

Now, everything is set up for the most interesting part: the deployment using docker compose.

4.4 Applying Docker Compose Up for deploying the Containers as Azure Container Instance

Finally, I’d like to see a running state of “first-linux-container” and “second-linux-container” in Azure. After conducting the docker compose up command, I’ll recognize a new instance of Azure Container Instances in the Azure Portal.

As a last step, I’ll ensure that I’m in the containing directory of the “docker-compose.yml” file and after that I’ll conduct:

docker compose up

After that, all containers defined in the “docker-compose.yml” with their corresponding images, will get in a running state:

12_Docker-Compose-Up

Switch to the Azure Portal and prove, that the new Container instances was created - in my case the instance is named “docker-compose-azure”:

13_Azure-Portal-ACI-Instance-Created.png

After selecting that item, I’ll choose “Containers” for verifying that “first-linux-container” and “second-linux-container” are running:

14_Azure-Portal-ACI-Instance-Overview

In addition, I’ll also verify the logs of the running container by selecting “Logs”

15_Azure-Portal-ACI-Logs

Clicking at “Connect” attaches to the container and it is possible to e.g.: start the the script “/scripts/start.sh” in a manual way…

17_Azure-Portal-Exec-First-Linux-Container

…which is equivalent by attaching the container using the dedicated docker exec command:

16_Docker-Exec-First-Linux-Container

Deploying multiple containers in Azure works also great, by applying docker compose up.

4.5 Applying Docker Compose Down for deleting the Azure Container Instance

Terminating all containers, respectively deleting the Container Instance can be done by conducting:

docker compose down
18_Docker-Compose-Down

Switching to the Azure Portal proves, that this resource does not exist any more:

19_Azure-Portal-Resource-Not-Found

5. Conclusion

Docker Compose is a good choice, if you’d like to run multiple containers - which are defined in the dedicated YAML file. Conducting docker compose up, respectively docker compose down will start and terminate your containers.

Microsoft offers an easy way of applying the docker compose approach in Azure: As explained in this post, I’ve just pushed the container images at an Azure Container Registry and created a specific (aci) context. Conducting docker compose up combined by setting the ACI context before, results to a new Azure Container Instance, which includes the containers. It is a fast and easy way of deploying containers in the cloud.

References

github.com/patkoch - docker-compose-azure example

docs.microsoft.com - tutorial-docker-compose

docs.docker.com - Compose

docs.docker.com - Install Docker Compose

kubernetes.io - pods

azure.microsoft.com - Azure Container Instances