Building to Deploying and Running Docker Container in Cloud

Let’s start with docker. Docker is an OS-level virtualization platform used to deliver software in an isolated environment called containers. This means your application runs on the Docker Engine, which furthermore runs on the OS you are using. Docker architecture can be clearer with the image below.

Note: This blog does not contain Docker installation, refer https://docs.docker.com/get-docker/ for installation. We will be talking about basis of Docker, creating Docker images, deploying it to Azure Container Registry and run the container in Azure Container Instances.

To get started with containers, we need to have an application of course as we are keeping applications in a container. I have a simple node.js application using express framework. It simply returns “Welcome to Docker express.”

const express = require('express');
const app = express();
const port = 3000;
app.get('/',(req,res)=>{
    res.send("Welcome to Docker Express");
}) 
app.listen(port,()=> console.log(`Server running at port ${port}`));

Let’s create a Dockerfile which stores all the configurations for our application.

FROM node:alpine 
RUN mkdir /nodeapp
WORKDIR /nodeapp
COPY ./* /nodeapp/ 
RUN npm install
EXPOSE 3000
CMD ["node","index.js"]

It says to pull the ‘node’ image. Then create /nodeapp folder and set the present working directory of our container to /nodeapp. Now, copy the contents from present working directory of our local machine to /nodeapp/ of our container. Of course, we do not want to copy the dependencies container in our node_modules folder. So create a .dockerignore file to ignore, like the gitignore file used in git. Then run npm install command to install all the dependencies of our application. And finally, expose port 3000 which is used by our application and run the application.

Now lets build our Docker image. To build the image, run docker build -t express-demo:v1 . This tells docker to build an image with tag express-demo:v1, from the Dockerfile in the current directory. Providing a tag is just giving a name to our image and v1 is to tell the version.

To see the list of images, just run docker image ls

Now, we need to run our container. To run the container, run docker run -d -p 80:3000 express-demo:v1.

This tells us to run express-demo:v1 container, the one we just created, map the port 80 of our local machine to port 3000 of the container, and to run in detached mode. Now every request sent to our localhost:80 port will go to 3000 port of our container. To verify this, open the browser and go to localhost. I am using curl for this.

Now, we have created and run our image in our machine. But to make our container accessible globally, we need to deploy it somewhere. So, we are using Azure Container Registry. You can use any of the container registries like Docker Hub, GitLab container registry, AWS Elastic Container Service, Google Cloud Container Registry, or anyone.

Let’s head to portal.azure.com, and search for Container Registry in Marketplace or SearchBox. Select create container registry . Create a new resource group and select Registry name. As the Registry name is globally unique, we need to verify the name. Select the location of your preference. I have chosen Southeast Asia as it is the nearest Azure Data Center. Choose SKU and create the Container Registry.

Now, after the deployment is complete, go to the resource. Here you will find options for the Container Registry. Navigate to Access Keys and turn on the admin user. Then we will get a username and password to log in. There are various other methods to authenticate, which we can refer to https://docs.microsoft.com/en-us/azure/container-registry/container-registry-authentication#authentication-options, but for now we are using the Admin user.

To login, we will need either az cli or docker login. We are using docker login for this as we do not need to install azcli.

Now as we have our docker image ready and have logged in to Container Registry, we need to push our image to the Container Registry. But before that, we need to give a proper name to our image according to our Registry. To achieve this, we will tag our express-demo:v1 container with a new name expressdemo.azurecr.io/express-demo:v1 Run docker image tag express-demo:v1 expressdemo.azurecr.io/express-demo:v1To verify our name, list the images with docker image ls | grep express

Now we need to push our image. Run docker push expressdemo.azurecr.io/express-demo:v1

Now we have our container in a Container Registry. To run this container, we can pull this image and run on local storage or use cloud services like Amazon ECS container instance, Azure Container Instances, or any other service. We will be looking into Azure Container Instances.

Search for Container Instance in the Search bar or Marketplace in Azure Portal. Give Container name and choose the region best for you. In the Image source choose Azure Container Registry. If you had your Container in another container registry, then choose Docker Hub or other registry. Then moving on, Choose Registry name, Image name and Image tag of your container, which we deployed earlier. Choose the size according to our needs. I am using 1 Core CPU with 1.5GiB memory.

Move to the Networking section and choose port 3000. Port mapping is currently not available and is in backlog, meaning we will get the feature soon. To achieve this, you can change the port of the node app from 3000 to 80 and start by creating Docker image. You can also use a load balancer to map the ports, and this also increases the cost. Apart from the port, we can also choose an FQDN (Fully Qualified Domain Name) provided by Azure.

Now, review and create the Container Instance. After Deployment is complete, you can see a Public IP and FQDN(if you setup earlier). Copy the IP and goto <IP>:3000. If you have FQDN, you can use <FQDN>:3000

And finally, we have deployed our locally created container to a Container Registry and Run it in Container instance. For more info you can visit these links.

Feel free to drop any queries, feedbacks, and suggestions. I would love to hear. And the code of the demo is available here: https://github.com/anwesh-b/Docker-workshop/tree/master/nodejs