Welcome to today’s post.
Today I will be showing how to create a docker container for an Angular application that is run as a web server.
In the previous post I showed how to create a Node docker image containing an Angular application and run the application as an Angular docker container.
I will be using an Nginx image as our web server. An Nginx server is a lightweight, high performance server that can be used for many purposes, including reverse proxy, web server, and load balancer. In this case we will be using it as a web server that serves static content from an Angular application.
The Docker hub has an image repository for Nginx at https://hub.docker.com/_/nginx.
Building a Docker Container that runs an Angular Application
Before we can include the Angular application in the container, we will need to include the Nginx web server in the build.
Including an Nginx Web Server in a Docker Build
To setup an Nginx web server as a Docker image we need the following:
- An Nginx image from Docker hub.
- Nginx configuration file for our web application.
- Web application folders populated with static content.
- Expose ports from the static web site to our container.
- Mapping of an external host port to the container’s static web site’s port.
As we saw in the previous post, an Angular application uses port 4200 in a development environment, however in a web server container that hosts static content, it uses localhost (port 80). After we have built our Angular application into static content, all we need to do is move it into the web server distribution folder where it can be served.
We can map the web server port to different port, which is exposed to our host environment instead of the internal port.
With an Nginx server, we not only have a web server, but also a gateway for our web application. Any additional web services and data stores that are dependent on our static Angular web application can be hosted within their own API gateway server.
To include the Nginx image within our build we refer to the guide at https://hub.docker.com/_/nginx.
The following script:
FROM nginx:1.19.7-alpine
COPY /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
achieves the following:
- Pulls the Nginx image from docker hub
- Copies the application distribution folder to the Nginx HTML folder
- Exposes port 80 within the container.
- Runs the Nginx server with switch -g daemon off, which keeps Nginx server as a foreground task so that the container keeps running.
Including an Nginx Web Server in a Docker Multi-Build
The next step is to include the NgInx web server in a build that includes installation and setup of the Angular development environment. When we include the Nginx build as part of a multi-build within the DockerFile the script will look as follows:
FROM node:12.18-alpine AS build
WORKDIR /usr/src/app
ENV PATH /usr/src/app/node_modules/.bin:$PATH
COPY ["package.json", "package-lock.json", "./"]
RUN npm install
RUN npm install -g @angular/cli
RUN npm install --save-dev @angular-devkit/build-angular
COPY . .
FROM nginx:1.19.7-alpine
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
The line starting with COPY –from=build copies the Angular application distribution folder from the build stage of the build and copies it over to the Nginx HTML folder.
Running the Docker Image
To create our docker image we can run the following Docker command:
>docker build -f Dockerfile -t angular_docker_app:latest .
The successful output will look as shown:
Sending build context to Docker daemon 18.55MB
Step 1/12 : FROM node:12.18-alpine AS build
---> e13d60032d4d
Step 2/12 : WORKDIR /usr/src/app
---> Running in a1fc451eafc7
Removing intermediate container a1fc451eafc7
---> 83fa1ae01946
Step 3/12 : ENV PATH /usr/src/app/node_modules/.bin:$PATH
---> Running in 3d748d13b233
Removing intermediate container 3d748d13b233
---> 180ebba60e37
Step 4/12 : COPY ["package.json", "package-lock.json", "./"]
---> cf46b209b336
Step 5/12 : RUN npm install
---> Running in ad063906ee9b
Removing intermediate container ad063906ee9b
---> 77a58eef6dc8
Step 6/12 : RUN npm install -g @angular/cli
---> Running in e26077de6bc2
Removing intermediate container e26077de6bc2
---> f29d9b47b40c
Step 7/12 : RUN npm install --save-dev @angular-devkit/build-angular
---> Running in 9365fbeda245
Removing intermediate container 9365fbeda245
---> d01c87ab22ff
Step 8/12 : COPY . .
---> 61790f993bfa
Step 9/12 : FROM nginx:1.19.7-alpine
---> eb9291454164
Step 10/12 : COPY --from=build /usr/src/app/dist/angular-docker-app /usr/share/nginx/html
---> 2e45d73c1e1b
Step 11/12 : EXPOSE 80
---> Running in 31a66ba5eb7b
Removing intermediate container 31a66ba5eb7b
---> 2a2a84bd5590
Step 12/12 : CMD ["nginx", "-g", "daemon off;"]
---> Running in 1b708de30fc1
Removing intermediate container 1b708de30fc1
---> e6ed60430755
Successfully built e6ed60430755
Successfully tagged angular_docker_app:latest
Running the Angular Application within the Docker Container
To run the Angular app hosted in an Nginx web server we apply the following Docker command:
>docker run --name angular_docker_app_container -d -p 63001:80 -it angular_docker_app:latest
Note that instead of using internal port 4200 as we did for an Angular container app, we use port 80 from the Nginx container web server’s port. In the command we map port 80 over to host port 63001.
When the application is run in our browser at the URL:
http://localhost:63001/ We can view it the same as we would for an Angular docker container app:
We have successfully hosted an Angular application within an Nginx web server within a Docker container!
In future post I will be showing how to allow environment variables to be used within our Angular container application.
That’s all for today’s post.
I hope you found this post useful and informative.
Andrew Halil is a blogger, author and software developer with expertise of many areas in the information technology industry including full-stack web and native cloud based development, test driven development and Devops.