Building a multi-tier web application.

John Edward Szwec
Nerd For Tech
Published in
11 min readJul 14, 2023

The purpose of this project is to create a multi-tier web-application

This is my first documented project on this platform.
It is the first project from Imran Teli’s Udemy course titled:
“20 Real Time DevOps Projects”

For this project, I will build a multi tier web application which hosts a social networking application.

This is a chart of the project to be built:

Before I start let’s define what exactly a web application is?

A web application is a software application that is accessed via a web browser. The applications are delivered to end users usually across the WWW (World Wide Web). They are used to provide services or perform tasks. Some common examples of web applications are: email clients like Gmail and Outlook and social media platforms such as Facebook and Twitter.

A multi-tier web application also known as a multi layered architecture is the way in which the tiers of a web application are segmented.
There are three tiers or layers:
* Presentation tier, Frontend—user interface layer.
* Application Tier — business logic
* Data Tier — data is stored and retrieved.

The main benefits of a three tier application are
Scalability — Each tier can be scaled independently.
Reliability — enhances the applications resiliency.
Security — Separation of data between tiers

In comparison to a three tier application, there are also single and two tiered applications.

  • Single tier architecture:
    All the layers (Presentation Tier; Application tier and Data Tier) reside in the same server. This means the user directly interacts with the data.
  • Two tier architecture:
    This is an architecture where the presentation layer runs on the client (i.e., the user’s computer), and the data layer is on the server side. The application tier can either reside on the server or on the client. The most common example is a client-server application where the client communicates directly with the server.

In this project the servers will be built manually.

This Application stack will be built locally on my Windows 10 laptop and will be comprised of 5 virtual servers hosted on Oracle Virtual BOX. This stack will also serve as a baseline for upcoming projects.
Although the virtual servers will be installed with an automation tool called ‘vagrant’ , the servers will all be built manually.

The virtual servers will be built using an application called “Vagrant”. Vagrant is an open-source tool that simplifies the creation and management of virtual development environments. It provides a way to automate the setup and configuration of virtual machines (VMs) for different projects, making it easier to maintain consistent and reproducible development environments across different machines and operating systems.

<<< Location of the source code used for the project. >>> https://github.com/devopshydclub/vprofile-project.

PREREQUISTIES FOR THE PROJECT

  1. Tools, accounts and technologies that I have pre-installed and configured which are required to replicate the project.
  • Oracle VM VirtualBox — virtualization software that allows creation and launching of virtual machines
  • Git Bash — a command-line interface (CLI) program which provides a Unix-like environment on Windows systems. Primarily used for executing Git commands.
  • Vagrant — A tool to create and manage virtual development environments.
  • Chocolatey— A package manager for Windows operating systems that automates the installation, configuration, and management of software packages
  • JDK 8 (Java Development Kit 8)
  • Maven — A build automation and project management tool used primarily for Java-based projects
  • IntelliJ — IntelliJ IDEA (commonly referred to as IntelliJ) is an integrated development environment (IDE) designed specifically for Java development.
  • Sublime Text— Text / code editor
  • AWS CLI — Command Line Tool, used to interact with Amazon Web Services

2. Signed up and created for accounts for the following

  • GitHub
  • My own registered WEB domain
  • Docker Hub
  • SonarCloud

3. On an Amazon AWS account the following is needed.

  • An IAM account with MFA configured
  • A billing alarm configured
  • Certificate setup

** Not all of the tools list above are used in this first project but will be throughout the entire course

Overview of the steps to complete the project

  • Clone the repository in the link above to my local Windows laptop.
  • Build the 5 virtual servers on the Oracle VBOX with Vagrant.
  • Configure the five servers.
  • Test the application works as designed.

The five virtual machines built by Vagrant are:

NGINX — Ubuntu Linux
Tomcat — CentOS
RabbitMQ —Message Queue Server / Linux — CentOS
Memcached — CentOS
MySQL — CentOS

BEGIN: Detailed steps to setup and configure each of the 5 new servers:

At this point the repository has been cloned to my local Windows 10 laptop and the 5 VMs have been setup on the Oracle VBOX using vagrant. I am starting the documentation at the third step in the overview: Configuring the 5 servers.

Configuring the 5 Servers

  1. MySQL server.
  • The following steps installs, starts and secures the MYSQL database on the CentOS Linux server.
    These commands are run one at time on the new MySQL DB server.
Update OS with latest patches
# yum update -y

Set Repository
# yum install epel-release -y

Install Maria DB Package
# yum install git mariadb-server -y

Starting & enabling mariadb-server
# systemctl start mariadb
# systemctl enable mariadb

RUN mysql secure installation script.
# mysql_secure_installation

## The mysql_secure_installation is a script or a command
## created by the Mariadb or MySQL. It will ask you
## a series of questions to secure the database.

The code block below does the following steps

  • Set DB name and users
    Creates a database named ‘accounts’ on the new MYSQL DB instance.
    Then creates a database admin account and grants that account full privileges' to the new database.
    Download Source code & Initialize Database.
Set DB name and users.
# mysql -u root -padmin123
mysql> create database accounts;
mysql> grant all privileges on accounts.* TO 'admin'@'%' identified by 'admin123' ;
mysql> FLUSH PRIVILEGES;
mysql> exit;
  • Download Source code initialize Database.
    Clones the GitHub repository to the server then imports a backup of a preconfigured database to our new ‘accounts’ database.
Download Source code & Initialize Database.
# git clone -b local-setup https://github.com/devopshydclub/vprofile-project.git
# cd vprofile-project
# mysql -u root -padmin123 accounts < src/main/resources/db_backup.sql
# mysql -u root -padmin123 accounts
mysql> show tables;
  • Restart the MariaDB service on the server
Restart mariadb-server
# systemctl restart mariadb
  • Lastly, we configure the firewall and allow access on port 3306
Starting the firewall and allowing the mariadb to access from port no. 3306
# systemctl start firewalld
# systemctl enable firewalld
# firewall-cmd --get-active-zones
# firewall-cmd --zone=public --add-port=3306/tcp --permanent
# firewall-cmd --reload
# systemctl restart mariadb

2. Memcached server.

  • The following commands install the Memcached service.
Install, start & enable memcache on port 11211
#yum install epel-release -y
#yum install memcached -y
#systemctl start memcached
#systemctl enable memcached
#systemctl status memcached
#memcached -p 11211 -U 11111 -u memcached -d
  • The firewall is then configured to allow connections to the Memcached service on port TCP port 11211
Starting the firewall and allowing the port 11211 to access memcache
# systemctl enable firewalld
# systemctl start firewalld
# systemctl status firewalld
# firewall-cmd --add-port=11211/tcp --permanent
# firewall-cmd --reload
# memcached -p 11211 -U 11111 -u memcache -d

3. RabbitMQ — Message Queue Service

  • Install the Extra Packages for Enterprise Linux (EPEL) Repository
    EPEL repositories are a collection of additional packages that are not included in the default set of repositories that come with distributions like CentOS, Red Hat Enterprise Linux (RHEL), and Scientific Linux. These packages offer extra features and utilities.
Set EPEL Repository
# yum install epel-release -y
  • Install Dependencies
    Erlang — A general-purpose, concurrent, functional programming language and runtime environment.
    Socat — A command-line tool that can be used to create bidirectional byte streams between two addresses. The addresses can be files, sockets, or other types of data sources
Install Dependencies
#sudo yum install wget -y
#cd /tmp/
#wget http://packages.erlang-solutions.com/erlang-solutions-2.0-1.noarch.rpm
#sudo rpm -Uvh erlang-solutions-2.0-1.noarch.rpm
#sudo yum -y install erlang socat
  • Install RabbitMQ server
    Download and install the RabbitMQ package.
Install Rabbitmq Server
#curl -s https://packagecloud.io/install/repositories/rabbitmq/rabbitmq-server/script.rpm.sh | sudo bash
#sudo yum install rabbitmq-server -y

Start & Enable RabbitMQ
#sudo systemctl start rabbitmq-server
#sudo systemctl enable rabbitmq-server
#sudo systemctl status rabbitmq-server
  • Config Change
    The first command in this section enables users to access the server remotely, the [] means that no users are allowed to access RabbitMQ from the local machine.
    Add a RabbitMQ user and set a tag on that user to Administrator.
Config Change
#sudo sh -c 'echo "[{rabbit, [{loopback_users, []}]}]." > /etc/rabbitmq/rabbitmq.config'
#sudo rabbitmqctl add_user test test
#sudo rabbitmqctl set_user_tags test administrator

Restart RabbitMQ service
# systemctl restart rabbitmq-server
  • Enabling the firewall and configuring it to allow port 25672
Enabling the firewall and allowing port 25672 to access the rabbitmq permanently
# systemctl start firewalld
# systemctl enable firewalld
# firewall-cmd --get-active-zones
# firewall-cmd --zone=public --add-port=25672/tcp --permanent
# firewall-cmd --reload

4. Tomcat- Application Server

  • Install Dependencies
    JAVA-JDK; Apache Tomcat is a Java-based web server and servlet container, which means it requires the Java Development Kit (JDK) to run. This is because Tomcat uses Java Servlet, JavaServer Pages (JSP), Java Expression Language, and Java WebSocket technologies, all of which require Java to function.
    Git — used to clone the source code for the project.
    Maven is a popular open-source tool that is used to build and manage Java projects.
Install Dependencies
# yum install java-1.8.0-openjdk -y
# yum install git maven wget -y
  • Download & install Tomcat
Change dir to /tmp
# cd /tmp/

Download & Tomcat Package
# wget https://archive.apache.org/dist/tomcat/tomcat-8/v8.5.37/bin/apache-tomcat-8.5.37.tar.gz
# tar xzvf apache-tomcat-8.5.37.tar.gz
  • Add a Tomcat user and copy the tomcat package to the tomcat user home directory
    This user will be used by the Tomcat process, therefore it will not require a login shell.
Add tomcat user
# useradd --home-dir /usr/local/tomcat8 --shell /sbin/nologin tomcat
Copy data to tomcat home dir
# cp -r /tmp/apache-tomcat-8.5.37/* /usr/local/tomcat8/
  • Make the tomcat user owner of the tomcat home directory
Make tomcat user owner of tomcat home dir
# chown -R tomcat.tomcat /usr/local/tomcat8
  • Setup systemd for Tomcat. Create a tomcat.service file.
vi /etc/systemd/system/tomcat.service
  • Add the following code to that file and save it.
[Unit]
Description=Tomcat
After=network.target

[Service]
User=tomcat
WorkingDirectory=/usr/local/tomcat8
Environment=JRE_HOME=/usr/lib/jvm/jre
Environment=JAVA_HOME=/usr/lib/jvm/jre
Environment=CATALINA_HOME=/usr/local/tomcat8
Environment=CATALINE_BASE=/usr/local/tomcat8
ExecStart=/usr/local/tomcat8/bin/catalina.sh run
ExecStop=/usr/local/tomcat8/bin/shutdown.sh
SyslogIdentifier=tomcat-%i

[Install]
WantedBy=multi-user.target
  • Run the following set of commands to reload the systemd configuration files and update the systemd service definitions. Then start tomcat.
# systemctl daemon-reload
# systemctl start tomcat
# systemctl enable tomcat
  • Enable the firewall and allow port 8080 to access the tomcat service.
# systemctl start firewalld
# systemctl enable firewalld
# firewall-cmd --get-active-zones
# firewall-cmd --zone=public --add-port=8080/tcp --permanent
# firewall-cmd --reload
  • Code Build and Deploy the Tomcat — Application Server.
    Download Source Code- this is the actual application code written by the application developers which will be used for our social-networking application on this project. — -We run the clone command from the /tmp/ directory.
Download Source code
# git clone -b local-setup https://github.com/devopshydclub/vprofile-project.git
  • Open for editing the application.properties file located in the /src/main/resources/ folder to reflect the correct settings.
Update configuration
# cd vprofile-project
# vim src/main/resources/application.properties
# Update file with backend server details
  • The application.properties file contains the backend service information.
#JDBC Configutation for Database Connection
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://db01:3306/accounts?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull
jdbc.username=admin
jdbc.password=admin123

#Memcached Configuration For Active and StandBy Host
#For Active Host
memcached.active.host=mc01
memcached.active.port=11211
#For StandBy Host
memcached.standBy.host=127.0.0.2
memcached.standBy.port=11211

#RabbitMq Configuration
rabbitmq.address=rmq01
rabbitmq.port=5672
rabbitmq.username=test
rabbitmq.password=test

#Elasticesearch Configuration
elasticsearch.host =192.168.1.85
elasticsearch.port =9300
elasticsearch.cluster=vprofile
elasticsearch.node=vprofilenode
  • Now we run the # mvn install command. This command is part of the standard Maven lifecycle, which includes phases like validate, compile, test, package, verify, install, and deploy.
Build code
Run below command inside the repository (vprofile-project)
# mvn install
  • Then we deploy our artifact. To do this we will remove the default application and replace it with the artifact we just created in previous steps. Then restart the tomcat service to bring up the service with our new application as default.
Deploy artifact
# systemctl stop tomcat
# sleep 120
# rm -rf /usr/local/tomcat8/webapps/ROOT*
# cp target/vprofile-v2.war /usr/local/tomcat8/webapps/ROOT.war
# systemctl start tomcat
# sleep 300

# chown tomcat.tomcat usr/local/tomcat8/webapps -R
# systemctl restart tomcat

5. NGINX setup

  • Update and Upgrade the NGINX server
Update OS with latest patches
# apt update && apt upgrade -y
  • Install the NGINX application.
apt install nginx -y
  • Create the NGINX config file.
# vi /etc/nginx/sites-available/vproapp
  • Add the following contents to the config file.
upstream vproapp {
server app01:8080;
}
server {
listen 80;
location / {
proxy_pass http://vproapp;
}
}
  • Remove the default NGINX config file.
# rm -rf /etc/nginx/sites-enabled/default
  • Create a link to activate the website.
# ln -s /etc/nginx/sites-available/vproapp /etc/nginx/sites-enabled/vproapp
  • Restart the NGINX application.
# systemctl restart nginx

Validating the Application

To do this I retrieved the IP address from the NGINX Web Server and pasted that IP address in my browser on the Windows 10 Laptop.
And I am presented with the application login page.
This login page is being presented by the tomcat application server so at this point we know the NGINX Web Server is successfully routing the traffic to the Tomcat server.

Now I am logged into the application. Since the login details are stored in the database this proves the database is functioning as designed.

In order to check if the RabbitMQ server is functioning I click on the RabbitMQ button

The results page shows some queue generated which proves we have a connection to RabbitMQ. If it fails here that means there is a problem with RabbitMQ.

In order to verify the Memcached server is functioning I click the All Users button.

Then click on any user at random.

The subsequent page shows a message that the user data was retrieved and inserted into the cache.

If I then go back a page on the browser and then click the same user again, the message states the data was now retrieved from cache

And there we have it. I hope you have found this useful. Thank you for reading.

Please feel free to contact me on LinkedIN questions or suggestions. https://www.linkedin.com/in/john-szwec/

--

--