ZipHub is a Vercel-inspired, full-stack deployment platform built with Node.js, TypeScript, and React. It utilizes a microservices architecture with Redis for message queuing and AWS S3 for artifact storage to automate the process of deploying frontend and backend applications from a Git repository.
- Node.js/Express: Backend microservices for authentication, file uploads, deployment queuing, and request handling.
- React/TypeScript: A modern, responsive frontend for initiating and monitoring project deployments.
- Redis: High-performance message queue for managing deployment jobs and caching application state.
- AWS S3: Scalable, persistent object storage for project source code and final build artifacts.
- Prisma & MongoDB: A robust ORM and database solution for user management and authentication.
- Reverse Proxy: Dynamic request handlers for routing traffic to the correct deployed static sites and backend services based on subdomains.
This project uses a microservices architecture. Each service must be installed and run separately.
-
Clone the Repository:
git clone https://github.com/sayantann7/vercel-clone.git cd vercel-clone -
Install Dependencies for Each Service: Open a terminal for each service directory listed below and run
npm install.- Authentication Service:
cd vercel-auth-service npm install - Upload Service:
cd ../vercel-upload-service npm install - Frontend Deploy Service:
cd ../vercel-deploy-service npm install - Backend Deploy Service:
cd ../vercel-be-deploy-service npm install - Frontend Request Handler:
cd ../vercel-request-handler npm install - Backend Request Handler:
cd ../vercel-be-request-handler npm install - Frontend UI:
cd ../vercel-frontend npm install
- Authentication Service:
-
Setup Prisma: Navigate to the authentication service directory and run the Prisma commands to sync your schema with the database.
cd vercel-auth-service npx prisma generate npx prisma db push -
Run the Services: Open a new terminal for each service and run the development server.
vercel-auth-service:npm run dev(Runs on port specified in.env)vercel-upload-service:npm run dev(Runs on port 3001)vercel-deploy-service:npm run devvercel-be-deploy-service:npm run devvercel-request-handler:npm run dev(Runs on port 3000)vercel-be-request-handler:npm run dev(Runs on port 3002)vercel-frontend:npm run dev(Runs on port 5173 by default)
Create a .env file in the root directory of each service that requires one (vercel-auth-service, vercel-upload-service, vercel-deploy-service, etc.).
| Variable | Service(s) | Example Value | Description |
|---|---|---|---|
DATABASE_URL |
auth-service |
mongodb+srv://user:pass@cluster.mongodb.net/ziphub?retryWrites=true |
MongoDB connection string. |
JWT_SECRET |
auth-service |
your-super-secret-jwt-key |
Secret key for signing JWTs. |
PORT |
auth-service |
4000 |
Port for the auth service to run on. |
accessKeyId |
All aws.ts users |
your-s3-access-key-id |
AWS S3 or compatible object storage key. |
secretAccessKey |
All aws.ts users |
your-s3-secret-access-key |
AWS S3 or compatible secret. |
endpoint |
All aws.ts users |
https://s3.us-east-1.amazonaws.com |
S3 endpoint URL. |
Note: Redis connection details are currently hardcoded in vercel-upload-service, vercel-deploy-service, and vercel-be-deploy-service. It is recommended to move these to environment variables for production use.
The API is split into two main public-facing services: Authentication and Upload/Deploy.
- Auth Service:
http://localhost:4000(or your configuredPORT) - Upload Service:
http://localhost:3001
Creates a new user account.
Request:
{
"name": "John Doe",
"email": "john.doe@example.com",
"password": "strongpassword123"
}Response (201 Created):
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": "60d0fe4f5311236168a109ca",
"email": "john.doe@example.com"
}
}Errors:
400 Bad Request:name,email, andpasswordare required.409 Conflict: Email already in use.500 Internal Server Error: Server-side processing error.
Authenticates a user and returns a JWT.
Request:
{
"email": "john.doe@example.com",
"password": "strongpassword123"
}Response (200 OK):
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"user": {
"id": "60d0fe4f5311236168a109ca",
"email": "john.doe@example.com",
"name": "John Doe"
}
}Errors:
400 Bad Request:emailandpasswordare required.401 Unauthorized: Invalid credentials.500 Internal Server Error: Server-side processing error.
Health check endpoint.
Request: None
Response (200 OK):
{
"status": "ok"
}Errors:
- None
Initiates a new deployment by cloning a Git repository and queueing it for build.
Request:
{
"repoUrl": "https://github.com/username/repo-name",
"projectType": "frontend",
"envVars": "API_KEY=value1\nDATABASE_URL=value2",
"installCommand": "npm install",
"buildCommand": "npm run build",
"runCommand": "npm start"
}Fields other than repoUrl are optional and have sensible defaults.
Response (200 OK):
{
"id": "a1b2c",
"projectType": "frontend"
}Errors:
500 Internal Server Error: Failed to clone repository or queue the build.
Polls the deployment status for a given project ID.
Request:
/status?id=a1b2c&projectType=frontend
Response (200 OK):
{
"status": "deployed"
}Possible statuses: uploaded, building, deployed, failed.
Errors:
- None (Returns
nullstatus if ID is not found).
| Technology | Description |
|---|---|
| React | A JavaScript library for building user interfaces. |
| Node.js | JavaScript runtime for building backend services. |
| Express | Fast, unopinionated, minimalist web framework for Node.js. |
| TypeScript | Typed superset of JavaScript that compiles to plain JS. |
| Redis | In-memory data structure store, used as a message broker. |
| MongoDB | NoSQL database for flexible, JSON-like documents. |
| Prisma | Next-generation ORM for Node.js and TypeScript. |
| AWS S3 | Scalable object storage for code and build artifacts. |
| Tailwind CSS | A utility-first CSS framework for rapid UI development. |
This project is not under a specific license. All rights are reserved by the author.
Sayantan
- LinkedIn: Your LinkedIn Profile
- Twitter: @YourTwitterHandle