A custom, distributed frontend hosting and deployment platform built using Node.js, Express, TypeScript, Redis, and S3-compatible object storage.
This platform allows users to enter a GitHub repository URL, builds the project in the background, and deploys it, serving the static assets via a custom request handler mapped to a unique project subdomain.
sequenceDiagram
actor User
participant FE as Frontend (Vite + React)
participant US as Upload Service (Port 3000)
participant R as Redis (Queue & State)
participant S3 as S3 Bucket (vercel)
participant DS as Deploy Service (Worker)
participant RH as Request Handler (Port 3001)
User->>FE: Enter GitHub Repo URL & Submit
FE->>US: POST /deploy { repoUrl }
activate US
US->>US: Clone repo locally to Output/{id}
US->>S3: Upload cloned files to Output/{id}/
US->>R: Push {id} to 'build-queue'
US->>R: Set status of {id} to 'upload'
US-->>FE: Return { id }
deactivate US
Note over FE, US: Frontend starts polling GET /status?id={id}
activate DS
R->>DS: brPop 'build-queue' -> get {id}
DS->>S3: Download all files under Output/{id}/
DS->>DS: Build project (npm install && npm run build)
DS->>S3: Upload files inside dist/ to dist/{id}/
DS->>R: Set status of {id} to 'deployed' (or 'failed')
deactivate DS
FE->>US: GET /status?id={id}
US->>R: Read status
R-->>US: 'deployed'
US-->>FE: Return { status: 'deployed' }
User->>RH: Visit http://{id}.kumar.com:3001/index.html
activate RH
RH->>S3: Get Object dist/{id}/index.html
S3-->>RH: File Contents
RH-->>User: Return response (HTML/CSS/JS) with content-type
deactivate RH
Before running the project, ensure you have the following installed and running:
- Node.js (v18.x or higher recommended) & npm
- Redis Server (running locally on default port
6379) - S3-Compatible Object Storage (e.g., AWS S3, Cloudflare R2, MinIO, etc.)
- Create a bucket named
vercel(or adjust the hardcoded bucket names in the code if needed).
- Create a bucket named
You need to provide S3 credentials to the backend services. Create a .env file in the following service directories:
./upload-service/.env./deploy-service/.env./request-handler/.env
Inside each .env file, specify:
ACCESS_KEY_ID=your-s3-access-key-id
SECRET_ACCESS_KEY=your-s3-secret-access-key
ENDPOINT=your-s3-endpoint-urlFollow these steps to run each service. You can run them in separate terminal windows.
Make sure your Redis server is running:
redis-serverThis service handles repository cloning, initial uploads to S3, and queuing.
cd upload-service
npm install
npm run build
npm startThis background worker processes the build queue, downloads code, builds it, and uploads the built assets.
cd deploy-service
npm install
npm run build
npm startThis service acts as the hosting router, fetching and serving built assets from S3 based on the subdomain.
cd request-handler
npm install
npm run build
npm startThe user interface to submit GitHub repositories and track deployment progress.
cd frontend
npm install
npm run devSince the platform serves projects using a subdomain-based routing scheme (e.g., http://<uploadId>.kumar.com:3001/index.html), requests to <uploadId>.kumar.com must resolve to 127.0.0.1 (localhost) for the request handler to intercept them.
Add the generated deployment ID to your /etc/hosts file (requires sudo privileges):
127.0.0.1 <generated-upload-id>.kumar.com
Instead of modifying hosts files every time, you can modify frontend/src/components/landing.tsx to use the standard wildcard local domain localhost.direct or lvh.me which resolve to 127.0.0.1 out-of-the-box:
- Update
landing.tsxto point to:http://${uploadId}.localhost:3001/index.html - All modern browsers resolve
*.localhostrequests to127.0.0.1automatically without configuration!