How To Run an Angular App As a Container On Azure VM
There is a number of ways you can run your applications nowadays. It’s very common to containerize your application and run it on Docker runtime. You have several options in Microsoft Azure such as App Service, AKS, etc. But, you have limited control over the underlying architecture when you use these options. If you want complete control over the underlying architecture you can install Docker on Azure VM and run your application on it.
In this post, we will see how we can install Docker on Azure VM and run an Angular application as a container on it.
- Example Project
- Set up a VM and Install Docker
- Run the Container
- Access From the Browser
There are some prerequisites for this article. You need to have nodejs installed on your laptop and how http works. If you want to practice and run this on your laptop you need to have these on your laptop.
You should have a Microsoft Azure Account. You can get a free account for one year. You should see the below screen after you login.
You need to create a subscription for your account. The most common is Pay As You Go subscription.
You need a subscription to be associated with your tenant so that all the cost is billed to this subscription.
Install Azure CLI and Configure
Once you have the Azure Account you can install Azure CLI. You can go to the below documentation and install Azure CLI based on your operation system. You can configure Azure CLI with your subscription.
Let’s list the subscription with the following command
az account list --output table
Let’s see what we are running as an example project here. This is a simple project which demonstrates developing and running an Angular application with NodeJS. We have a simple app in which we can add users, count, and display them at the side, and retrieve them whenever you want.
// clone the project
git clone https://github.com/bbachi/angular-nodejs-minikube.git// Run NodeJS server on port 3080
npm start// Run Angular code on port 4200
Run it On Docker
We use the multi-stage builds for efficient docker images. Building efficient Docker images are very important for faster downloads and lesser surface attacks. In this multi-stage build, building an Angular project and put those static assets in the dist folder is the first step. The second step involves taking those static build files and serve those with the node server.
Let’s build an image with the Dockerfile. Here are the things we need for building an image.
- Start from the base image
- There are two package.json files: one is for the nodejs server and another is for Angular UI. We need to copy these into the Docker file system and install all the dependencies.
- We need this step first to build images faster in case there is a change in the source later. We don’t want to repeat installing dependencies every time we change any source files.
- Copy all the source files.
- Angular uses Angular/CLI to build the app. So, install CLI and install all the dependencies.
npm run buildto build the Angular App and all the assets will be created under
dista folder within a my-app folder.
- Start from the base image
- Take the build from stage 1 and copy all the files into ./my-app/dist folder.
- Copy the nodejs package.json
- Install all the dependencies
- Finally, copy the server.js
- Have this command
node server.jswith the CMD. This automatically runs when we run the image.
Here is the complete Dockerfile
Let’s build the image with the following command.
// build the image
docker build -t angular-node-image .// check the images
Once the Docker image is built. You can run the image with the following command.
// run the image
docker run -d -p 3080:3080 --name ang-node-ui angular-node-image// check the container
Once you run the container you can the application on port 3080.
Publishing the Docker Image
Let’s publish the Docker image to Docker Hub with this command
docker push <repo name> . Before that, you need to create a Docker Hub account if you don’t have one. Here is the link for it.
Let’s create a repository and it’s bbachin1 in my case. We need to login, tag the image, and push it finally.
docker login// tag the image
docker tag angular-node-image bbachin1/angular-node-webapp// push the image
docker push bbachin1/angular-node-webapp
Set up a VM and Install Docker
There is a number of ways to set up a VM on Azure. We will see how to set up a VM with Azure CLI. Make sure you have set the correct subscription you want to use with the following command.
az account set --subscription <subscription id>
In Azure, whatever resource you create that should be placed in the resource group. So, let’s create a resource group
az group create --name vm-demo --location eastus
You can verify in the portal whether the resource group is created or not.
Let’s create a VM with the following command. The image I selected here is ubuntuLTS.
az vm create \
--resource-group vm-demo \
--name dockerVM \
--image UbuntuLTS \
--admin-username azureuser \
Note your own
publicIpAddress in the output from your VM. This address is used to access the VM in the next steps. In this case, the public IPAddress is
184.108.40.206.You can check the VM created in the portal.
By default, only SSH connections are opened when you create a Linux VM in Azure. Use az vm open-port to open TCP port 80 for the web traffic.
az vm open-port --port 80 --resource-group vm-demo --name dockerVM
Let’s ssh into VM and install Docker on it with the following commands.
ssh email@example.com// install docker
sudo apt-get -y update// remove any old versions of Docker
sudo apt-get remove docker docker-engine docker.io// Install Docker
sudo apt install docker.io// Start the Docker
sudo systemctl start docker// Enable Docker so that Docker runs on startup
sudo systemctl enable docker// check the version
Run the Container
We set up a VM and install Docker on it. It’s time to pull the Docker Image that we published in the earlier section with the following command. You need to set the permission so that you can pull the image without getting permission denied error.
// set the permission
sudo chmod 666 /var/run/docker.sock// pull the image
docker pull bbachin1/angular-node-webapp
Run the following command to run the container.
docker run -d -p 80:3080 --name ang-node-ui bbachin1/angular-node-webapp
Access From the Browser
We know the public IP address of the VM we have created which is 220.127.116.11 and the container is running on port 3080 and is mapped to outside port 80. You can access the app from the following location.
- There is a number of ways you can run your applications nowadays. It’s very common to containerize your application and run it on Docker runtime.
- If you want complete control over the underlying architecture you can install Docker on Azure VM and run your application on it.
- You need to create a resource group before you create a VM.
- You can create a VM with any one of the images such as Windows, Centos, or Ubuntu, etc.
- You can specify the Docker image either from the container registry or Docker Hub.
- All the external traffic is denied by default.
- You have to open a port so that you can access the app from the browser.
- You need to set the permission on docker.sock so that you can pull the image without getting permission denied error.
- You can access the application with external IP provided by VM instances and the port that the application listens.
This is one way of deploying your containerized Angular application on Azure. But, this method has some limitations such as you have to run a single Docker container per instance you can’t scale up based on the demand. You have to use VM scale sets that let you operate apps on multiple identical VMs. You can make your workloads scalable and highly available by LoadBalancer in front of VMs. In future posts, we will see how we can deploy Angular apps on App Service, Azure AKS, Azure container instances, etc.