Loading0%
Back to portfolio

Real Estate MERN App

Property Listings, Containerized and Deployed on AWS

ReactViteRedux ToolkitReact RouterTailwind CSSSwiper.jsNode.jsExpress.jsMongoDBJWTSupabase StorageDockerAWS EC2Nginx

A full stack real estate platform where users create accounts, list properties with photos, and browse listings, built with the MERN stack and containerized for deployment on AWS EC2.

Project overview

This platform lets users create an account, list a property with up to six photos, and browse other listings through a slider-driven interface. Authentication runs on JWT stored in HTTP-only cookies, and every write to a listing is tied back to the authenticated user rather than trusting anything the client sends. Beyond the application itself, this project doubled as a DevOps exercise, containerizing the frontend and backend with Docker and deploying the result to a real AWS EC2 instance instead of a managed platform like Vercel.

Listings with image uploads through Supabase

Creating a listing supports up to six images, uploaded to Supabase Storage rather than stored directly in the app's own database. Only the resulting public URLs get saved to MongoDB, and a Swiper-powered slider handles browsing through them on the listing page.

Listings with image uploads through Supabase

Ownership enforced server side, not client side

Every listing is tied to a userRef field, but that value is never read from what the client submits. It's derived from the authenticated JWT on the server, so there's no way to submit a listing under someone else's account by tampering with a request body.

Ownership enforced server side, not client side

Containerized and deployed on a real EC2 instance

Rather than deploying to a managed platform, the app is packaged into Docker containers and served from an AWS EC2 instance behind Nginx, which is a deliberately more hands on deployment path than most portfolio projects take.

Containerized and deployed on a real EC2 instance

Key features

JWT authentication

Registration and login backed by JWT tokens stored in secure, HTTP-only cookies.

Protected listing routes

Creating, updating, and deleting a listing all require an authenticated session tied to that listing's owner.

Multi-image listings

Up to six images per listing, uploaded to Supabase Storage with client-side type and size validation.

Image slider

Listing photos browse through a Swiper-powered slider rather than a static gallery grid.

Profile management

Users can update their profile details, change their profile picture, or delete their account entirely.

Containerized deployment

Frontend and backend both run in Docker containers, deployed to an AWS EC2 instance rather than a managed hosting platform.

6

Max images / listing

1

User roles

Supabase

Storage

JWT

Auth

Architecture & diagrams

The React frontend talks to an Express API split into auth, listing, and user modules, with MongoDB for data and Supabase handling image storage separately.

Challenges & solutions

ChallengeSolution
A client could potentially spoof the listing owner by sending an arbitrary userRef value in the request body.userRef is derived from the authenticated JWT on the server instead of ever being trusted from what the frontend submits.

Best practices

Authentication & security

  • JWT stored in HTTP-only cookies, never exposed to client-side JavaScript
  • Protected routes enforced through a verifyToken middleware on the backend
  • userRef derived from the token, never trusted from client input

Media handling

  • Images uploaded to Supabase Storage, only public URLs saved in MongoDB
  • Client-side validation on image type and size before upload
  • Up to six images per listing, browsed through a Swiper slider

Deployment & DevOps

  • Frontend and backend containerized separately with Docker
  • Deployed to a real AWS EC2 instance rather than a managed platform
  • Nginx configured as the entry point in front of both containers

What's next

  • Favorites and saved listings
  • Admin dashboard
  • Google Maps integration
  • Messaging between users