Best of 2022: Deploying Angular Apps to a Kubernetes Cluster
As we close out 2022, we at Container Journal wanted to highlight the most popular articles of the year. Following is the latest in our series of the Best of 2022.
Angular is a component-based framework for building single-page client-side applications. It is based on HTML and TypeScript. Angular is written in TypeScript and provides TypeScript libraries you can import into your applications, with functionality such as routing, form management and client/server communication.
Web application frameworks like Angular improve development efficiency by providing a consistent structure so that developers do not have to rewrite their code from scratch. A framework also provides useful infrastructure and features that can be added to the software without extra effort. Angular also provides developer tools to support initial development, builds, file uploads, code testing and updates.
Kubernetes is the world’s most popular container orchestration platform. It is being used to run workloads of all shapes and sizes, and web applications are no exception. Kubernetes can be an excellent option to run large-scale web apps composed of multiple services, potentially with multiple instances for each service. I’ll cover the basics of Angular and show how to use Kubernetes to deploy and scale Angular applications.
Angular Concepts
NgModules
The basic building blocks of an Angular application are NgModules which provide compilation contexts for components. NgModules aggregate related code into feature sets. An Angular application always has at least one root module that supports bootstrapping and might have one or more additional feature modules.
Components and services
In Angular, components define views, which are a set of UI elements that Angular can select and change based on program logic and data.
Components use services that provide specific functionality not directly related to views. By injecting service providers as dependencies into components, you can make your code modular and reusable.
Components and services are simple classes with decorators that expose their types and provide metadata that describes how Angular should use them.
A few important points about components, services and views:
- Each component class has metadata associating it with the template that defines the view.
- Templates combine plain HTML with Angular directives and binding tags, allowing Angular to modify HTML for display before rendering.
- Service class metadata provides the information Angular needs to make available to components via dependency injection (DI).
Error handling
Angular provides error handlers that offer user-friendly information about errors and enable developers to gather important data for development and debugging. The data gathered from error handling can inform the development team about important issues missed in testing. In the next section, I’ll show you how to run an Angular application in a container and error handling will be important to enable monitoring of your container deployment.
The traditional way to handle errors in Angular is to provide an ErrorHandler class. You can extend this class to create your own global error handler.
Since Angular 4.3.1, a new way to handle errors is HttpInterceptor. It provides a way to intercept HTTP requests and responses and transform or process them before forwarding them. This makes it possible to change headers, add authentication tokens, and change data types.
How to Deploy Angular Applications on Kubernetes
1. Create Angular Application
To create an Angular application:
- Use the following command to initialize a new Angular application and go inside the directory:
ng new demo-app
cd demo-app
- Use the following command to run the development server:
ng serve
- Put the following link in your browser to view the Angular app:
http://localhost:4200/
2. Write Custom Nginx Configuration
To add a custom Nginx configuration file:
Add the following in a file named demo-nginx-custom.conf:
map $sent_http_content_type $expires {
default off;
text/html epoch;
text/css max;
application/json max;
application/javascript max;
~image/ max;
}
server {
listen 80;
location / {
root /usr/share/nginx-demo/html;
index index.html index.htm;
try_files $uri $uri/ /index.html =404;
}
expires $expires;
gzip on;
}
3. Build and Push Dockerfile for Building Angular Application
To create a dockerfile to build the Angular application:
Store the following in a dockerfile named Dockerfile and put it inside the demo-app:
FROM node:10.8.0 as demo-build
WORKDIR /demo-app
COPY package*.json /demo-app/
RUN npm install
COPY ./ /app/
ARG configuration=production
RUN npm run build — –output-path=./demo-dist/out –configuration $configuration
FROM nginx:1.15
COPY –from=build-stage /demo-app/demo-dist/out/ /usr/share/nginx-demo/html
COPY ./demo-nginx-custom.conf /etc/nginx/conf.d/default.conf
This dockerfile provides the application with a node environment and builds it. Then, it copies the folder titled demo-dist from the earlier step to the specified Nginx container and copies the Nginx configuration inside nginx.
To build the docker image and push it:
- Use the following commands to build:
docker build -t demo/demo-app:v1 .
docker push demo/demo-app:v1
- Use the following commands to push to docker registry:
docker push demo/demo-app:v1
4. Create Kubernetes Deployment and Service Manifest
To deploy application in a Kubernetes environment:
- Create a deployment manifest file called demo-deployment.yaml and add this configuration to it:
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: demo-deployment
spec:
replicas: 1
template:
metadata:
labels:
label-key : demo-label
spec:
containers:
– name: demo-deployment-container
image: inyee/demo-app:v1
imagePullPolicy: Always
ports:
– containerPort: 80
- Create a service with the following configuration in a file called DEMO-service.yaml for internal access to the application:
apiVersion: v1
kind: Service
metadata:
labels:
service-label-key: demo-service-label
name: demo-service
spec:
type: ClusterIP
ports:
– name: demo-service-port
port: 80
protocol: TCP
selector:
deployment-label-key: demo-deployment-label
- Create a service for load balancing for access outside the Kubernetes cluster with the following configuration in a file called demo-load-balancer.yml:
apiVersion: v1
kind: Service
metadata:
labels:
service-label-key: demo-service-label
name: demo-loadbalancer
spec:
type: LoadBalancer
ports:
– name: demo-service-port
port: 80
protocol: TCP
selector:
deployment-label-key: deployment-label-value
- Use the following command to create a deployment in a Kubernetes cluster:
kubectl apply -f demo-deployment.yaml
- Use the following command to create a ClusterIP service:
kubectl apply -f DEMO-service.yaml
- Use the following commands to create a load balancer service to access the application via an external IP:
kubectl apply -f demo-load-balancer.yml
kubectl get svc -owide
- This command gets the external IP that the service provides:
kubectl get svc
This shows the following output:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service-name ClusterIP xx.xx.xx.xx <none> 80:31527/TCP 1d
demo-load-balancer LoadBalancer xx.xx.xx.xx xx.xx.xx.xx 80:31202/TCP 1d
Visit the external IP provided here to see the Angular app.
Conclusion
In this article, I explained the basics of Angular and showed how to deploy your first Angular application to a Kubernetes cluster. This involves the following main steps:
- Create a demo Angular app (or use an existing application).
- Write a custom Nginx configuration that is compatible with a container environment
- Build a Dockerfile for your application and push it to Docker registry
- Create a Kubernetes deployment object and YAML service manifest for the application.
- Create the deployment object in your cluster by running kubectl apply -f your-application.yaml.
I hope this will be useful as you learn to deploy and manage web applications in containerized environments.