You are on page 1of 28

CS 816 – Software Production Engineering

Project – Bus Ticketing System with DevOps

MT2022161-Aditya.M
MT2022163-Kiran Kumar B

Bus Ticketing System :

▪ MERN stack is used for implementing the web app


▪ JWT Authentication and Password hashing
▪ Redux Toolkit
▪ Jest and Super Test for writing test cases
▪ UI components designed using Ant Design Library.
▪ Stripe’s API for Payments

▪ Feature in Web App:


o Create separate User Interfaces for users, admins.
o Manage Tickets and user from the Admin Panel.
o If a direct bus is not available between source & destination
locations then we will provide alternative booking option, if there is
a bus to intermediate stop and then to destination.
o User:
▪ New users have to first register and then login to use the web
app.
▪ Users can search a buses based and source and destination and
can book tickets. Then can also see and print the previous
bookings they have made.
o Admin
▪ Initial admin should be added directly to database. Later admin
can add new admins from the web app.
▪ Admin can block/unblock users. Also can make bookings like
user.
▪ Admin can also add/remove/update and delete buses.

Links:
• Source Code:
▪ BusTicketingSystem-DevOps/Client (github.com)
▪ BusTicketingSystem-DevOps/Server (github.com)
• Docker Images:
▪ adityagowda2000/client general | Docker Hub
▪ adityagowda2000/server general | Docker Hub
DevOps Tools Used:

• Git & GitHub- Git is a distributed version control system which is


used for management of changes /versions of your project source
code. GitHub is a web based , git file hosting service which enables
us to share/showcase our project and files to others.

• NPM (node package manager) -Node Package Manager (npm) is a


package manager for Node.js projects made available for public
use1. It allows developers to use code written by others easily
without the need to write them ourselves during development1.
npm manages all the packages and modules for Node.js and
consists of command line client npm2. It gets installed into the
system with installation of Node.js2. More than just a program,
npm is an entire ecosystem.

• Jenkins- Jenkins is a Java-based open-source automation platform


with Continuous Integration (CI) plugins. Jenkins is used to produce
and test software projects on a regular basis, making it easier for
developers to incorporate changes and for users to get a new build.

• Docker-Docker is an open platform for developing, shipping, and


running applications. Docker enables you to separate your
applications from your infrastructure so you can deliver software
quickly. With Docker, you can manage your infrastructure in the
same ways you manage your applications.

• Ansible-Ansible is an open-source configuration management tool


that provides a minimalist server automation framework based on
YAML definitions. Its simplified infrastructure requirements and
accessible syntax helped make Ansible one of the most popular
configuration management tools to date.
• ELK Stack- ELK stack is an acronym for three open-source projects:
Elasticsearch, Logstash, and Kibana.
It is a log analysis platform that allows you to aggregate, process,
and visualize data from multiple sources.

Screen Shots of the Web App:

Login Page
Register Page

User Screens
Admin Screens
Test Cases for backend
Test Cases for frontend
API’s Listing:-

Users Controller:

1. POST /api/users/register - Register a new user


2. POST /api/users/login - Authenticate user and get a token
3. GET /api/users/:userId - Get user by ID
4. GET /api/users - Get all users
5. PUT /api/users/:userId/permissions - Update user permissions by ID

Buses Controller:

1. POST /api/buses - Add a new bus


2. GET /api/buses - Get all buses
3. PUT /api/buses/:busId - Update bus by ID
4. DELETE /api/buses/:busId - Delete bus by ID
5. GET /api/buses/:busId - Get bus by ID

Bookings Controller:

1. POST /api/bookings - Book a seat


2. POST /api/bookings/payment - Make payment for a booking
3. GET /api/bookings/user/:userId - Get bookings by user ID
4. GET /api/bookings - Get all bookings

Project Steps:
1. Version Control with GitHub
Client repo is used to maintain the front end source code along with the
dockerfile to containerize the frontend of the application.

Server repo is used to maintain the back end source code along with the
dockerfile to containerize backend of the application . It also contins the
deploy.yaml file which Ansible used to deploy the application to target
machine in the inventory. It also contains the docker-compose.yaml file
which is used to setup the front end and back end container on the target
machine.

We are using git-crypt to encrypt the secretes stored in .env files and all
the target machines ip address in the inventory file of the Server
repository.
How to setup git-crypt: AGWA/git-crypt: Transparent file encryption in git (github.com)

How to decrypt the secretes in Jenkins: Git-Crypt with Jenkins. Before going forward let’s just
see… | by vishant sharma | Medium

2. Jenkins [continuous Monitoring]

Jenkins installation and setup- Install Jenkins on your computer to


use it as a Jenkins server.
• $ wget -q -O -
https://pkg.jenkins.io/debian-
stable/jenkins.io.key |sudo apt-key
add –
• $ sudo sh -c 'echo deb http://pkg.jenkins.io/debian-stable
/etc/apt/sources.list.d/jenkins.list
• $ sudo apt update
• $ sudo apt install Jenkins
• $ sudo cat/var/lib/Jenkins/secrets/initialAdminPassword
=>to copy initial password for Jenkins
• Go to localhost/8080 for the Jenkins page
• Enter the initial Admin Password and then create
new userprofile.

Plugins to be installed in Jenkins-


• Git
• Maven
• Ansible
• Docker

Ngrok setup
Used to convert the private IP address of the Jenkins server into
public address so we can use webhooks to automatically rebuildthe
project when new changes are pushed into the GitHub
repository.
• Install ngrok on you system after creating a free account
$ngrok 8080 => to expose port no 8080 to a public IP

• Make note of the ngrok ip address

Secrete Text Creation – GitHub

Create a secrete text/personal access token and make note of it.

GitHub Webhook setup


• In the GitHub repository’s setting add a webhook with
payload as the Jenkins server’s public IP address[ngrok
address] and also add the secrete access token which was
copied in the above step.
Jenkins server configuration
2. In configure system add the ngrok address as the
JenkinsURL

3. Copy personal access token from the webhook configuration

Create two new Pipeline project with GitHub hook trigger for GITScm
polling as a build trigger.

[ONE PIPELINE IS LINKED WITH THE CLIENT GITHUB REPO AND ANOTHER IS LINKED WITH SERVER GITHUB REPO.]
Pipeline Scripts:
• Client Pipeline Script

Here we are getting the source code of the frontend from the Client
repo. Then installing all the dependency packages and running the
test cases. If all the test cases are passed then in next stage we will
build the image of the client with help of the dockerFile present and
publish it to DockerHub.
[MORE EXPLAINATION IN FURTHER STEPS ABOUT CREATING IMAGE AND PUSHING TO DOCKER HUB ]

As the code to deploy new changes to target machine is present in


the Server pipeline whenever a new build completes in Client job it
should trigger the Server job .

So in Server job set the Client as a upstream job.


• Server Pipeline Script

Initial steps are same as Client script where we are pushing the
image containing updated Server code. But here first we are
decrypting the .env and inventory file using the symmetric key
which we had encrypted before pushing the source code to docker
hub.

At last step we are deploying the application using Ansible .


[MORE EXPLAINATION IN FURTHER STEPS ABOUT DEPLOYING THE APPLICATION WITH ANSIBLE]
3. Containerization using Dockerfile
 Install Docker on your computer which is acting as the Jenkins
server : How To Install and Use Docker on Ubuntu 20.04 | DigitalOcean
 Give permission for docker to be executed without sudo
command.
i. Solution 1:
$ sudo usermode -a -G docker $USER
ii. Solution 2:
$ sudo chmod 777 /var/run/docker.sock

[Caution: Running sudo chmod 777 /var/run/docker.sock will solve


your problem but it will open the docker socket for everyone which
is a security vulnerability]

Docker file for building image


# syntax=docker/dockerfile:1.4

# Create image based on the official Node image from dockerhub


FROM node:alpine

# Create app directory


WORKDIR /usr/src/app

# Copy dependency definitions


COPY package.json /usr/src/app
#COPY package-lock.json /usr/src/app
# Install dependecies
RUN npm install

# Get all the code needed to run the app


COPY . /usr/src/app

# Expose the port the app runs in


EXPOSE 5000

# Serve the app


CMD ["npm", "run","server"]

Docker file for building image


# syntax=docker/dockerfile:1.4

# Create image based on the official Node image from dockerhub


FROM node:alpine

# Create app directory


WORKDIR /usr/src/app

# Copy dependency definitions


COPY package.json /usr/src/app
#COPY package-lock.json /usr/src/app

# Install dependecies
RUN npm install

# Get all the code needed to run the app


COPY . /usr/src/app

# Expose the port the app runs in


EXPOSE 3000

# Serve the app


CMD ["npm", "start"]

4. Deployment with Ansible Playbook


Install ansible on Jenkins Server
• $ sudo apt install ansible

Note: We are going to create a new user account and consider it as


the target mahcine.
Create a new user on your computer which acts as deployment
server/target machine:
o $ adduser user_name
o $Usermode -aG sudo user_name => to
give sudopermissions to this user account
o $ su user_name => to switch back to user_name
which act’s as deployment server/target machine

Configure all the target machines to which the configuration has


to be pushed by the Jenkins server.
o Add the target machines in the inventory file.
o append the client hosts ip address along with
username and password in hosts inventory
file.
▪ [machine]
172.16.140.200 ansible_ssh_user=ag ansible_shh_pass=ag

Deploy.yaml- It is configured to send the docker-compose.yaml file to


the target machine and then start the containers using the docker
compose file.
---
- name: Deploy Docker Compose stack
hosts: all
tasks:
- name: Install Docker Compose
apt:
name: docker-compose
state: present

- name: Stop Previous Session


command: docker-compose down
args:
chdir: /home/ag/ansible

- name: Prune Unused Containers,Images and Networks


command: docker system prune -f

- name: Pull Backend Image


docker_image:
name: adityagowda2000/server
source: pull

- name: Pull Frontend Image


docker_image:
name: adityagowda2000/client
source: pull

- name: Copy Docker Compose file to host


copy:
src: /var/lib/jenkins/workspace/Server/docker-compose.yaml
dest: /home/ag/ansible/docker-compose.yaml

- name: Start Docker Compose stack


command: docker-compose up -d
args:
chdir: /home/ag/ansible

docker-compose.yaml- It is configured to pull the latest images of Server and


Client from the DockerHub and then start them on same network in the target
machine.
version: "3"
services:
client:
image: adityagowda2000/client
stdin_open: true
ports:
- "3000:3000"
networks:
- mern-app
depends_on:
- server
server:
image: adityagowda2000/server
ports:
- "5000:5000"
networks:
- mern-app
volumes:
- logs:/usr/src/app/logs
networks:
mern-app:
driver: bridge
volumes:
logs:
driver: local
driver_opts:
type: none
o: bind
device: /home/aditya/Desktop/logs

5. Monitoring Log files with ELK Stack


• Clone https://github.com/deviantony/docker-elk
• Unzip it and open terminal in the directory
• $docker-compose up -d => to create the image
• Launch the elastic server by running the docker image:
o $docker run -it docker-elk-main_kibana
• Now ELK sack is live in localhost/5601
• Login with “elastic” as user name and “changeme” as
password.
• Upload the log file generated manually.
Dashboards creates with log data

You might also like