We use cookies to provide you with a great user experience, analyze traffic and serve targeted promotions.   Learn More   Accept
Card image cap

Dockerizing an Angular Application for Release Build and Deploy

Docker Angular  • Posted one month ago

Let's talk about how we can use docker in building and hosting an Angular application in a container. Docker is a tool which helps in creating, deploying, and running applications by means of isolated environments called as containers. A container can be thought of a package which allows developer to pack all the necessary libraries and dependencies for running an application without any issues and deploy the entire container as an instance. This ensures that the application runs without any environmental issues which might otherwise arise in an application deployment.

For creating a container using docker, we make use of a build script called Dockerfile which contains instructions for docker on how to build the application and what all the dependencies and libraries that need to be packed into the container before packing it into a complete entity. Once the container has been created, we then run the docker command to boot up the container with instructions on how the application should behave on startup and so on.

Now that we have an idea about what Docker is and how we shall proceed, we begin by understanding how we need to build and pack our angular application for containerized use. Angular application is a Single Page Application (SPA) in which the entire application runs on an index.html with JavaScript files tagged along with it. In order for any Angular application or an SPA to run, we would need to host it in a webserver that listens to incoming HTTP requests and routes to the application accordingly. Some examples of a webserver are Apache, Kestrel, IIS, Nginx and so on. So it is clear that we would also need to pack a webserver along with our angular application for it run inside a container.

To release build an angular application, we would go through the below steps:

  1. Install dependencies
  2. Run angular build with release flag
  3. Copy the output files onto the webserver

Let's begin by scripting the Dockerfile we are to use for building the container. A Dockerfile generally contains three segments, A base image declaration, some script instructions and a startup command.

We shall choose a base image which can provide us with necessary prerequisites such as nodejs, angular and npm for us begin with the build. Unfortunately, we would need to prepare one such image for us as there are not many docker images which come with angular out-of-the-box. Instead, we would choose a docker image which comes with nodejs so that we can continue on top of it by installing angular and so on.

For this, we would choose node:14.2.0-alpine3.11, which is an alpine image with nodejs preinstalled. For starters, alpine is a light-weight linux image which supports installing necessary dependencies by means of its own package manager known as apk (Alpine Package Manager).

We shall write instructions on top of the node:14.2.0-alpine3.11 image we have chosen inline with the steps mentioned above as:


# BASE IMAGE with an alias #
FROM node:14.2.0-alpine3.11 as build
WORKDIR /app

# Install Angular CLI to run Build #
RUN npm install -g @angular/cli

As described in the comments, so far we have specified our base image with a tagged "alias" which we shall use in the next steps. Then we added an instruction to run install angular/cli via npm. After these steps are executed, we will have a node-alpine image with angular/cli installed. We can now run angular commands over our angular project for build and deploy.


COPY ./package.json .
RUN npm install
COPY . .
RUN ng build

In the next steps, we begin by copying the package.json file alone from our angular project and copy it onto the container directory. This is followed by an instruction to run "npm install" that installs all the necessary dependencies for our angular project onto the container. Once this is done, we just copy all the contents in our angular project onto the container. This includes the src, e2c, tsconfig and other files which are in the angular project directory. Since we already have the node_modules installed, we are now good to go and so our next instruction is for an "ng build" that packs the angular application into index.html and minified JavaScript files.

We now have our angular application built and the binaries available under /app/dist/MyAngularApp in the container. Next is deploying the contents of this folder in a webserver. We choose nginx for this job, because it's lightweight and easy to use. The steps to copy the contents from /app/dist/MyAngularApp onto another container which is an nginx webserver is what we called a "build step".


# BASE IMAGE with an alias #
FROM nginx as runtime

# Copy contents from the other container with alias "build" #
# onto the specified path in the current container#
COPY --from=build /app/dist/MyAngularApp /usr/share/nginx/html

As described in the comments, we make use of the alias "build" we tagged for the container in the "previous step" which generated the output angular files and copy those output files into the path "/usr/share/nginx/html" within the current container. According to the nginx documentation, in order for a file to be hosted in the nginx webserver we would need to paste the contents under the above path.

Whenever Docker comes across a second FROM instruction, it treats it as a new "build step" meaning that the container instructions have been completed. It now starts with the new container and in this case, copies the contents from the previous container and into the current container in the specified path. This completes our build and deploy "script". But we haven't instructed on how the "application" should behave when it starts up as a container. In this case, since we're using a webserver all it does is listen on the port 80 and so nothing in particular needs to be done for us here.

The complete script:


FROM node:14.2.0-alpine3.11 as build
WORKDIR /app

RUN npm install -g @angular/cli

COPY ./package.json .
RUN npm install
COPY . .
RUN ng build

FROM nginx as runtime
COPY --from=build /app/dist/MyAngularApp /usr/share/nginx/html

To run this recepie, we run the below command in the same directory as the Dockerfile, which will build this script into a container.


> docker build .

Which returns us a container_id. Then we run,


docker run -p 8080:80 container_id

This way, we specify that all the requests to port 8080 onto the container from the outside network shall be internally routed to port 80 where the angular application runs.

Alternatively, we have the docker-compose route which simplifies our "docker run" instructions in the form of a docker-compose.yaml file in the same directory as of the Dockerfile as below:


version: "3"
services: 
    angular-app:
        build: .
        ports: 
            - 8080:80

And to run this, we simply call:


> docker-compose up