Angular front end on nginx, SpringBoot APIs and MongoDB
First need to get the following tools installed:
-
Install Kubernetes
-
Install Minikube
-
Install Docker
The frontend application is contained within the folder front-end and the backend SpringBoot project is
contained within back-end. The kubernetes yaml files for both front end and the backend are inside
the folder k8s.
We will use the official mongo image from dockerhub and run a mongodb service in our kubernetes cluster. This
service will be used by the backend as data storage.
The mongo.yaml defines a ReplicationController which ensures that there is always one instance of mongo
running in our cluster. This mongodb pod is listening on container port 27017 and the data storage path is /data/db
within the container which is mounted on host at /data/storage/mongodb.
The mongodb pod above is exposed as a service within our kubernetes cluster as a service with name mongo-service as
described in mongo.yaml.
arun:k8s achalise$ kubectl get pods
arun:k8s achalise$ kubectl get pod mongo-controller-5b3dl
NAME READY STATUS RESTARTS AGE
mongo-controller-5b3dl 1/1 Running 0 5m
arun:k8s achalise$ kubectl exec -it mongo-controller-5b3dl -- /bin/bash
-
minikube startto start the local kubernetes cluster which takes a while to get the cluster ready.arun:k8s achalise$ minikube start There is a newer version of minikube available (v0.19.0). Download it here: https://github.com/kubernetes/minikube/releases/tag/v0.19.0 To disable this notification, run the following: minikube config set WantUpdateNotification false Starting local Kubernetes cluster... Starting VM... SSH-ing files into VM... Setting up certs... Starting cluster components... Connecting to cluster... Setting up kubeconfig... Kubectl is now configured to use the cluster. arun:k8s achalise$ -
Deploy and start up the
mongoservice using the descriptor filemongo.yamlarun:k8s achalise$ kubectl create -f mongo.yaml replicationcontroller "mongo-controller" created service "mongo-service" created arun:k8s achalise$Check that the pod and service are created and running successfully:
arun:k8s achalise$ kubectl get pods NAME READY STATUS RESTARTS AGE mongo-controller-srq9f 1/1 Running 0 8m arun:k8s achalise$ kubectl get services NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes 10.0.0.1 <none> 443/TCP 27d mongo-service 10.0.0.111 <none> 27017/TCP 8m arun:k8s achalise$Check the logs to make sure mongodb started successfully:
kubectl logs mongo-controller-srq9fin my case. Run command with the correctpodname. -
Deploy and start up the SpringBoot service
arun:k8s achalise$ kubectl create -f backend.yaml deployment "backend" created service "backend" created arun:k8s achalise$ kubectl get pods NAME READY STATUS RESTARTS AGE backend-2415081020-tmx44 1/1 Running 0 51s mongo-controller-srq9f 1/1 Running 0 21m arun:k8s achalise$ kubectl get services NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE backend 10.0.0.88 <none> 8080/TCP 1m kubernetes 10.0.0.1 <none> 443/TCP 27d mongo-service 10.0.0.111 <none> 27017/TCP 21m arun:k8s achalise$ -
Deploy and start the Front End
arun:k8s achalise$ kubectl create -f front-end.yaml deployment "frontend" created service "frontend" created arun:k8s achalise$ arun:k8s achalise$ kubectl get pods NAME READY STATUS RESTARTS AGE backend-2415081020-tmx44 1/1 Running 0 8m frontend-3251706051-p7770 1/1 Running 0 31s mongo-controller-srq9f 1/1 Running 0 29m arun:k8s achalise$ arun:k8s achalise$ kubectl get services NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE backend 10.0.0.88 <none> 8080/TCP 9m frontend 10.0.0.86 <nodes> 8888:32318/TCP 52s kubernetes 10.0.0.1 <none> 443/TCP 27d mongo-service 10.0.0.111 <none> 27017/TCP 29m arun:k8s achalise$ -
Access the application from outside the cluster
arun:k8s achalise$ minikube service frontend Opening kubernetes service default/frontend in default browser... arun:k8s achalise$To just list the url of the service:
arun:k8s achalise$ minikube service frontend --url http://192.168.99.100:32318 arun:k8s achalise$
We hardcoded value for the MONGO_URI env variable to mongo-service in our deployment yaml for backend.
spec:
containers:
- name: backend
image: "achalise/demo-backend"
ports:
- containerPort: 8080
env:
- name: MONGO_URI
value: mongo-service
Also there is customer.message defined in application.properties which we would like to populate via configmap
to fully externalise conig from code.
We want to change it so that the value to the environment variable is fed from config map so that configuration is completely separate from the image.
Create a backend config map yaml backend-config.yaml with the relevant config data:
apiVersion: v1
kind: ConfigMap
metadata:
name: backend-config
namespace: default
data:
MONGO_URI: mongo-service
customer_message: message overridden from configmap
Then execute kubectl create -f backend-config/backend-config.yaml
or from literal
kubectl create configmap backend-config --from-literal=mongo.host=mongo-service --from-literal=customer.message='original message modified'
arun:k8s achalise$ kubectl create configmap backend-config --from-file=backend-config
configmap "backend-config" created
arun:k8s achalise$ kubectl describe configmap backend-config
Name: backend-config
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
backend-config.properties:
----
MONGO_URI=mongo-service
customer.message="Message overwritten from configmap"
arun:k8s achalise$
The to create backend specifying the environment variable names,
kubectl create -f backend-with-configmap-specify-names.yaml
Or to create backend importing everything in the configmap as env variables,
kubectl create -f backend-with-everything-in-configmap.yaml
First install angular cli gloablly with npm install -g @angular/cli.
Now generate a new project with angular cli by executing
ng new front-end. We have named our application front-end.
Create a Dockerfile using nginx image to deploy our angular app.
docker build -t achalise/demo-frontend
docker push achalise/demo-backend
To remove all stopped containers
docker rm $(docker ps -a -q)
-
MongoDB - exec
mongod --dbpath /data/db, where/data/dbis your local drive for mongodb to write to.chmodwrite permission on it. -
Backend -
./gradlew bootRun -
Front End -
ng serve --proxy-conf proxy.conf.json
-
MongoDB -
docker run -p 27017:27017 mongo -
Backeend - prepare docker image
./gradlew buildDocker -x test- and run usingdocker run -p 8080:8080 achalise/demo-backend -
FrontEnd - run
ng buildto produce dist artefact anddocker build -t achalise/demo-frontendin the folderfront-endwhere we have ourDockerfile. Thendocker run achalise/demo-frontend -p 4300:80
But need Docker compose to make a bridge to make them talk to one another.
Easiest way is to do it using stackpoint.io
Initial set up:
-
Sign up with AWS, and have a free tier ubuntu instance set up
-
Locall install aws client for CLI
-
Locally install KOPS
-
Create Route53 domain for the cluster with name
dev.demo.comaws route53 create-hosted-zone --name dev.demo.com --caller-reference 1And verify withdig NS dev.demo.com -
Create S3 bucket to store the cluster state
aws s3 mb s3://clusters.dev.demo.com -
Export
export KOPS_STATE_STORE=s3://clusters.dev.demo.com, store it as env variable in.bash-profile. -
Build the cluster
kops create cluster --zones=us-east-2a useast2.dev.demo.com