Building a unusual 3-tier application for testing

3-tier appThe problem

When dealing with vRealize Automation and NSX it’s very likely that, for testing or learning purpose, you are going to need a three-tier application and so do I.
Personally I’m not an application developer nor a database expert so I thought “Not a problem, let me Google it and I’m sure I’ll find someone who’s done it guiding me through the process step by step”. My requirements were pretty simple:

  1. must use free software
  2. must run 100% on Linux to keep the footprint at minimum
  3. must be simple (KISS principle)

Unfortunately I couldn’t find anything out there matching my requirements.
I’ve asked this question internally to my colleagues, guess what? Someone else had same problem before, not surprisingly.

The solution I’m covering in this post came as an advice from Sam McGweon so here’s my public 

The Solution

So why unusual? Well whenever I think of three layers I think of a back end database, a front end web presentation layer (web server) and a functional process logic layer represented by an application server.
As I can’t write an application myself let’s use an existing one (WordPress) and put in front of it a proxy.
The reverse proxy itself it’s quite a powerful clever tool to reduce load on the web servers, cache content, load balance requests from client as well as prevent direct access to the web servers.
Clients rather than hitting the web server(s) directly they will point to the reverse proxy, which will transparently redirect to the web servers.
In order to achieve this, in my example I firstly installed WordPress with the CNAME record pointing to 192.168.70.62 subsequently I remapped the alias to 192.168.70.61.

NOTE: if you install WordPress pointing the browser to 192.168.70.62 you’ll have that IP address stored everywhere inside the SQL tables and, as a result, you browser will skip the reverse proxy and connect straight to the web server. To avoid this problem point your browser to http://<Webserver-CNAME>/wp-admin/install.php 

In the real life you would expect all the tiers to be on separate subnets with firewall in between (i.e. NSX distributed firewall of Edge Gateway) but in my lab, to keep it simple and get it up and running quickly I kept everything on the same subnet.

“Always start simple, establish the principle and then add complexity later”

All my virtual machines are Linux CentOS 6.6 64 bit. I couldn’t go with version 7 simple because my vCenter Server is still 5.5 which does not support guest OS customisation of CentOS 7.

Common configuration of CentOS

On a clean CentOS 6.6 build I simply added VMware tools and disabled iptables with the following:

service iptables save
service iptables stop
chkconfig iptables off

Database configuration

I’m using MySQL.

yum install mysql
yum install mysql-server
yum install mysql-devel
/usr/bin/mysql_secure_installation

Follow the wizard to setup the root password, remote login and decide if you want a default database pre-populated for you.
Enable the service at start-up

service mysqld start
chkconfig mysqld on

We then need to create the database.
Please note that I did not want to use phpMyAdmin because it would have meant installing Apache and PHP on what was supposed to be just a database server, something conceptually wrong.
Commands I used are:

mysql -u root -p
SELECT User, Host, Password FROM mysql.user;
CREATE DATABASE wordpress;
CREATE USER wp_svc@localhost;
CREATE USER wp_svc@'%';
SET PASSWORD FOR wp_svc@localhost=PASSWORD("Password123");
GRANT ALL PRIVILEGES ON wordpress.* TO wp_svc@localhost IDENTIFIED BY 'Password123';
GRANT ALL PRIVILEGES ON wordpress.* TO 'wp_svc'@'%' IDENTIFIED BY 'Password123';
FLUSH PRIVILEGES;
exit

Optionally, you can bind MySQL to the ip address. Edit the file etc/my.cnf and add the following line

bind_address = 192.168.70.63

Webserver configuration

Install Apache and enable the service at OS start-up

yum install -y httpd
chkconfig --levels 235 httpd on
yum install -y php

Enable PHP support to MySQL

yum install -y php-mysql

Install common modules required my most of CMS (as precaution)

yum -y install php-gd php-imap php-ldap php-odbc php-pear php-xml php-xmlrpc php-mbstring php-mcrypt php-mssql php-snmp php-soap php-tidy curl curl-devel

Download and install WordPress

get http://wordpress.org/latest.tar.gz
tar -xzvf latest.tar.gz
cd wordpress
cp wp-config-sample.php wp-config.php

Edit the file wp-config.php and change the following lines to match your configuration:

define('DB_NAME', 'wordpress');
define('DB_USER', 'wp_svc');
define('DB_PASSWORD', 'Password123');
define('DB_HOST', '192.168.70.63');

Copy the folder over to /var/www/html

cp -r ./wordpress/* /var/www/html

Point your browser to http://<WebServer-FQDN>/wp-admin/install.php and follow the wizard to install WordPress (it’s a two step process).
If everything went smooth you should have your WordPress up and running at this point.

OPTIONALLY: if you want the webserver to respond only to requests coming from the proxy, you can add an iptables rule that allows tcp connectivity only from the proxy, so something like this:

iptables -I INPUT -p tcp -s 192.168.70.61 -j ACCEPT

Reverse Proxy configuration

rmp -UvH https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm
yum install -y nginx
cd etc/nginx/conf.d
mv default.conf default.conf.disabled

Create the file etc/nginx/conf.d/wordpress-proxy.conf and add the following

server {
   listen 80;
   server_name wordpress.dom.local;
   access_log off;
   error_log off;
   location / {
      proxy_pass http://192.168.70.62/;
      proxy_redirect off;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      client_max_body_size 100M;
      client_body_buffer_size 1m;
      proxy_intercept_errors on;
      proxy_buffering on;
      proxy_buffer_size 128k;
      proxy_buffers 256 16k;
      proxy_busy_buffers_size 256k;
      proxy_temp_file_write_size 256k;
      proxy_max_temp_file_size 0;
      proxy_read_timeout 90;
      proxy_send_timeout 90;
   }
}

This config is basically saying “reverse proxy, you are wordpress.dom.local and you’re passing all traffic on port 80 to 192.168.70.62”
Start the service and enable it at start-up

service nginx start
chkconfig nginx on

Lastly change your CNAME (alias) record to point the reverse proxy IP address.

When you point your browser to http://wordpress.dom.local you should hopefully see your WordPress site.

So here you go, you have a 3-tier application you can play with! 🙂

Thanks to CentOS server build I was able to keep resources at very minimum:
Webserver: 1 vCPU, 256MB memory
Reverse proxy: 1 vCPU, 256MB memory
MySQL database: 1 vCPU, 512MB memory

A 3-tier application squeezed into 1GB of RAM, how cool is that ?

Be sociable, share!Tweet about this on TwitterShare on LinkedInShare on FacebookShare on Google+Email this to someone

1 Comment

 Add your comment
  1. Wonderful Information, I would like to add my 10 cents here. One must disable Selinux while building this setup on Centos-7.

Leave a Comment

Your email address will not be published.