☁️ Day 28 of #90DaysOfCloud: Deploying a 3-Tier PHP Registration App on AWS with NGINX & RDS

Pratik DasPratik Das
5 min read

Today marks a milestone in my #90DaysOfCloud challenge, as I successfully built and deployed a 3-tier web application architecture on AWS, designed with best practices for security, modularity, and scalability. This blog details every major configuration β€” from VPC and subnets, through security controls, to the deployment of a PHP registration app β€” with NGINX as a reverse proxy and MariaDB RDS as persistent storage.

🧱 What Is a 3-Tier Architecture?

A 3-tier architecture separates the application into:

  • Presentation Layer – NGINX Reverse Proxy (public subnet)

  • Application Layer – PHP App Server (private subnet)

  • Data Layer – Amazon RDS (private subnet)

This pattern improves security, scalability, and manageability.


πŸ–₯️ Project Summary

ComponentAWS ResourceSubnet
Reverse ProxyNGINX on EC2Public Subnet
App ServerPHP on EC2Private Subnet 1
DatabaseAmazon RDS (MariaDB)Private Subnet 2

🧱 Architecture Overview

A robust three-tier architecture separates presentation, application logic, and database into isolated network layers for improved security.

text           Internet
               β”‚
         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
         β”‚   Proxy     β”‚  ← Public Subnet (10.0.1.0/24)
         β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
              β”‚ (HTTP)
         β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”
         β”‚  App EC2 β”‚  ← Private Subnet (10.0.2.0/24)
         β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜
              β”‚ (3306)
         β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”
         β”‚   RDS    β”‚  ← Private Subnet (10.0.3.0/24)
         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
  • Presentation Layer: NGINX reverse proxy (public subnet)

  • Application Layer: PHP app (private subnet)

  • Database Layer: MariaDB on RDS (private subnet)

🧐 Why 3-Tier Architecture?

  • Security: Only the proxy is exposed to the internet, the app and DB are shielded.

  • Scalability: Each layer can scale independently.

  • Maintainability: Easier to debug and maintain.

πŸ—οΈ Full Step-by-Step Setup Guide

1️⃣ Create VPC and Subnets

VPC

  • Name: 3TierVPC

  • IPv4 CIDR block: 10.0.0.0/16

Subnets

  • Public Subnet (Proxy) – 10.0.1.0/24

  • Private Subnet 1 (App) – 10.0.2.0/24

  • Private Subnet 2 (DB) – 10.0.3.0/24

2️⃣ Internet Gateway & Routing

  • Create IGW, attach to 3TierVPC

  • Public Route Table:

    • Destination: 0.0.0.0/0 β†’ IGW

    • Associate with Public Subnet only

  • Private Route Table:

    • No route to IGW (private only), used for both private subnets

3️⃣ Security Groups

Security GroupInbound RulesOutbound Rules
Proxy SGTCP 22 from <your-IP>

TCP 80 from 0.0.0.0/0 | All allowed (default) | | App SG | TCP 22 from <your-IP>
TCP 80 from Proxy SG | All allowed (default) | | DB SG | TCP 3306 from App SG | All allowed (default) |

πŸš€ Launch EC2 Instances

Proxy Server (Public Subnet) – NGINX Reverse Proxy

AMI: Amazon Linux 2

Install NGINX

sudo yum update -y
sudo amazon-linux-extras install nginx1 -y
sudo systemctl enable nginx
sudo systemctl start nginx

Configure NGINX as Reverse Proxy

Edit or create a new server block (/etc/nginx/conf.d/reverse-proxy.conf):

textserver {
    listen 80;
    server_name _;

    location / {
        proxy_pass http://<App-Server-Private-IP>;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Replace <App-Server-Private-IP> with your actual app EC2 private IP.

Restart NGINX:

sudo systemctl restart nginx

App Server (Private Subnet) – PHP Application

AMI: Amazon Linux 2

Install Apache, PHP, and MySQL client

sudo yum update -y
sudo yum install -y httpd php php-mysqlnd mysql
sudo systemctl enable httpd
sudo systemctl start httpd

Deploy PHP App Files

Upload via SCP to the proxy, then to app server:

# Upload from your local machine to proxy
scp -i your-key.pem *.php ec2-user@<Proxy-Public-IP>:/home/ec2-user/

# SSH into app server (through the proxy, if needed), then:
sudo mv *.php /var/www/html/

Configure RDS Credentials (config.php)

php<?php
$mysqli = new mysqli("your-rds-endpoint", "appuser", "password", "myappdb");
if ($mysqli->connect_error) {
    die("Connection failed: " . $mysqli->connect_error);
}
?>

πŸ›’οΈ Amazon RDS (MariaDB)

  • Create DB Subnet Group: Add both private subnets for high availability

  • Launch RDS:

    • Engine: MariaDB

    • DB Name: myappdb

    • Username: appuser

    • Password: your_password

    • VPC: 3TierVPC

    • Subnet group: DB subnet group

    • Public access: No

    • Security group: DB SG

Once created, note the endpoint for your app server’s config.

Create Table:

sqlmysql -h <rds-endpoint> -u appuser -p

CREATE TABLE users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(50),
    email VARCHAR(50),
    password VARCHAR(100)
);

🌐 Access the App

Visit your proxy EC2’s public IP in a browser:

http://<Proxy-Public-IP>

You should see your PHP registration form, and registered users are now saved securely in Amazon RDS.

🧼 Cleanup (To Avoid Charges)

  • Terminate EC2 instances

  • Delete RDS instance

  • Remove VPC and its resources

πŸ“Έ Screenshots

πŸ’‘ Best Practices and Improvements

  • Use SSL & enforce HTTPS: (Free cert with AWS ACM + NGINX config)

  • App Server Outbound Access: Add NAT Gateway if your app server requires outbound internet.

  • Secrets Management: Use AWS Secrets Manager for DB credentials, not hardcoded.

  • Backups & Availability: Enable automatic RDS backups and consider Multi-AZ deployment.

  • Monitoring: Use CloudWatch for logging and performance alerts.

🧭 What’s Next?

Tomorrow, I’ll begin building a production-ready 3-tier architecture for a Java web application using Tomcat on AWS.

πŸ”§ The plan:

  • Set up NGINX as a reverse proxy in the public subnet

  • Deploy a Java app on Tomcat inside a private subnet

  • Connect to Amazon RDS as the backend database

πŸ“‹ I’ll be sharing:

  • Step-by-step commands

  • All necessary configurations

  • Detailed architecture and networking setup

πŸ”₯ Stay tuned for a hands-on guide to deploying a secure and scalable Java web app on AWS from scratch!

0
Subscribe to my newsletter

Read articles from Pratik Das directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Pratik Das
Pratik Das