GameOn is a full-stack game discovery, review, and price-comparison platform built with a FastAPI backend, Supabase, RAWG, and a modern React/Vite frontend.
GameOn lets players discover games, compare live storefront prices, write reviews, track what they want to play, and follow friends. The backend is containerized and self-hosted on AWS EC2 behind Nginx with Certbot-managed HTTPS, while the frontend is deployed on Vercel.
- Self-hosted the containerized FastAPI backend on AWS EC2 instead of managed platforms using Docker, Nginx, automatic restarts, and Certbot for zero-downtime, auto-renewing SSL.
- Built a feature-rich game community product with discovery, reviews, reactions, social graphs, lists, profile management, and live price aggregation.
- Added layered caching, rate limiting, auth hardening, and image proxying to keep the app fast and safe under load.
- Shipped a polished PWA-capable frontend with React, Vite, React Router, React Query, Supabase JS, and Tailwind CSS.
| Layer | Stack |
|---|---|
| Frontend | React 19, Vite, React Router v7, React Query, Tailwind CSS, Supabase JS, Axios, Lucide React, Vite PWA |
| Backend | FastAPI, Uvicorn, Pydantic, httpx, python-jose |
| Data | Supabase Postgres, Supabase Auth |
| External APIs | RAWG Video Games API, Steam, Epic Games, PlayStation Store, Xbox Store |
| Infrastructure | Docker, AWS EC2, Nginx, Certbot, Vercel |
- Search games with per-IP rate limiting.
- Browse featured and popular game feeds from RAWG.
- Open detailed game pages with screenshots and a RAWG image proxy.
- Fetch multiple games in batches for richer UI rendering.
- Pull live prices from Steam, Epic Games, PlayStation Store, and Xbox Store.
- Parse RAWG store links and use title-matching heuristics to find the right store page.
- Cache price results to reduce repeated scraping and API calls.
- Create, edit, and delete reviews with 1-10 ratings and long-form text.
- Enrich review feeds with like/dislike counts, score, and the current user’s reaction.
- Show popular and recent review feeds with in-memory caching.
- Surface review-like notifications for signed-in users.
- View public profiles and edit your own profile.
- Track game status with want-to-play, playing, and played lists.
- Send, accept, and remove friend requests.
- Browse a friends-only review feed and a social summary of requests and friendships.
- JWT auth using Supabase JWKS with cached key rotation.
- Security headers, CORS allow-listing, and gzip compression.
- Feed, search, screenshot, price, and JWKS caches to reduce latency.
- Rate limits for search, review writes, and friend requests.
- PWA support in the frontend build.
flowchart LR
U[User Browser] --> V[Vercel Frontend\nReact + Vite]
V -->|VITE_API_URL| B[AWS EC2 Backend\nFastAPI + Docker + Nginx + Certbot]
B --> S[Supabase\nPostgres + Auth]
B --> R[RAWG API]
B --> P[Steam / Epic / PlayStation / Xbox]
The frontend is deployed on Vercel and reads its backend base URL from VITE_API_URL. The backend runs on AWS EC2 in Docker behind Nginx, with Certbot providing auto-renewing TLS. The Docker Compose files in this repository are for local development and testing only, not production deployment.
cd backend
pip install -r requirements.txt
uvicorn app:app --reloadcd frontend/GameOnFrontend
npm install
npm run devdocker compose upBackend:
SUPABASE_URLSUPABASE_ANON_KEYSUPABASE_SERVICE_ROLE_KEYRAWG_API_KEYFRONTEND_URLorFRONTEND_URLSPORTUVICORN_WORKERS
Frontend:
VITE_API_URLVITE_SUPABASE_URLVITE_SUPABASE_ANON_KEY
GameOn/
├── backend/
│ ├── app.py
│ ├── db.py
│ ├── dockerfile
│ ├── middleware/
│ │ └── auth.py
│ ├── routers/
│ │ ├── games.py
│ │ ├── lists.py
│ │ ├── reviews.py
│ │ ├── socials.py
│ │ └── users.py
│ └── services/
│ ├── rawg.py
│ └── store_prices.py
├── frontend/
│ └── GameOnFrontend/
│ ├── src/
│ ├── vite.config.js
│ ├── nginx.conf
│ └── Dockerfile
├── docker-compose.prod.yml
└── readme.MD
GET /games/searchGET /games/featuredGET /games/popularGET /games/image-proxyPOST /games/batchGET /games/{game_id}GET /games/{game_id}/pricesGET /games/{game_id}/screenshots
GET /reviews/game/{game_id}GET /reviews/game/{game_id}/mineGET /reviews/meGET /reviews/me/countGET /reviews/me/like-notificationsGET /reviews/popularGET /reviews/POST /reviews/PUT /reviews/{review_id}DELETE /reviews/{review_id}POST /reviews/{review_id}/reactionDELETE /reviews/{review_id}/reaction
GET /users/mePUT /users/meDELETE /users/meGET /users/{user_id}PUT /users/{user_id}GET /users/{user_id}/reviews
GET /lists/meGET /lists/me/{rawg_game_id}POST /lists/PUT /lists/{rawg_game_id}DELETE /lists/{rawg_game_id}
GET /socials/summaryGET /socials/searchPOST /socials/requestsPOST /socials/requests/{request_id}/acceptDELETE /socials/requests/{request_id}DELETE /socials/friends/{friend_id}GET /socials/friend-reviews
- Frontend: Vercel
- Backend: AWS EC2
- Reverse proxy: Nginx
- TLS: Certbot with auto-renewal
- Production container orchestration: Docker on EC2
- Local testing only:
docker-compose.ymlanddocker-compose.prod.yml

