Optimize NodeJS Applications Build Using Docker
Tags: docker, node
Published: 2019-11-18 10:08:08

Azure DevOps has really great set of features when it comes to manage project from iterations, continuous integration, continuous delivery etc. With a small change in the code the whole CI/CD pipeline gets trigger and based on the architecture and size of nodejs based application it takes time, for instance Angular application continuous integration takes couple of minutes as it downloads and verify all the npm packages.

In order to reduce this build/continuous integration time, keep packages version and integrity intact Docker comes into action.

We need to create a docker image based on Node 9.1.0-alpine. This is very light weight image. We need to install all the required npm packages on it and save it in custom docker registry. I prefer Azure custom registry but you can use any private registry. This image will now have all the locked required dependencies so every time we perform code check in continuous integration instead downloading all the npm package will download the image which is fairly very small. Now we can also share the same image among the team and for different components development, that will help the code integrity as everyone has same dependencies and we are not flooding the machine with npm packages for every component.

I am using this build process for Angular Applications, Save [Docker file](https://medium.com/r/?url=https%3A%2F%2Fraw.githubusercontent.com%2Ftalha0113%2FBlogs%2Fmaster%2FOptimizeNodeJSApplicationsBuildUsingDocker%2FBase%2FDockerfile) and [package.json](https://medium.com/r/?url=https%3A%2F%2Fraw.githubusercontent.com%2Ftalha0113%2FBlogs%2Fmaster%2FOptimizeNodeJSApplicationsBuildUsingDocker%2FBase%2Fpackage.json) file in a folder reserved for building base image. execute following command in PowerShell as I am using windows machine.

```bash
docker login "<Docker RegistryUrl>" –username "<User Name>" –password "<Password>"
docker build –tag angular:5.0.1 ./
docker tag angular:5.0.1 <Docker RegistryUrl>/angular:5.0.1
docker push angular:5.0.1 <Docker RegistryUrl>/angular:5.0.1
docker logout "samples.azurecr.io"
```
Replace <Docker RegistryUrl> with Private registry or azure registry like for azure "registryname.azurecr.io".

Create a new directory for angular application. root of the directory must contain package.json, docker file, Source folder(contains all the source code for Angular application), dist folder and Configuration folder(contains webpack and karma configurations). In the docker file replace <registry name> with the private registry name you have.

```bash
docker login "<Docker RegistryUrl>" –username "<User Name>" –password "<Password>"
docker build –tag angular-client-azure ./
docker run –rm –detach –name angular-client-azure-container 
–volume ${pwd}/Source:/app/Source 
–volume ${pwd}/Dist:/app/Dist –volume ${pwd}/Reports:/app/Reports 
-p 4321:4321 -i angular-client-azure
(Volume defines mapping between host and container 
in order to get data from container vice-versa. As we will 
need test reports and dist files)
docker exec angular-client-azure-container npm test
docker exec angular-client-azure-container npm run build
docker exec angular-client-azure-container npm start (Optional)
(Once your work is finished with the component you can stop 
and remove the container along with the images)
docker stop angular-client-azure-container
docker rmi angular-client-azure
docker rmi <Registry Name>.azurecr.io/angular:5.0.1
docker logout "<Registry Name>.azurecr.io"
```

If you will look at package.json file for application there isn't any dependency defined because we have all the dependencies in the container. "npm test" will execute the test and create all the report in the Reports folder. "npm run build" will perform the build and place all the bundles and associated files in Dist folder. If you want to perform code changes and keep the webpack-dev-server running you can execute "npm start".

You can choose any Continuous Integration system and perform the same tasks automatically.

Originally posted on [Medium Blog](https://medium.com/@MTNomani/optimize-nodejs-applications-build-using-docker-7fc5c756271a) Posting