Skip to content

Repository files navigation

mini-insta

A lightweight Instagram clone built with Node.js + Express. The project focuses on core social features: user authentication, photo uploads, feed generation, and interactions (likes & comments).

Architecture

Backend

flowchart LR
    subgraph Routing
        api[api.js]
        router[Express Router]
    end

    subgraph Middleware
        jwt[JWT Authentication]
        multer[Multer Upload]
    end

    subgraph Controllers
        uc[userController]
        pc[postsController]
        fc[feedController]
    end

    subgraph Models
        um[userModel]
        pm[postsModel]
        fm[feedModel]
    end

    subgraph DBAccess["Database Access"]
        pool["pg.Pool\nConnection Pool\nReuses connections\nConcurrent requests"]
    end

    subgraph PG["PostgreSQL"]
        users[(users)]
        posts[(posts)]
        likes[(likes)]
        comments[(comments)]
    end

    api    --> router
    router --> jwt
    jwt    --> multer
    multer --> uc
    multer --> pc
    multer --> fc
    uc     --> um
    pc     --> pm
    fc     --> fm
    um     --> pool
    pm     --> pool
    fm     --> pool
    pool   --> users
    pool   --> posts
    pool   --> likes
    pool   --> comments

    classDef routing    fill:#0a1628,stroke:#3b82f6,color:#93c5fd
    classDef middleware fill:#140a2e,stroke:#8b5cf6,color:#c4b5fd
    classDef controller fill:#071c10,stroke:#10b981,color:#6ee7b7
    classDef model      fill:#1c1002,stroke:#f59e0b,color:#fcd34d
    classDef dbaccess   fill:#1c0505,stroke:#ef4444,color:#fca5a5
    classDef database   fill:#0d1117,stroke:#6b7280,color:#9ca3af

    class api routing
    class router routing
    class jwt middleware
    class multer middleware
    class uc controller
    class pc controller
    class fc controller
    class um model
    class pm model
    class fm model
    class pool dbaccess
    class users database
    class posts database
    class likes database
    class comments database

    style Routing     fill:#0a1628,stroke:#3b82f6,color:#93c5fd
    style Middleware  fill:#140a2e,stroke:#8b5cf6,color:#c4b5fd
    style Controllers fill:#071c10,stroke:#10b981,color:#6ee7b7
    style Models      fill:#1c1002,stroke:#f59e0b,color:#fcd34d
    style DBAccess    fill:#1c0505,stroke:#ef4444,color:#fca5a5
    style PG          fill:#0d1117,stroke:#6b7280,color:#9ca3af
Loading

Infrastructure

flowchart LR
    cloudinary["Cloudinary API\n[ external service ]"]

    subgraph HOST["Host Machine"]
        subgraph NET["Docker Network — app-net"]
            subgraph APP["App Container"]
                node["Node.js\nPort :3000\nClustering enabled"]
            end
            subgraph DBC["DB Container"]
                pg["PostgreSQL 16\nPort :5432"]
            end
        end
        subgraph VOL["Docker Volumes"]
            pgdata[("pgdata\nDB persistence")]
            schema["schema.sql\nbind mount"]
        end
    end

    node   -->|"depends_on"| pg
    pg     -->|"mounts"| pgdata
    schema -->|"init on start"| pg
    node   -->|"HTTPS / REST"| cloudinary

    classDef appnode fill:#071c10,stroke:#10b981,color:#6ee7b7
    classDef dbnode  fill:#0a1628,stroke:#3b82f6,color:#93c5fd
    classDef volnode fill:#1c1002,stroke:#f59e0b,color:#fcd34d
    classDef extnode fill:#1c0505,stroke:#ef4444,color:#fca5a5

    class node appnode
    class pg dbnode
    class pgdata volnode
    class schema volnode
    class cloudinary extnode

    style HOST fill:#0a0a0a,stroke:#374151,color:#6b7280
    style NET  fill:#111827,stroke:#4b5563,color:#6b7280
    style APP  fill:#040f07,stroke:#10b981,color:#6ee7b7
    style DBC  fill:#040810,stroke:#3b82f6,color:#93c5fd
    style VOL  fill:#0d0a00,stroke:#f59e0b,color:#9ca3af
Loading

Quick Start

Prerequisites

  • Node.js 22+
  • Docker & Docker Compose
  • Cloudinary account (for image storage)

Setup

  1. Clone & install

    git clone https://github.com/kunal649/mini-insta.git
    cd mini-insta
    npm install
  2. Configure environment

    cp .env.example .env

    Add your Cloudinary API credentials and JWT secret.

  3. Start with Docker

    docker-compose up -d

    Database initializes automatically with schema. API runs on http://localhost:3000.

  4. Or run locally

    npm run dev

    Make sure PostgreSQL is running on localhost:5432.

API Endpoints

Authentication

  • POST /users/register - Create account (username, email, password)
  • POST /users/login - Get JWT token

Posts

  • POST /posts - Upload photo (requires token + image file)
  • GET /posts - List all posts
  • POST /posts/:id/like - Like/unlike a post
  • POST /posts/:id/comment - Add comment to post
  • GET /posts/:id/comments - View comments

Feed & Users

  • GET /feed - Paginated feed (20 posts, newest first)
  • GET /users - List users (requires token)

Tech Stack

  • Backend: Express.js + Node.js clusters
  • Database: PostgreSQL 16 with connection pooling
  • Auth: JWT tokens + bcrypt password hashing
  • File Upload: Multer + Cloudinary CDN
  • Container: Docker & Docker Compose
  • Security: Helmet headers

Project Structure

src/
├── config/          Database & Cloudinary setup, CPU clustering
├── middlewares/     JWT auth, file upload validation
├── controllers/     Business logic (users, posts, feed)
├── models/          Database queries (user, posts, feed)
└── routes/          All API endpoints

Database Schema

Four tables with foreign keys & indexes:

  • users - username, email, hashed passwords
  • posts - caption, image_url, user_id, likes_count
  • likes - composite key (user_id, post_id)
  • comments - user_id, post_id, comment text

Key Features Built

✅ User registration & JWT login
✅ Photo upload (Cloudinary storage)
✅ Feed pagination with SQL JOINs
✅ Like/unlike with count updates
✅ Comments on posts
✅ Connection pooling for concurrency
✅ Worker process clustering (4 CPU cores)

Development

npm run dev              # Auto-reload on file changes
npm run docker:up        # Start Docker services
npm run docker:down      # Stop Docker services

Notes

  • Images compressed & hosted via Cloudinary
  • Tokens expire in 1 hour
  • All protected routes require Bearer token in Authorization header
  • Database indexes optimize queries on email, user_id, post_id

About

Just for practice.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages