Deploy locally NodeJS and MongoDB application using kubernetes
Kubernetes is an open source container orchestration engine for automating deployment, scaling, and management of containerized applications
What we’re going to do in this tutorial:
1. Create NodeJS and Express Application
2. Setup MongoDB
3. Dockerizing the application and run locally using docker-compose
4. Converting docker-compose to kubernetes and deploy locally
We’ll be using Minikube for our local deployment, you check their website for installation steps.
Along with minikube, install kubectl, kubectl allows you to run commands against Kubernetes clusters. You can use kubectl to deploy applications, inspect and manage cluster resources, and view logs
Let’s start with the first step by creating nodejs application first
mkdir nodejs-mongodb-kubernetes && npm init --yes && yarn add express && mongodb
Create src/index.js
file and copy below content
Next copy db.js
in src folder and copy following content
Create Dockerfile
and copy following content
Create docker-compose.yml
and copy following content:
so if all the files in place the directory structure will look as follows:
if you’ll see docker-compose file line 4, there is local docker image (local-nodejs-kubernetes
), to create the docker image run following command in the root of the project. don’t forget to copy dot(.) in the last
docker build -t local-nodejs-kubernetes .
once docker build successful, it will create docker image in you machine, now let’s try to run this images using docker-compose, run following command
docker-compose up --build -d
it will run the image and mongdb and exit from shell, run following command to see the running images.
docker-compose ps
you will see your running images and ports, now let’s see the logs of our service, run following command, nodejs-kubernetes
is the name of the service in docker-compose.yml
file
docker-compose logs -f nodejs-kubernetes
you will see following output:
Attaching to nodejs-mongodb-kubernetes_nodejs-kubernetes_1
nodejs-kubernetes_1 |
nodejs-kubernetes_1 | 🚀 Server is running!
nodejs-kubernetes_1 | 🔉 Listening on port 80
nodejs-kubernetes_1 | 📭 Click here http://localhost:80
nodejs-kubernetes_1 |
nodejs-kubernetes_1 | DB connection successful!
so based on the above logs, DB connection is successful and server is running on port 80, 80 is the internal port and we exposed it and bind the port with 8099 in docker-compose file, you can see port forwarding in docker-compose ps
output, it will shows you ports 0.0.0.0:8099->80/tcp,:::8099->80/tcp
, now let’s try to open http://localhost:8099
, you should see success message on browser like following image:
Next step is to Converting docker-compose to kubernetes, for that we’ll be using tool called Kompose, check the installation steps it’s very easy, once you installed successfully just go your project directory where docker-compose.yml
file and run the following command
kompose convert
if command runs successfully you will get following output:
Create a directory called deployments
move all the files in deployments, before moving just ensure minikube is running, you run command minikube start
, if already running just check the status minikube status
it will show the status of your cluster. along with that check kubectl is installed and type kubectl
and press enter it will show bunch of commands. now let’s deploy out stack using kubectl, run following commands:
kubectl apply -f deployments
it will create and deploy service and once you can check status using following commands:
kubectl get pods
but you will see it will show error for local image:
NAME READY STATUS RESTARTS AGE
nodejs-kubernetes-5788bdd4f7-k7b4n 0/1 ErrImagePull 0 9s
nodejs-kubernetes-mongodb-77c4b9944-nzn6w 1/1 Running 0 9s
and after some time it will also show ImagePullBackOff
, reason is kubernetes not able to download the local images, there are two ways to fix
1. set the docker env eval $(minikube docker-env)
in shell and after that again build the image and set the imagePullPolicy to Never.
2. upload the local image to docker hub and it will run
let’s try both ways
go to shell and run the following command
eval $(minikube docker-env)
Now let’s build the image again
docker build -t local-nodejs-kubernetes:1 .
once done open nodejs-kubernetes-deployment.yaml
after line 32 image: local-nodejs-kubernetes
add this line and change image name to local-nodejs-kubernetes:1
see below
image: local-nodejs-kubernetes:1
name: nodejs-kubernetes
imagePullPolicy: Never
save the file and delete the deployment using command
kubectl delete -f deployments
and apply again
kubectl apply -f deployments
now check the running pods:
kubectl get pods
so if so far everything is well both of services are running, let’s check the service logs:
kubectl logs -f nodejs-kubernetes-56b84df6ff-sqhjv
so our service is up and running, however after few seconds it show error because service is not able to connect to mongodb and pod status show service is crashlooping
and if you will see the logs kubectl logs -f nodejs-kubernetes-56b84df6ff-sqhjv
connection timed out means service is not able to connect to MongoDB, to fix this let’s check the type of the service MongoDB, run the following command
kubectl get services
as mentioned in docs , we need to expose the mongo port to using type NodePort
open file nodejs-kubernetes-mongodb-service.yaml
and after line 11 spec:
press enter indent and copy this type: NodePort
spec:
type: NodePort
make sure to indent equal to ports and also change the port to 27017, NodePort will assign the external port automatically, save the file and apply the configuration again or delete and apply whole stack
kubectl apply -f deployments/nodejs-kubernetes-mongodb-service.yaml
and also delete the pod, first check the pods by running kubectl get pods
and delete the service pod
once delete kubernetes will bring it back and if you check the status it will show running and check the logs as well, you should see following output
now if you will check the services using kubectl get services
you should see like this
Next step is to expose the service so that we can access it though browser, open the file nodejs-kubernetes-service.yaml
after line 11 press enter and copy another type: LoadBalancer
spec:
type: LoadBalancer
save the file and apply kubectl apply -f deployments/nodejs-kubernetes-service.yaml
and delete the pod and now if you will check the services again
you will type LoadBalancer
for node-kubernetes
service and port is also assigned by kubernetes itself however if you will try to open in browser it will still not work because EXTERNAL-IP
coming as <pending>
, so for local deployment purpose we need to minikube tunnel, open another shell and run command
minikube tunnel
once this is done check the kubectl get services
and you will see external ip assigned
now try to open http://10.111.140.118:8099/ and you will see success message if everything goes well,
2 .upload the local image to docker hub and it will run — let’s try this now
create a new docker image and change the success message from success to hello kubernetes! go to index.js
and on line 10 change like below and save the file
res.json('Hello kubernetes!')
now let’s build the image in new terminal with your username as in docker or you can tag later on whatever suitable
docker build -t yasharma6121991/local-nodejs-kubernetes:1 .
now push this image to docker hub and open the file nodejs-kubernetes-deployment.yaml
and also comment line 34 # imagePullPolicy: Never
change the image name save the file, apply the configuration again
kubectl apply -f deployments/nodejs-kubernetes-deployment.yaml
check the pod status it will show terminating old and creating new one
now refresh the page and you will see new message
Hurray! you are able to run deploy and run services using kubernetes, i know there are rooms for improvement and it’s not production setup one thing is missing that is MongoDB volume mounting because if MongoDB service re-deployed it will lost the data. once tested you can stop the minikube and delete the stack
kubectl delete -f deployments
minikube stop
Thanks for reading, let me know your comments and you can check the code in Github repo