Skip to content

hkumar3b/vercel

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Vercel Clone

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.


System Architecture

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
Loading

Prerequisites

Before running the project, ensure you have the following installed and running:

  1. Node.js (v18.x or higher recommended) & npm
  2. Redis Server (running locally on default port 6379)
  3. 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).

Environment Setup

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-url

How to Run

Follow these steps to run each service. You can run them in separate terminal windows.

1. Start Redis

Make sure your Redis server is running:

redis-server

2. Run the Upload Service (Port 3000)

This service handles repository cloning, initial uploads to S3, and queuing.

cd upload-service
npm install
npm run build
npm start

3. Run the Deploy Service (Worker)

This background worker processes the build queue, downloads code, builds it, and uploads the built assets.

cd deploy-service
npm install
npm run build
npm start

4. Run the Request Handler (Port 3001)

This 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 start

5. Run the Frontend (Port 5173 / Vite dev server)

The user interface to submit GitHub repositories and track deployment progress.

cd frontend
npm install
npm run dev

Local Domain Resolution / Subdomain Testing

Since 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.

Option 1: Configure /etc/hosts (Static)

Add the generated deployment ID to your /etc/hosts file (requires sudo privileges):

127.0.0.1 <generated-upload-id>.kumar.com

Option 2: Using standard wildcard subdomains (Recommended for local dev)

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:

  1. Update landing.tsx to point to: http://${uploadId}.localhost:3001/index.html
  2. All modern browsers resolve *.localhost requests to 127.0.0.1 automatically without configuration!

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages