Real Estate MERN App
Property Listings, Containerized and Deployed on AWS
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.

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.

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.

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
| Challenge | Solution |
|---|---|
| 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