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).
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
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
- Node.js 22+
- Docker & Docker Compose
- Cloudinary account (for image storage)
-
Clone & install
git clone https://github.com/kunal649/mini-insta.git cd mini-insta npm install -
Configure environment
cp .env.example .env
Add your Cloudinary API credentials and JWT secret.
-
Start with Docker
docker-compose up -d
Database initializes automatically with schema. API runs on
http://localhost:3000. -
Or run locally
npm run dev
Make sure PostgreSQL is running on localhost:5432.
POST /users/register- Create account (username, email, password)POST /users/login- Get JWT token
POST /posts- Upload photo (requires token + image file)GET /posts- List all postsPOST /posts/:id/like- Like/unlike a postPOST /posts/:id/comment- Add comment to postGET /posts/:id/comments- View comments
GET /feed- Paginated feed (20 posts, newest first)GET /users- List users (requires token)
- 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
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
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
✅ 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)
npm run dev # Auto-reload on file changes
npm run docker:up # Start Docker services
npm run docker:down # Stop Docker services- 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