Benny Duah
Back to Work
1 min read
Cloud & Infrastructure
Documentation

CloudPress

Next.js
Tailwind CSS
AWS
Terraform
Ansible
Python
Project Overview

Deploy a full production WordPress site on AWS in five minutes, with one click, for less than a managed host charges per month.

1. The Big Picture: What is CloudPress?

Imagine you run an agency or business that needs 10 or 100 WordPress websites. Normally, you have two bad choices:

  1. Pay a Managed Host (like WP Engine, Kinsta, or Hostinger): They charge $30 to $50 per site every month (or lock you into cheap shared hosting where hundreds of sites share the same overloaded CPU). If you have 20 client sites, you are paying $600 to $1,000 every single month to a third party.
  2. Build them manually on AWS: You log into AWS and click through 50 complex web pages, configure networks, create databases, install software over terminal, and copy passwords by hand. It takes 3 hours per site, and if you make one typo, the site gets hacked or goes down.

What CloudPress Does Instead

CloudPress is your own private, automated cloud hosting platform.

It gives you a clean web dashboard (the Control Center). You type in a site name and domain, click "Deploy", and walk away.

Behind the scenes, CloudPress automatically talks to Amazon Web Services (AWS), buys and connects the virtual hardware, installs Ubuntu Linux, configures Nginx, connects a private database, downloads WordPress, locks down all security, and gives you a live, production-grade website in about 5 minutes.

2. Answering Your Question: Is this an actual WordPress site?

### YES. 100% yes.

When you deploy a site in CloudPress:

  • It is not a mockup or a preview.
  • It is not running on your laptop.
  • It is an actual, living, breathing WordPress installation running in AWS's North Virginia datacenter (`us-east-1`).

Here is what is physically created on AWS for every single site you deploy:

  1. Its own private network (VPC) so no other site can peek into its data.
  2. An actual virtual computer (EC2) running Ubuntu Linux 22.04 with an Nginx web server and PHP 8.1.
  3. An actual dedicated database server (Amazon RDS MariaDB/MySQL) running inside a private security zone with its own encrypted password.
  4. An Application Load Balancer (ALB) that handles public traffic and SSL certificates.
  5. A full WordPress installation with its database tables, ready for you to install themes, write blog posts, install WooCommerce, or build client websites.

When you open the Application Load Balancer address (http://cloudpress-alb-*.elb.amazonaws.com), you literally see the famous WordPress setup screen asking for your Site Title, Admin Username, and Password.

3. The Technology Dictionary: Every Technical Term Translated

If you are talking to a recruiter or reading about the system, here is what every buzzword actually means in plain human language:

| Technical Term | Plain English Translation | Real-World Analogy | |---|---|---| | AWS (Amazon Web Services) | Amazon's giant collection of datacenters where you rent computers, storage, and networking by the second instead of buying physical boxes. | Renting apartments in a giant skyscraper instead of buying land and building a house. | | IaC (Infrastructure as Code) | Writing down your computer setups in a text file rather than clicking buttons in an AWS console. | A digital blueprint or architectural CAD file for a building. | | Terraform | The industry-standard tool that reads that blueprint and automatically orders and builds the hardware in AWS. | The automated construction crew that builds the skyscraper according to the blueprint. | | Ansible | A tool that logs into computers after they turn on and installs/configures software (Nginx, PHP, WordPress). | The interior decorators who paint the walls, install furniture, and plug in the appliances after the building is built. | | VPC (Virtual Private Cloud) | An isolated digital fenced-in neighborhood in AWS just for your servers. | A gated community where nobody can enter without an invitation. | | EC2 (Elastic Compute Cloud) | A virtual computer (server) running in AWS. | A laptop with no screen sitting in Amazon's datacenter that you control remotely. | | RDS (Relational Database Service) | Amazon's managed database service that stores your WordPress posts, users, and passwords. | A high-security bank vault where important records are guarded 24/7. | | ALB (Application Load Balancer) | A smart traffic director that sits between the internet and your server. | A receptionist in an office lobby who greets visitors and sends them to the right room. | | AWS Systems Manager (SSM) | A secure Amazon technology that allows you to control servers without needing old-fashioned SSH passwords or opening port 22 to hackers. | A secure walkie-talkie channel directly into the building with no exterior doors needed. | | AWS Lambda | "Serverless" code: Amazon runs your small script for 2 seconds when requested, and charges you $0 when nobody is using it. | An automatic light sensor that turns on only when you walk into the room, saving electricity. | | API Gateway | The front door that receives HTTP web requests from your dashboard and forwards them to Lambda. | The customer service window at a bank. | | DynamoDB | Amazon's ultra-fast NoSQL database used by CloudPress to track which sites exist and whether they are active or broken. | A super-fast digital ledger or spreadsheet. | | EventBridge | Amazon's automated alarm clock that triggers tasks on a schedule (e.g. "run the health check every hour"). | A recurring calendar reminder. | | Next.js | A modern React framework for building fast web dashboards and applications. | The dashboard instrument panel in a luxury car. | | CloudFront (CDN) | Amazon's Content Delivery Network with hundreds of servers worldwide that save copies of your photos and style files close to visitors. | Convenience stores on every corner stocking copies of popular newspapers so you don't have to drive to the main printing press. | | RPO (Recovery Point Objective) | "How much data could we lose if disaster strikes?" (e.g., 24 hours of changes). | The time elapsed since you last saved your game. | | RTO (Recovery Time Objective) | "How many minutes does it take to get the website back online if the server explodes?" | How quickly the mechanic can replace a flat tire. |

4. The Anatomy of a Site: How the AWS Pieces Fit Together

Every site you launch through CloudPress has a 3-tier, zero-trust architecture:

### 1. The Public Layer (The Reception Desk)

  • Application Load Balancer (ALB): Listens for incoming visitors on Port 80 (HTTP) and Port 443 (HTTPS).
  • It handles traffic spikes and protects the virtual server behind it.

### 2. The Application Layer (The Kitchen)

  • EC2 Instance (Virtual Server): Runs Ubuntu Linux, Nginx (web server), and PHP-FPM.
  • Security Rule: The EC2 instance refuses connections from the public internet. It only talks to the Load Balancer! If a hacker tries to attack your server's IP directly, the firewall drops the packet.

### 3. The Database Layer (The Vault)

  • RDS MariaDB/MySQL: Houses all WordPress posts, pages, usernames, and passwords.
  • Security Invariant: The database has no public IP address. It is physically impossible to connect to it from outside the private AWS network. Only your specific EC2 WordPress server has permission to query it.

### 4. The Secrets Safe

  • AWS Secrets Manager: Generates a 32-character random database password. The password is never stored in git or typed into a config file by hand. The server fetches it securely through AWS IAM permissions when WordPress boots.

5. The Step-by-Step Journey: What Happens When You Click "Deploy Site"

When you open http://localhost:3000, click [+ Deploy Site], type my-brand and mybrand.com, and click Execute, here is the exact chain reaction:

``` [You Click Deploy] | v

  1. Next.js Dashboard sends a POST request with JSON { site_id, domain }

| v

  1. AWS API Gateway receives the request and triggers the "cloudpress-api" Lambda

| v

  1. Lambda creates a record in DynamoDB with status: "PROVISIONING"

| v

  1. Lambda wakes up AWS CodeBuild (a temporary serverless container)

| v

  1. CodeBuild runs Terraform:
  • Creates the VPC, Subnets, Security Groups, EC2 server, ALB, and RDS Database.
  • Outputs the database credentials and IP into an automated JSON file.

| v

  1. CodeBuild runs Ansible:
  • Connects to the new EC2 server over AWS Systems Manager (SSM) - no SSH port open!
  • Installs Nginx, PHP, and WordPress.
  • Connects WordPress to the RDS database.

| v

  1. CodeBuild updates DynamoDB: status = "AVAILABLE"

| v

  1. Next.js Dashboard polls DynamoDB, sees "AVAILABLE", and turns the site card GREEN!

```

6. Why CloudPress is Unique: Tough Engineering Problems We Solved

When recruiters or senior engineers interview you, they don't care about simple tutorials; they want to know what went wrong and how you engineered through it. Here are the real battle-tested achievements in CloudPress:

### 1. Eliminating All Inbound SSH Ports (Zero-Trust Security) * The Problem: Normal tutorials open Port 22 (SSH) to the entire internet (0.0.0.0/0) and use private .pem keys to configure servers. If that key leaks or Port 22 is brute-forced, the server is compromised. * Our Solution: We completely closed Port 22. We configured Ansible to tunnel through AWS Systems Manager (SSM). Communication uses encrypted IAM role credentials with zero open inbound ports on the EC2 security group.

### 2. Eliminating Idling Server Costs (The Serverless Build Plane) * The Problem: Traditional CI/CD tools (like Jenkins or self-hosted GitHub runners) require servers running 24/7, costing $50-$150/month even when you aren't deploying any sites. * Our Solution: We used AWS CodeBuild on-demand. When you deploy a site, Amazon spins up a container for 5 minutes, runs Terraform and Ansible, and immediately destroys the container. When you aren't deploying, the build plane costs $0.00.

### 3. Solving the AWS Regional VPC Quota Limit * The Problem: AWS enforces a strict default quota of 5 VPCs per region. Failed or orphaned test runs can trap subnet groups and load balancers, causing subsequent deployments to fail with VpcLimitExceeded. * Our Solution: We engineered an automated dependency-aware cleanup script (cleanup_vpcs.py) that systematically tears down dependencies in reverse order (EC2 instances -> Load Balancers -> DB Subnet Groups -> RDS instances -> Subnets -> Internet Gateways -> VPCs), guaranteeing clean isolation.

### 4. DynamoDB Python Decimal Serialization Bug * The Problem: When our background monitor stored integers in DynamoDB (like core_updates: 0), Python's AWS SDK returned them as decimal.Decimal objects. Python's default json.dumps() crashed with a 500 error because it cannot serialize Decimal types. * Our Solution: We authored a custom DecimalEncoder class inside api/app.py that dynamically detects Decimal values and casts whole numbers to int and fractions to float, making the API completely crash-proof.

### 5. Resilient, Brutalist UI (Zero AI Slop) * The Problem: Most AI-generated dashboards use cookie-cutter blue Tailwind templates with oversized drop-shadows that look like cheap templates. * Our Solution: We studied BennyDuah.com and Anchor.BennyDuah.com to create an intentional, monospace, dark-mode terminal aesthetic (#0a0a0a background, zinc accents, high-density telemetry data).

7. The Recruiter & Client Pitch Guide: How to Talk About This Project

Use this cheat sheet during interviews, portfolio presentations, or client pitches.

### The 30-Second Elevator Pitch > *"I built CloudPress, a production-grade, API-driven WordPress cloud hosting platform on AWS. Instead of paying managed hosts $30 per site every month or manually setting up servers, CloudPress gives you a custom Next.js dashboard where you click 'Deploy', and an automated pipeline uses Terraform, Ansible, and AWS CodeBuild to provision an isolated, multi-tier WordPress infrastructure in 5 minutes with private databases, zero open SSH ports, and automated hourly health monitoring."*

### Key Technical Talking Points for Interviews

#### If they ask: *"How do you handle security?"*

  • *"We enforce a strict zero-trust model. Database instances have zero public IP addresses and live in private subnets. EC2 instances have no inbound SSH ports open; all configuration management and telemetry commands are executed via IAM-authenticated AWS Systems Manager tunnels. Secrets are dynamically generated in AWS Secrets Manager and never committed to version control."*

#### If they ask: *"Why didn't you just use Docker or Kubernetes?"*

  • *"WordPress has specific stateful characteristics - uploads in wp-content and relational data in MySQL. Running Kubernetes for individual client sites introduces huge operational overhead and cluster idle costs. Our architecture gives every tenant a dedicated, isolated AWS VPC with an Application Load Balancer and burstable compute at a fraction of the cost, with zero container orchestration tax."*

#### If they ask: *"How does the monitoring work?"*

  • *"We built an EventBridge scheduled Lambda that runs hourly. Instead of just doing a basic HTTP 200 ping, it uses AWS SSM Run Command to run WP-CLI commands inside the container as the web user (www-data). It extracts actual WordPress runtime metrics: available plugin updates, core updates, real disk space consumption, and active administrator accounts, and records them in DynamoDB so the dashboard has live telemetry."*

8. The Enterprise Additions: CDN, 1-Click Updates & Disaster Recovery

When moving from a portfolio project to an enterprise-ready production platform, three major gaps had to be closed:

`` +------------------------------------------------------------------------------------+ | The 3 Enterprise Pillars | +------------------------------------------------------------------------------------+ | 1. The Speed Gap -> CloudFront CDN + Nginx Browser 30-Day Static Caching | | 2. The Maintenance Gap -> Automated OS Patching + 1-Click Atomic Pre-Backup Updates| | 3. The Data Safety Gap -> Automated Daily Snapshots + 7-Day Rolling Retention + DR | +------------------------------------------------------------------------------------+ ``

### 8.1 Pillar 1: Global CDN & Edge Caching (The Speed Gap) * The Problem: Without a Content Delivery Network (CDN), every visitor in London, Tokyo, or Sydney has to make a round-trip connection all the way to Virginia (us-east-1) to download images, CSS, and JavaScript. This causes slow load times and wastes server CPU. * What We Built:

  1. AWS CloudFront Edge Distribution: Added automated CloudFront routing in terraform/modules/site/dns_cdn.tf.
  2. Smart Caching Rules:
  • Media & Code (/wp-content/* and /wp-includes/*): Cached aggressively at 450+ Amazon edge locations worldwide with Brotli and Gzip compression.
  • Admin & Login (/wp-admin/* and wp-login.php): Completely bypasses cache (Managed-CachingDisabled) so cookies, logins, and form submissions are never mistakenly cached.
  1. Nginx Browser Caching: Added 30-day cache headers (Cache-Control: public, no-transform; expires 30d;) inside nginx.conf.j2 for fonts, SVGs, WebP images, and scripts.

* Why It Matters: Your sites now load in under 1 second globally and can easily withstand traffic spikes without crashing the server.

### 8.2 Pillar 2: Automated OS Patching & 1-Click Updates (The Maintenance Gap) * The Problem: WordPress is the #1 target for automated internet bots. If plugins or the operating system aren't updated, vulnerabilities leave the site open to hacks. But blind automatic updates can break themes or crash the site! * What We Built:

  1. Automated Linux OS Patching: Configured unattended-upgrades via Ansible in hardening/tasks/main.yml. The Ubuntu server installs critical Linux security patches automatically in the middle of the night and cleans up old packages.
  2. 1-Click Atomic Safe Updates (`POST /sites/{site_id}/update`):
  • Before touching a single file, the system takes an immediate safety backup (an Amazon AMI image of the server and an Amazon RDS snapshot of the database).
  • It connects via AWS SSM and runs:

``bash wp core update wp plugin update --all wp core update-db ``

  • If anything goes wrong, you have an exact freeze-frame snapshot taken 10 seconds before the update to roll back to.
  1. Dashboard Button: Added an `[Apply Updates]` button directly on the site details screen in the Next.js dashboard.

* Why It Matters: It gives agencies complete maintenance peace of mind. One click updates core, plugins, and database safely.

### 8.3 Pillar 3: Backup & Disaster Recovery (The Data Safety Gap) * The Problem: If a client deletes a WooCommerce product table by mistake, or Amazon's underlying physical hardware experiences an outage, how do you get the site back? * What We Built:

  1. Automated Daily Backups: In api/monitor.py, the hourly Lambda check tracks last_backup_time. If 24 hours have passed, it automatically triggers:
  • An EC2 Golden AMI (cloudpress-backup-{site_id}-{timestamp}) saving all files, Nginx configs, and uploaded media.
  • An RDS DB Snapshot (cloudpress-db-backup-{site_id}-{timestamp}) saving all SQL tables.
  1. Automated 7-Day Rolling Retention Cleanup: cleanup_old_backups() inspects all snapshots and AMIs. Anything older than 7 days is automatically deregistered and its underlying EBS storage deleted. This keeps backups fresh while preventing your AWS bill from ballooning.
  2. Disaster Recovery Playbook (`docs/disaster-recovery-playbook.md`): A complete, step-by-step emergency manual documenting:
  • RPO (< 24 Hours): Maximum potential data delta.
  • RTO (< 15 Minutes): Time required to bring a crashed server back up from an AMI snapshot into the Load Balancer target group.

9. How We Made Sites Publicly Accessible (The ALB URL Discovery)

When you originally tested the dashboard, the URLs showed: http://api12.test.cloudpress.local

### Why .local Didn't Open in Your Browser A domain ending in .local is a private AWS Route 53 zone. It only resolves inside the AWS Virtual Private Cloud (VPC). Your laptop's home Wi-Fi doesn't know what .local means.

### How We Solved It

  1. Every site already has an Application Load Balancer with a public Amazon domain name, like:

cloudpress-alb-test-site-api-12-1903336491.us-east-1.elb.amazonaws.com

  1. We modified api/app.py so that whenever it returns site information, it automatically queries the AWS Elastic Load Balancing API, extracts the real public DNS address of the load balancer, and attaches:

``json { "alb_dns_name": "cloudpress-alb-test-site-api-12-1903336491.us-east-1.elb.amazonaws.com", "public_url": "http://cloudpress-alb-test-site-api-12-1903336491.us-east-1.elb.amazonaws.com" } ``

  1. We updated the Next.js dashboard (frontend/src/app/page.tsx and sites/[site_id]/page.tsx). Now, clicking the site opens the live AWS Application Load Balancer URL directly, letting anyone test WordPress from any device anywhere in the world!

10. Pitching to Companies & Agencies Setting Up WordPress on the Cloud

If you are speaking to an agency owner, an AWS Managed Service Provider (MSP), or a recruiter looking for cloud platform engineers, here is how you frame CloudPress as a high-margin B2B business engine:

### The Agency Business Problem Most web design agencies and digital consultancies launch 20 to 100 WordPress sites for their clients. They typically do one of two things:

  • Put clients on Hostinger / Bluehost ($5-$10/mo): The sites are slow, get hacked, share databases, and when the site goes down, the client gets furious with the agency.
  • Put clients on WP Engine or Kinsta ($35-$100/mo per site): The agency pays a massive bill every month to a vendor, and makes almost zero profit on the hosting.

### The CloudPress Solution & Profit Margin With CloudPress, the agency deploys directly into their own AWS account:

  • Raw AWS Cost per Site: ~$22.00 / month (EC2 t3.micro + RDS db.t4g.micro).
  • Agency Client Retainer: $250.00 – $500.00 / month for "Enterprise Managed Cloud Hosting & Disaster Recovery".
  • Gross Profit Margin: 80% to 90%!

``` 20 Client Sites:

  • AWS Infrastructure Cost: ~$440 / month
  • Client Billing: $5,000 / month
  • Net Agency Profit: $4,560 / month ($54,720 / year ARR)

50 Client Sites:

  • AWS Infrastructure Cost: ~$1,100 / month
  • Client Billing: $12,500 / month
  • Net Agency Profit: $11,400 / month ($136,800 / year ARR)

```

### The 4 Enterprise Arguments Clients Love

  1. Total Isolation (Zero Noisy Neighbors): Other hosts put hundreds of websites on one server. If one gets hit by a DDoS attack, all sites slow down. CloudPress gives each client their own dedicated virtual server and private database.
  2. Bank-Grade Zero-Trust Security: No public SSH port 22 open to hackers. All administration runs through encrypted AWS SSM tunnels. Databases have zero public internet exposure.
  3. Automated Rollback & Disaster Recovery: If an update fails, a freeze-frame snapshot exists from 10 seconds before the update. Daily snapshots with 7-day retention guarantee zero data loss.
  4. Global Edge Acceleration: CloudFront serves assets from 450+ edge datacenters worldwide, giving visitors sub-50ms page load speeds.

11. The Git Security Scrub: How We Made the Repository Safe for the Public

When making your repository public on GitHub (https://github.com/theimaginaryangel/CloudPress), security was paramount.

### The Hidden Danger of Git History If you accidentally commit an SSH private key (ec2_key.pem) in commit #1, and then in commit #5 you delete the file, the key is still in Git! Anyone can view commit #1 on GitHub and steal the key.

### What We Did:

  1. History Rewrite (`git filter-branch`): We used Git's deep history filter to scan every single commit across the entire branch history and permanently scrubbed ansible/ec2_key.pem.
  2. Pruned Reflogs & Packed Garbage Collection: We forced Git to purge all historical dangling references (git reflog expire --expire=now --all && git prune).
  3. Verified Zero Secrets: We scanned the entire tree for private keys, AWS access keys (AKIA...), and .env files. There are zero sensitive credentials in the repo.
  4. Permanent `.gitignore` Guardrails:
  • *.pem and *.key are permanently ignored.
  • *.zip and *.tfstate are permanently ignored.
  • `docs/cloudpress-complete-guide.md` (this exact document) is permanently ignored so your personal study notes and pitch book stay 100% private on your laptop!

12. Cost Optimization & Deploy Button Security

### 12.1 Sashing the AWS Bill (From $56 to ~$15/mo) When inspecting the AWS Cost Breakdown, three databases were running simultaneously ($12.24/mo each = $36.70) along with 8 test Route 53 zones ($0.50/mo each = $4.50):

  1. Pruned 2 Extra Test Sites: Deleted site-kaluna and site-bennyduah databases, EC2 instances, and ALBs, leaving 1 pristine, live production demo site (`test-site-api-12`).
  2. Pruned 7 Orphan Route 53 Zones & 14 Empty Media Buckets: Slashed Route 53 costs down to $0.50/mo.
  3. Result: Your ongoing AWS bill drops by ~70%, while keeping your live portfolio site completely operational.

### 12.2 Securing the Deploy Button & Admin Operations To prevent unauthorized visitors, recruiters, or bots from clicking [+ Deploy Site] or triggering AWS provisioning:

  1. Admin Passkey Protection: Mutating endpoints (POST /sites, DELETE /sites/{site_id}, reboot, backup, update) now enforce an x-api-key header matching ADMIN_API_KEY .
  2. Read-Only Showcase Mode: Public visitors and recruiters can freely browse the dashboard, view active sites, inspect live health metrics, and open the live WordPress site, but cannot deploy, delete, or reboot without the passkey.
  3. Browser Memory: When you enter the passkey on your machine, the dashboard saves it in localStorage, so you never have to retype it.
Next.js
Tailwind CSS
SWR
AWS API Gateway
AWS Lambda
Amazon DynamoDB
Amazon EventBridge
AWS CodeBuild
Amazon EC2
Amazon RDS
CloudFront
AWS Secrets Manager
AWS Systems Manager
Terraform
Ansible
Redis
Python
Found this technical breakdown useful?Share it with your team or network.