Table of contents
The figure below shows the flow of our project. In this, we are going to take some code(Reddit clone) from GitHub to a t2.micro instance where Docker is installed. This t2.micro instance will be a CI server where we will build the code, test it and then push it into a repository. That repository is going to be Dockerhub.
Then we need another server which is going to be our deployment server. Here we will have a Kubernetes setup which will deploy our image on a scale. This is going to be a heavy server, so make sure you have a t2.xlarge instance, not a t2.micro.
Prerequisites
First of all, here is the link to the Reddit clone. Click here. Fork it.
Then we need to launch two EC2 instances. One will be our CI Server and another will be our Deployment server.
CI - Server
Let us do all the work we need to do on our CI server.
First, we need to install Docker on this server.
So connect to our CI-Server and copy and paste these commands.
sudo apt-get update
sudo apt-get install docker.io -y
sudo usermod -aG docker $USER && newgrp docker
Now once our Docker is installed, we need to bring the code from GitHub. So clone the repository. Use the command,
git clone <repository_URL>
Get the repository URL from the forked repository. As shown in the screenshot,
Now your code is available on CI-Server. Now we need to build this code. We already have a Dockerfile available in the source code.
FROM node:19-alpine3.15
WORKDIR /reddit-clone
COPY . /reddit-clone
RUN npm install
EXPOSE 3000
CMD ["npm","run","dev"]
Now we need to build a docker image from this Dockerfile and push it to Dockerhub. Run the command,
docker build . -t <username/image_name>
for example,
docker build . -t iamnaved/reddit-clone
After hitting enter you will see this kind of output,
After the command is successful, we need to push the image to Dockerhub so that we can deploy it on Kubernetes.
So we need to log in to Docker through our terminal. Run the command,
docker login
Then it will ask you for your username and password. Enter them and you will be logged in as shown in the screenshot.
Now to push the image to Dockerhub, run the command,
docker push <username/image_name>
for example,
docker push iamnaved/reddit-clone:latest
As you can see in the screenshot, your image is being pushed to Dockerhub.
So our CI part is done. We brought the code from GitHub, built it using docker and pushed it to dockerhub. So the first half of our project was successful.
Deployment Server
Now let us start with the deployment server.
Connect to the Deployment server. We need to install Docker, minikube and kubectl on this server. Run these commands,
# For Docker Installation
sudo apt-get update
sudo apt-get install docker.io -y
sudo usermod -aG docker $USER && newgrp docker
# For Minikube & Kubectl
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
sudo snap install kubectl --classic
minikube start --driver=docker
After successfully installing all these on our deployment server, we need to deploy the image which is available on Dockerhub.
So first we need to write Deployment. Here it is:
apiVersion: apps/v1
kind: Deployment
metadata:
name: reddit-clone-deployment
labels:
app: reddit-clone
spec:
replicas: 2
selector:
matchLabels:
app: reddit-clone
template:
metadata:
labels:
app: reddit-clone
spec:
containers:
- name: reddit-clone
image: trainwithshubham/reddit-clone
ports:
- containerPort: 3000
Make a folder on your instance, inside that create a Deployment.yaml file and paste the above code inside it. Now to deploy the application, run the command:
kubectl apply -f Deployment.yaml
Now to check the deployments, run the command:
kubectl get deployment
You will see this output,
You can manage the replicas as per your needs. Just simply update the number of replicas in the Deployments.yaml file.
Now how do we access our application?
For that, we will use a feature of Kubernetes which is known as 'Service'. So we need to create a Service.yaml file. Here it is:
apiVersion: v1
kind: Service
metadata:
name: reddit-clone-service
labels:
app: reddit-clone
spec:
type: NodePort
ports:
- port: 3000
targetPort: 3000
nodePort: 31000
selector:
app: reddit-clone
Copy this and paste it into the Service.yaml file. Then run the command and your service will be created,
kubectl apply -f Service.yaml
Now you can access your application.
For that run the command:
minikube service reddit-clone-service --url
You will get a URL after executing this command.
Now run the command,
curl -L <URL>
Your application will run on the terminal itself.
But what if you want to run it on your browser? For that, you need to expose your deployment.
First, go to the security groups of your deployment server and add an inbound rule to make port 3000 available externally, and make it anywhere accessible.
Now run these commands:
kubectl expose deployment reddit-clone-deployment --type=NodePort
kubectl port-forward svc/reddit-clone-service 3000:3000 --address 0.0.0.0 &
Now open a new tab and enter <instance_IP:3000>, you will see your application running.
Ingress
Kubernetes Ingress is an API object that manages external access to services within a cluster.
First, we need to enable ingress on our minikube. Run the command:
minikube addons enable ingress
Create a file named ingress.yaml. Copy the below code and paste it into it.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-reddit-app
spec:
rules:
- host: "domain.com"
http:
paths:
- pathType: Prefix
path: "/test"
backend:
service:
name: reddit-clone-service
port:
number: 3000
- host: "*.domain.com"
http:
paths:
- pathType: Prefix
path: "/test"
backend:
service:
name: reddit-clone-service
port:
number: 3000
Run the command:
kubectl apply -f ingress.yaml
Now, run this command:
curl -L domain.com/test
You will see your application running.
Outro
Congratulations, you successfully deployed a Reddit clone using Kubernetes ingress.
Stay connected with me for more blogs in this DevOps Project blog series.