Skip to content

A web system about reference letter handling in the context of DIT HUA Thesis "Use of devops methodologies and tools in development and production environment of web applications"

Notifications You must be signed in to change notification settings

panagiotis-bellias-it21871/reference-letters-system

Repository files navigation

reference-letters-system

A web system about reference letter handling in the context of DIT HUA Thesis "Use of devops methodologies and tools in development and production environment of web applications"

panagiotis-bellias-it21871

Languages and Tools:

azure bash bootstrap css3 docker git html5 jenkins kubernetes linux nginx postgresql python

Table Of Contents

  1. Table Of Contents
  2. Setup & Run Projects Locally (Installation)
  3. Deploy fastapi and vuejs projects to a VM (Virtual Machine)
    3.1. CI/CD tool configuration (Jenkins Server)
    3.1.1. Step 1: Configure Shell
    3.1.2. Step 2: Add webhooks to system repository
    3.1.3. Step 3: Add the credentials needed
    3.1.4. Create Job
    3.1.4.1. Build stage
    3.1.4.2. Docker Deployment
    3.1.4.3. Kubernetes Deployment
    3.2. Deployment with Docker and docker-compose using Ansible
    3.3. Deployment with Kubernetes using a piece of Ansible
    3.3.1. Using Multiple Namespaces

Setup & Run Projects Locally (Installation)

Clone repository with submodules

git clone --recurse-submodules https://github.com/panagiotis-bellias-it21871/reference-letters-system.git
cd reference-letters-system

For Python FastAPI project see here and for JavaScript VueJS project see here

Deploy fastapi and vuejs projects to a VM (Virtual Machine)

We are going to need 3 VMs. One for the jenkins server and one for each execution environment (docker and kubernetes)

CI/CD tool configuration (Jenkins Server)

Make sure service is running

sudo systemctl status jenkins
netstat -anlp | grep 8080 # needs package net-tools

http://PUBLIC-IP:8080/

Step 1: Configure Shell

Go to Dashboard / Manage Jenkins / Configure System / Shell / Shell Executable and type '/bin/bash'

Step 2: Add webhooks to system repository

Dublicate repositories for easier configuration.

Step 3: Add the credentials needed

# ID                            What is the value?
app-db-user                     The backend database user
app-db-pass                     The password for the above user
app-db-name                     The database we have for the backend functionality
auth-secret                     The authentication secret that backend is using
mail-username                   Mail account's username
mail-password                   Mail account's app password
mail-from                       Mail account address
mail-port                       Mail account's server port (e.g. 587 for gmail)
mail-server                     Mail account's provider (e.g. smtp.gmail.com for gmail-google)
mail-from-name                  Mail account's name
base-endpoint-prefix            REST API's base prefix
rl-letters-endpoint             REST API's base endpoint for reference letters requests
auth-endpoint-prefix            REST API's prefix for authentication routes
auth-login-endpoint             REST API's signin endpoint
docker-db-url                   The database url where our postgres db is running using docker
docker-backend-url              The url where backend application is running in docker
docker-username                 The username we have in the container registry we use to push images
docker-push-secret              The secret we have in the container registry we use to push images
docker-container-registry       The container registry you use (e.g. ghcr.io for Github Container Registry). If you use DockerHub, create it with value 'https://index.docker.io/v1/'
docker-backend-prefix-image     The docker image name for the backend application
docker-frontend-prefix-image    The docker image name for the frontend application
k8s-db-url                      The database url where our postgres db is running using kubernetes
k8s-backend-url                 The url where backend application is running in kubernetes

Create Job

In the job the pipeline will be the fastapi.vue.Jenkinsfile

Build stage

Takes the code from the git repository and its submodules

MANUALLY

Ansible Prerequisites stage
sudo su
sudo apt update
sudo apt install software-properties-common
sudo add-apt-repository --yes --update ppa:ansible/ansible
sudo apt install ansible
ansible-galaxy collection install community.docker

Docker Deployment

Ansible connects to the docker-vm through ssh and runs a playbook that it will define the sensitive parameters and will use docker-compose module to do docker-compose up the containers according to docker-compose.yml

So, to deploy our app we need a docker image updated. So we build the images according to nonroot.Dockerfile and Dockerfile, we are logging in Github Container Registry (we will talk about it later) and push the image there to be public available.

Kubernetes Deployment

After we have configure connection between jenkins user and our k8s cluster, we update secrets and configmaps using also some Ansible to populate ~/.env values and create all the needed entities such as persistent volume claims, deployments, cluster IPs, ingress, services.

Secrets and ConfigMaps could be just prepared from earlier. This is applied to the https ingress, we will see later in SSL configuration

Deployment with Docker and docker-compose using Ansible

In order to be able to use Ansible for automation, there is the ansible-reference-letter-project. There is installation and usage guide.

Now, In order to deploy our project in Docker environment, we use a playbook that uses an Ansible role to run the application with docker-compose according to the docker-compose.yml. In that file, we have defined three services, the postgres container with its volume in order to be able to store data, the fastapi container and the vuejs container for our system taking environmental variables from local .env files (it's ready when we run the playbook from jenkins-server where the sensitive values from environmental variables are parametric). The fastapi container is built according to the nonroot.Dockerfile as a nonroot process for safety reasons. The vuejs container is built according to the Dockerfile.

For the HTTPS part we will talk about later.

Deployment with Kubernetes using a piece of Ansible

In order to deploy our project in Kubernetes cluster, we first need to connect to that VM so as to configure a better connection between local PC or jenkins server and deployment vm's:

echo "alias k='microk8s.kubectl' " >> ~/.bashrc

The permanent alias will be applied only if you reconnect to your VM.

Cluster Configuration & Enable Addons

sudo usermod -a -G microk8s <your-username>
sudo chown -f -R <your-username> ~/.kube
microk8s enable dns dashboard hostpath-storage ingress
microk8s status

Connect Kubernetes Cluster with Local PC or/and Jenkins server

# VM's terminal
k config view --raw > kube-config
cat kube-config

# Local terminal
mkdir ~/.kube
scp <vm-name>:/home/<vm-username>/kube-config ~/.kube/config

Edit ~/.kube/config to replace the 127.0.0.1 with the VM's public ip and the certificate line in clusters section with the below line (not used this way in a real production environment)

insecure-skip-tls-verify: true
  • Don't forget to add a firewall rule for the port specified in the ~/.kube/config file With
kubectl get pods

you can ensure that the connection is established.

If you use CI/CD tool and mostly Jenkins do the following (for better deployment fork the repository to be able to change code where needed):

# Jenkins terminal
sudo su
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
su jenkins
cd

# Local terminal
scp ~/.kube/config <jenkins-vm-name>:/tmp/config

# Jenkins terminal
mkdir -p .kube
cp /tmp/config ~/.kube/

With

kubectl get pods

you can ensure that the connection is established.

Kubernetes Entities

Either manually or via jenkins server using Jenkinsfile and secret texts the following will do the trick! The code is located in the k8s folder of each project, so every time we must change directory to be located in the correct application folder. The code is in the .yaml format.

  • Don't forget to have the docker images in Github Container Registry because the deployment entities use them. You can follow the logic located in fastapi.vue.Jenkinsfile in the 'Docker Deployment' stage. You must have docker installed in your local machine (or jenkins server)
  • In projects' README.md files you will find information about the docker image each application is dockerized in.
# Secret (for the postgresql database)
kubectl create secret generic pg-users \
--from-literal=PGUSER=<put user name here> \
--from-literal=PGPASSWORD=<put password here> \
--from-literal=FAUSER=<put backend username here> \
--from-literal=FAPASSWORD=<put backend password here> \
--from-literal=FADBNAME=<put backend database name here>

# Continue from here
cd reference-letters-fastapi-server

# Config Map (for .env variables)
cp ref_letters/.env.k8s.example ref_letters/.env
nano ref_letters/.env # change to the correct values
kubectl create configmap fastapi-config --from-env-file=ref_letters/.env

cd k8s
# Persistent Volume Claim
kubectl apply -f db/postgres-pvc.yaml
# Postgres Deployment
kubectl apply -f db/postgres-deployment.yaml
# Postgres Initialization
kubectl get pods
kubectl exec -it <POD-NAME> -- psql -h localhost -U postgres -p 5432 < ../../assets/init_db/*
# FastAPI Deployment
kubectl apply -f fastapi/fastapi-deployment.yaml
# Services (Cluster IPs)
kubectl apply -f db/postgres-clip.yaml
kubectl apply -f fastapi/fastapi-clip.yaml

cd ../..
cd reference-letters-vuejs-client

# Config Map (for .env variables)
cp .env.k8s.example .env
nano .env # change to the correct values
kubectl create configmap vuejs-config --from-env-file=.env

cd k8s
# Deployments
kubectl apply -f vuejs/vuejs-deployment.yaml
# Services (Cluster IPs)
kubectl apply -f vuejs/vuejs-clip.yaml
# Ingress (For just HTTP - Edit file changing host to your own dns name)
kubectl apply -f vuejs/vuejs-ingress.yaml

To change to the correct values the .env file we use some Ansible running this playbook. This is also used by Jenkins server and Jenkinsfile. See more here. *

About

A web system about reference letter handling in the context of DIT HUA Thesis "Use of devops methodologies and tools in development and production environment of web applications"

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages