Multi Tier Web Application Stack Setup Locally

Oluwatobiloba Adu
11 min readJan 29, 2023

--

Vprofile-Project1:

Project Source: DevOps Project by Imran Teli

GitHub Repo: vprofile-project

Prerequisite

To complete this project you should have your lab set-up with the appropriate tools.

  • Git Bash or any Code editor of choice
  • Oracle VirtualBox
  • Install Vagrant, and Vagrant Plugins.

Firstly We Set-up our VMs

Clone the project repository to your local environment (using gitbash)

git clone git@github.com:Adutoby/vprofile-project.git

cd to the directory that has the Vagrantfile and run below command to start the VM via vagrant.

Vagrant up

You might need to install vagrant plugins host-manger , run below command if you encounter errors while your VMs are coming up and run the Vagrant up command again

vagrant plugin install vagrant-hostmanager
vagrant up

It is important to note that bringing up the VMs will take sometime depending on your internet speed. If setup process stops, run vagrant up command again until all 5 VMs are up and running.

INFO: All the vm’s hostname and /etc/hosts file entries will be automatically updated

Check your Oracle Virtual-box Manager UI to see the VM’s setup and state running.

With all the VM’s now setup, lets validate via ssh into the VM’s starting with the web server named web01. Run command..

vagrant ssh web01

We are now inside the web server. Next, let us Check the host to validate all were automatically updated by running the cat command to view the content in in the /etc/hosts file

cat /etc/hosts

Great, now ping the app server to confirm connectivity and communication

ping app01

Connectivity was successful, logout of the web01 server and connect to the app01 server and check connectivity to the database VM db01, the memcache VM mc01 and the rabbitMQ VM respectively rmq01 since the application server will be communication directly with all 3 servers (VMs)

logout
vagrant ssh app01

app01 connects to db01 successfully i.e we have connectivity between the application server and the database server

same for app server and Memcache server mc01 and finally checking connectivity between app01 and queuing agent RabbitMQ server rmq01 was also successful.

Provisioning the VMs

The next stage will be to provision the servers manually and there are 6 different services that I will be provisioning in project architecture.

Services
1. Nginx: Web Service
2. Tomcat: Application Server
3. RabbitMQ; Broker/Queuing Agent
4. Memcache; DB Caching
5. ElasticSearch; Indexing/Search service
6. MySQL; SQL Database

Project Architecture

The Setup for the service will be done in below order staring from setting up the Database service down to the Web service accordingly.
1. MySQL (Database SVC)
2. Memcache (DB Caching SVC)
3. RabbitMQ (Broker/Queue SVC)
4. Tomcat (Application SVC)
5. Nginx (Web SVC)

Provisioning Database SVC — MySQL setup

ssh into the db01

vagrant ssh db01

Switch to root user and update all packages to latest patches when logged into the VM. Also set repository by installing EPEL Extra Packages for Enterprise Linux)

sudo -i
yum update -y
yum install epel-release -y

Set up db password using DATABASE_PASS environment variable and add it to /etc/profile file by running;

DATABASE_PASS='admin123'

To save the variable permanently, add the variable to/etc/profile file and update it using a text editor of choice. I used vim so i install vim using yum install vim command first and then below scripts

vim /etc/profile
source /etc/profile

Next is to install Maria DB and git Package

yum install git mariadb-server -y

Once Mariadb is installed, start and enable mariadb service. Also ensure to check the status of mariadb service to make sure it’s active (running).

systemctl start mariadb
systemctl enable mariadb
systemctl status mariadb

RUN mysql secure installation script.

mysql_secure_installation

For db root password, I used admin123

Validate connectivity to db with command below: at the password prompt enter admin123 . If connection is succesful exit from DB.

mysql -u root -p
exit

I proceeded to clone source code to db VM, change directory to src/main/resources/ to get the `sql queries.

git clone https://github.com/devopshydclub/vprofile-project.git
cd vprofile-project/src/main/resources/

Create a database account, Configure the db and initialize

mysql -u root -p"$DATABASE_PASS" -e "create database accounts"
mysql -u root -p"$DATABASE_PASS" -e "grant all privileges on accounts.* TO 'admin'@'app01' identified by 'admin123' "
cd ../../..
mysql -u root -p"$DATABASE_PASS" accounts < src/main/resources/db_backup.sql
mysql -u root -p"$DATABASE_PASS" -e "FLUSH PRIVILEGES"

Login to the database and verify

Restart Mariadb server and logout, db is provisioned and ready

systemctl restart mariadb
exit

Provisioning (DB Caching SVC) Memcache setup

following the flow of service provisioning highlighted above we will log-in to memcached server, (mc01) and switch to root user with below commands

vagrant ssh mc01
sudo -i

Just as MySQL provisioning, update OS with latest patches and download epel repository.

yum update -y
yum install epel-release -y

Install memcached package.

yum install memcached -y

Start/enable the memcached service and check the status of service.

systemctl start memcached
systemctl enable memcached
systemctl status memcached

To enable memcached to listen on TCP port 11211 and UDP port 11111 run below command.

memcached -p 11211 -U 11111 -u memcached -d

To Validate if the port is running, run command

ss -tunlp | grep 11211

The Caching server is provisioned and ready, exit from server and continue to the next flow setup.

Provisioning RabbitMQ

RabbitMQ is used as the queuing agent in the stack for a application. To begin the setup we login into Rabbit MQ server (rmq01) and switch to root user.

vagrant ssh rmq01
sudo -i

Updating OS with latest patches and install epel repository.

yum update -y
yum install epel-release -y

To install RabbitMQ, there are dependencies that should be installed first such a wget and erlang-solutions. Run below command to set those up.

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

Next Install RabbitMQ server with command below

curl -s https://packagecloud.io/install/repositories/rabbitmq/rabbitmq-server/script.rpm.sh | sudo bash
sudo yum install rabbitmq-server -y

Now start/enable the RabbitMQ service and check the status of service.

systemctl start rabbitmq-server
systemctl enable rabbitmq-server
systemctl status rabbitmq-server

Set up a config change to Create a test user with password test, Create user_tag for the test user as administrator .

Restart rabbitmq service after config change completion

cd
echo "[{rabbit, [{loopback_users, []}]}]." > /etc/rabbitmq/rabbitmq.config
rabbitmqctl add_user test test
rabbitmqctl set_user_tags test administrator
systemctl restart rabbitmq-server

Validate service is active/running after restart

systemctl status rabbitmq-server

Great!, exit rmq01 server to the next service.

Tomcat Setup (Application SVC)

With vagrant, log into app01 server , and switch to root user.

vagrant ssh app01
sudo -i

As per best practice, Update OS with latest patches and download epel repository.

yum update -y
yum install epel-release -y

Install dependencies for Tomcat server. (git, wget, maven, java-1.8.0-openjdk)

yum install java-1.8.0-openjdk -y
yum install git maven wget -y

(change directory) cd to /tmp/ directory, and download Tomcat.

cd /tmp
wget https://archive.apache.org/dist/tomcat/tomcat-8/v8.5.37/bin/apache-tomcat-8.5.37.tar.
tar xzvf apache-tomcat-8.5.37.tar.gz

Add tomcat user and copy data to tomcat home directory.

Check the new user tomcat with id tomcat command.

useradd --home-dir /usr/local/tomcat8 --shell /sbin/nologin tomcat

Copy your data to /usr/local/tomcat8 directory which is the home-directory for tomcat user.

cp -r /tmp/apache-tomcat-8.5.37/* /usr/local/tomcat8/

Observe that root user has ownership of all files under /usr/local/tomcat8/ directory, change it to tomcat user.

ls -l /usr/local/tomcat8/
chown -R tomcat.tomcat /usr/local/tomcat8
ls -l /usr/local/tomcat8/

Setup systemd for tomcat

Create a file with below content. once created, Use systemctl start tomcat to start tomcat and systemctl stop tomcat to stop tomcat service.

[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

Any changes made to file under /etc/systemd/system/ directory, we need to run below command to be effective and Enable tomcat service.

The service name tomcat has to be same as given /etc/systemd/system/tomcat.service .

systemctl daemon-reload
systemctl enable tomcat
systemctl start tomcat
systemctl status tomcat

Code Build & Deploy to Tomcat(app01) Server

Clone the source code into the /tmp directory, then cd into the vproject-project directory.

git clone https://github.com/devopshydclub/vprofile-project.git
cd vprofile-project/

To build the artifact with maven, we need to Update the configuration file that connect the backen services i.e, db, memcaches and the queuing agent rabbitMQ service.

This is done by editing the application.properties file in the /src/main/resources/application.properties file using a text editor of your choice. I sued vim.

vim src/main/resources/application.properties

In application.properties file:

Ensure the settings are correct. Check DB configuration: we named the db server db01 , and we have admin user with password admin123 setup as credentials.

For memcached service, hostname is mc01 and we validated it is listening on tcp port 11211.

For rabbitMQ, hostname is rmq01 and we have created user test with pwd test.

#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

Next we build our code with maven using mvn install command to creat our artifact.Run below command inside the repository (vprofile-project). An Artifact will be created /tmp/vprofile-project/target/vprofile-v2.war

cd target/
ls

cd to target and list to see the artifact, remove the default app from the Tomcat server and deploy the newly built artifact vprofile-v2.var to the Tomcat server

Ensure to stop the server first before removing the default from the /usr/local/tomcat8/webapps/ROOT directory. Give about 120seconds allowing the server to stop properly . use these command

systemctl stop tomcat
systemctl status tomcat
rm -rf /usr/local/tomcat8/webapps/ROOT

With our artifact is the vprofile-project/target directory, copy the artifact to /usr/local/tomcat8/webapps/ directory as ROOT.war then start tomcat server. Once started, it will extract our artifact ROOT.war under ROOT directory.

cd ..
cp target/vprofile-v2.war /usr/local/tomcat8/webapps/ROOT.war
systemctl start tomcat
ls /usr/local/tomcat8/webapps/

Give the application sometime to come up say around 200secs, whilw this happens we can proceed to set us the nginx server.

Setup Nginx SVC

We used Ubuntu for the Nginx server, while all other servers are CentOs . As usually as per best practice, update OS with latest patches run below command this time using apt package manager:

sudo apt update && sudo apt upgrade

Switch to root user and install nginx.

sudo -i
apt install nginx -y

Next we create an nginx configuration file under directory /etc/nginx/sites-available/. This allows nginx to act as a load balancer with below content:

vim /etc/nginx/sites-available/vproapp


upstream vproapp {
server app01:8080;
}
server {
listen 80;
location / {
proxy_pass http://vproapp;
}
}

Remove default nginx config file:

rm -rf /etc/nginx/sites-enabled/default

Create a symbolic link for our configuration file using default config location detailed below to enable our site and restart nginx server.

ln -s /etc/nginx/sites-available/vproapp /etc/nginx/sites-enabled/vproapp
systemctl restart nginx

Validate Application(stacks) from Browser

From inside of the web01 server, run ifconfig command to display its IP address. IP address of our web01 : 192.168.56.11

Now open a browser and enter the web app IP address to validate nginx is running 192.168.56.11. you should see the login page

Next validate db connection using credentials admin_vp for both username and password. connect successful!! show that app is running from Tomcat server through the web server.

To validate RabbitMQ connection, click RabbitMQ on page and it should return below on display.

To validate Memcache connection, click on All user button on the front page to load all users and them click on any user

Validate data is coming from Database when user first time requests it.

Validate data is coming from Memcached when user second time requests it.

Great Job making it this far, we have successfully setup tools for our stack , clone the source code , via vagrant we brought up our VM’s and validated them , we successfully setup all our services Mysql, Memcached, Rabbit MQ, Tomcat Nginx and built and deployed them and finally we have validated to see all work perfectly.

The exercise might seems time consuming but it helps to understand granularity of how to provision the aforementioned and their interaction, communication flow and they are interconnected. My next project will show how to automate this entire process using script

Cleanup

Navigate to the project directory in manual provisioning directory where the vagrant file is contained, run the command Vagrant destroy to bring down all virtual machines. The exercise might seems time consuming but it helps to understand granularity of how to provision the aforementioned and their interaction, communication flow and they are interconnected. My next project will show how to automate this entire process using script

vagrant destroy

Thank you for reading, your comment and reaction on how to better improve the stack will be appreciated and look out for next project automating the process. I can reached on LinkedIn HERE .

Project reference : Udemy

--

--