Sunday, August 23, 2020

Deploy multi-container application using Docker Compose

 

Hi Everyone, in this blog we will see how to deploy the multi-container applications using Docker Compose. 

Docker Compose is a tool for running multi-container docker applications. Usually, one container is used to host one service. Let's take a case where have a massive application where you have multiple services, in that case, we would need several containers for each service and containers will need to interact with each other. Creating it manually using the docker run command will be complicated.


With Docker Compose, just one command can create all the services. It allows you to manage images, containers, volumes, and networks from one configuration file called docker-compose.yml. It can also start and stop all services with one single command.

In my example, I have created a very simple .net API microservice that creates data and fetches data from a SQL server. Since my application talks to the database, I would need 2 containers, one for service and other for SQL database as below:


We will do this with Docker Compose, which is so easy with just one command.


Pre-requisites:

1. Any sample application ready with Dockerfile. You can use your own application or clone my         application from:

    https://github.com/Pujago/studentregistration

2. Docker for desktop (Windows or Mac)
    Link to install: https://www.docker.com/products/docker-desktop 
3. Install Docker Compose
    Installation link: https://docs.docker.com/compose/install/
    Run this command below to check:

   

5. VS Code editor.

    Link to install Visual Studio: https://visualstudio.microsoft.com/downloads/

6. AWS/ Azure account free to deploy the application in AWS EC2 or Azure VM. I used the AWS EC2.

7. Your own free Github account to push your code https://github.com/

8. Familiarity with Dockers and containerizing an application. Please see my previous blog: 

    https://www.leogether.com/2020/08/containerizing-net-microservice.html

9. Optional SQL Server tools. 


Creating a docker-compose file

We will create docker-compose.yml file to create the 2 containers, one for microservice, and another for the database.

If you have cloned my application from https://github.com/Pujago/studentregistration, it is .net web API 3.1 with GET and POST method and using Students database which has just one table and one column:


Open your application in VS Code. Go to View -> CommandPallete, type docker compose and select "Add Docker Compose Files to Workspace.." option as below:

This will create a docker-compose.yml file template as below:

The basic instruction of docker-compose.yml file have 4 options:

version: 

services:

volumes:

networks:

version and service option is mandatory and volumes and networks is optional.

I updated the file as below:

A brief explanation of the docker-compose file:

Services option:
This is used to define services, I have 2 services: studentregistration for microservice and sql-server for database.
studentregistration - This is the name of the service defined for the API and has details as below:
image - it is the name of the docker image that will be created using Dockerfile.
container_name - the name of the container.
build - the context of the Dockerfile (the current directory where your Dockerfile is located).
depends_on - it means this image is dependant on the database and the database container should be created before creating this.
ports - port 8080 of the host should be mapped to port 80 of the container.
networks: This will join the container to network defined in the "networks" options which is "studentregistration-network".

sql-server - This is the name of the service defined for the database and has details as below:
container_name - the name of the container.
image - this image is an official docker image taken from:
And under "how to use the image" section, the image and environment variables are defined:


environment - Under configuration section defines the variables that need to be used with this official docker image:


volumes: This tag will create normal volume "sql-data" which is defined in volumes option.
networks: This will join the container to the network defined in "networks" options which is "studentregistration-network".

networks option:
networks: This creates a network name "studentregistration-network"

volumes option:
volumes: This option creates the volume "sql-data"

 
So now, docker-compose.yml is ready.

Before moving forward, I will clear all images and containers from my host as below:



Few Docker Compose commands to remember:


docker-compose build:
This command only builds the images but does not start the containers. This command will read your docker-compose.yml file, look for all services containing build: statement, and run a docker build for each one. 

docker-compose up -d:
This command builds the images if images "do not exist" and start the containers. 
-d option starts the containers in detached mode.

docker-compose up --build
With --build option, it is forced to build the images even when not needed.

docker-compose up --no-build
With --no-build option, the image build process is skipped, if images are not built already, it fails.



Now, let's run the command: docker-compose up -d
Notice that it will first build SQL server image as there is "depends_on:" statement in "studentregistration" service defined.




Now run the command docker images, you will see new image for SQL will be added as well:

And run the command docker ps to see the containers up and running:


Test you service on port 8080 that maps to port 80 of the container:

Calling Get endpoint: 


Calling POST endpoint:

So we have our application and database containers ready in our localhost. We should be able to deploy these into any machine and it should work. To test this we will use AWS ECS. Please note we would need Docker, Docker Compose and Git to be installed on EC2.

Also, first, create a Github repository and push your code to the repository. 



Deploy the application in AWS EC2


1. Now, launch an EC2 instance, I used AMI of Linux 2 t2.large as database container needs at least 2 GB memory.

2. Install Docker, Docker Compose and Git. 
    I used these commands:
    Installing Docker:
    sudo yum update -y
    sudo amazon-linux-extras install docker
    sudo service docker start

    Installing Docker Compose: 

    Git:
    yum install git -y

3. Pull the repository from GitHub.

    

4. Go into the repo directory and run docker-compose up -d command.

    

5. Once completed, run command docker ps. You will see 2 containers:

    

8. Now test service using postman.

    Get endpoint:
    
    Post Endpoint:

    

Optionally, if you like to check if your database exists in the container, run the command below to ssh into the container:

docker exec -it <container-name/id> bash


Go to /var/opt/mssql/data and you will see Students database created.


Clean-up:

Do not forget to terminate EC2 instance. 

Hope my blog is useful. Please leave your comments. 



1 comment: