A full-stack University Management System built with FastAPI, MySQL, and Docker, featuring JWT authentication, role-based access control, async database operations, load testing, and VPS production deployment.
The project includes a lightweight frontend dashboard built with HTML/CSS/JavaScript for testing and interacting with the API.
- 🔐 JWT Authentication
- 🛡️ Role-Based Access Control
- ⚡ Async FastAPI + Async SQLAlchemy
- 🐳 Dockerized Backend & Database
- 📚 Course Management
- 👨🎓 Student Management
- 👩🏫 Faculty Management
- 🔗 Enrollment System
- 🧪 Full Async Pytest Suite
- 📈 k6 Load Testing & Benchmarking
- 🌐 VPS Production Deployment
- 🔒 HTTPS + Nginx Reverse Proxy
- 🚦 Rate Limiting using SlowAPI
Frontend:
https://ums.dhruvcore.com/
| Layer | Technology |
|---|---|
| Backend | FastAPI |
| Database | MySQL |
| ORM | SQLAlchemy 2.x |
| Async Driver | aiomysql |
| Validation | Pydantic |
| Authentication | JWT |
| Password Hashing | bcrypt + passlib |
| Testing | Pytest + pytest-asyncio |
| Load Testing | k6 |
| Server | Uvicorn / Gunicorn |
| Containerization | Docker + Docker Compose |
| Reverse Proxy | Nginx |
| SSL | Certbot + Let's Encrypt |
A simple frontend dashboard is included using:
- HTML
- CSS
- JavaScript
- Signup & Login
- Create Courses
- Create Students
- Create Faculty
- Create Enrollments
- JWT Protected API Calls
This frontend is a basic API interaction dashboard, not a production UI.
University-Management/
│
├── backend/
│ ├── core/
│ ├── db/
│ ├── dependencies/
│ ├── migrations/
│ ├── models/
│ ├── queries/
│ ├── routes/
│ ├── schemas/
│ ├── services/
│ ├── tests/
│ └── main.py
│
├── frontend/
├── docker/
├── requirements.txt
├── docker-compose.yml
├── README.md
└── LICENSE
git clone https://github.com/Dhruv-Cmds/University-Management.git
cd University-Managementpython -m venv .venv.venv\Scripts\activatesource .venv/bin/activatepip install -r requirements.txtCreate a .env file:
COMPOSE_PROJECT_NAME=ums-app
DB_NAME=ums
TEST_DB_NAME=ums_test
DB_USER=ums_user
DB_PASSWORD=ums_password
MYSQL_ROOT_PASSWORD=ums_password
SECRET_KEY=your_secret_key
ALGORITHM=HS256
ACCESS_TOKEN_EXPIRE_MINUTES=60CREATE DATABASE ums;uvicorn backend.main:app --reloadSwagger Docs:
http://127.0.0.1:8000/docs
docker compose up --build| Service | Port |
|---|---|
| FastAPI API | 8002 |
| MySQL | 3009 |
API Docs:
http://localhost:8002/docs
Protected routes require:
Authorization: Bearer <your_token>
This project is deployed on a Linux VPS using Docker, Nginx, HTTPS, and a production-style reverse proxy setup.
- Hostinger VPS
- Ubuntu 24.04
- Dockerized FastAPI backend
- Dockerized MySQL database
- Nginx reverse proxy
- HTTPS enabled with Certbot + Let's Encrypt
- Domain-based deployment
- FastAPI
- Async SQLAlchemy
- JWT Authentication
- Role-Based Access Control
- Gunicorn + Uvicorn workers
- Dockerized API container
- HTML/CSS/JavaScript dashboard
- Served behind Nginx
- Connected to protected backend APIs using JWT
- MySQL 8
- Dedicated Docker container
- Persistent Docker volume
- Separate test database support
- HTTPS enforced
- SSH key-based VPS access
- UFW firewall configured
- JWT-protected routes
- bcrypt password hashing
- Nginx reverse proxy isolation
- Rate limiting with SlowAPI
- Environment variables separated from source code
git push origin main
↓
SSH into VPS
↓
git pull
↓
docker compose up --build -d
↓
Nginx routes traffic to FastAPI container
↓
HTTPS served through Let's Encrypt
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /admin/signup |
❌ | Register admin |
| POST | /admin/login |
❌ | Login and receive JWT |
| GET | /admin/ |
✅ | List all admins |
| GET | /admin/{admin_id} |
✅ | Get admin by ID |
| DELETE | /admin/{admin_id} |
✅ | Delete admin |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /courses/ |
✅ | Create course |
| GET | /courses/ |
✅ | List courses |
| GET | /courses/{course_id} |
✅ | Get course by ID |
| DELETE | /courses/{course_id} |
✅ | Delete course |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /students/ |
✅ | Create student |
| GET | /students/ |
✅ | List students |
| GET | /students/{student_id} |
✅ | Get student by ID |
| DELETE | /students/{student_id} |
✅ | Delete student |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /faculties/ |
✅ | Create faculty |
| GET | /faculties/ |
✅ | List faculties |
| GET | /faculties/{faculty_id} |
✅ | Get faculty by ID |
| DELETE | /faculties/{faculty_id} |
✅ | Delete faculty |
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | /enrollments/ |
✅ | Create enrollment |
| GET | /enrollments/ |
✅ | List enrollments |
| GET | /enrollments/{enrollment_id} |
✅ | Get enrollment by ID |
| DELETE | /enrollments/{enrollment_id} |
✅ | Delete enrollment |
Run async pytest suite:
pytest -v- JWT authentication
- Role-based access control
- CRUD operations
- Database integration
- Enrollment flow
- Protected routes
- Async route testing
The API was stress-tested using k6 against a fully containerized environment:
- FastAPI running in Docker
- MySQL running in Docker
- Async SQLAlchemy + aiomysql
- JWT Authentication
- bcrypt password hashing
- Rate limiting enabled
- Mixed authenticated CRUD workloads
| Test | Virtual Users | Duration | Requests/sec | Avg Latency | Success Rate |
|---|---|---|---|---|---|
| Admin Auth Load Test | 500 | 60s | ~388 req/s | ~781ms | 99.14% |
| Mixed API Load Test | 1000 | 60s | ~550 req/s | ~1.26s | 97.19% |
| Admin Signup Success | 1000 | 60s | Included Above | ~1.26s | 95% |
| Admin Login Success | 1000 | 60s | Included Above | ~1.26s | 98% |
| Dockerized Deployment Test | 1000 | 60s | ~550 req/s | ~1.26s | Stable |
| Sustained Concurrent Sessions | 1000 VUs | 60s | Stable Throughput | Minor Slowdown After ~700 VUs | System Responsive |
- 2 vCPU
- 8GB RAM
- Ubuntu 24.04
- Dockerized environment
- FastAPI backend
- MySQL database
- Nginx reverse proxy
- HTTPS enabled
- Admin signup
- Admin login
- Course creation
- Student creation
- Faculty creation
- Enrollment creation
- Authenticated GET endpoints
- Concurrent database writes
- JWT-protected API access
- Role-based protected routes
- Tested up to 1000 virtual users
- Stable behavior observed under normal production-style load
- Authenticated API flows completed successfully
- Database remained operational during load testing
- Containers stayed responsive during sustained traffic
- No catastrophic crashes observed
- ~100–300 realistic concurrent active users
- ~300–700 concurrent virtual users
At aggressive loads beyond 700 concurrent VUs:
- Increased latency observed
- Higher response times on write-heavy endpoints
- bcrypt hashing became a visible bottleneck during login/signup
- MySQL write pressure increased
- Some failed/slow requests appeared under extreme load
- No full system crash observed
- Services remained operational
| Concurrent Users | System Behavior |
|---|---|
| 1–200 Users | Very stable with low latency |
| 200–500 Users | Stable under heavy authenticated traffic |
| 500–700 Users | Minor latency increase, still responsive |
| 700–1000 Users | Bottlenecks begin appearing in bcrypt hashing and Docker networking |
| 1000+ Users | Temporary connection refusals and increased latency spikes |
| Bottleneck | Cause |
|---|---|
| bcrypt hashing | CPU-intensive password hashing during signup/login |
| Docker Desktop networking | Windows Docker bridge overhead under high concurrency |
| Single-machine MySQL container | Concurrent write pressure |
| TCP/socket exhaustion | Windows localhost socket limitations during extreme load |
| Metric | Result |
|---|---|
| Total Requests Processed | 35,020 |
| Maximum Concurrent Virtual Users Tested | 1000 |
| Interrupted Iterations | 0 |
| Full System Crashes | 0 |
| Database Failures | None Observed |
| Event Loop Failures | None Observed |
| Container Stability | Stable Throughout Sustained Load |
Run load tests:
k6 run load_test.jsBenchmark suite includes:
- Admin signup/login
- JWT generation
- Course creation
- Student creation
- Faculty creation
- Enrollment creation
- Authenticated GET endpoints
- Concurrent database writes
- Protected role-based routes
Recommended production command:
gunicorn backend.main:app \
-k uvicorn.workers.UvicornWorker \
-w 4 \
-b 0.0.0.0:8000- Clean architecture:
routes → services → queries → models
- Dependency Injection using FastAPI
- Async database operations
- Stateless JWT authentication
- Foreign key constraints
- Service-layer business logic
- Async test isolation
- Dockerized infrastructure
- Production deployment using Nginx and HTTPS
fastapi
sqlalchemy
aiomysql
uvicorn
gunicorn
pydantic
python-jose
passlib
bcrypt
pytest
pytest-asyncio
httpx
slowapi
docker
- React frontend migration
- Admin analytics dashboard
- Email notifications
- Refresh tokens
- Redis caching
- Prometheus + Grafana monitoring
- Background task queue
- Database replication
- Horizontal scaling
Licensed under the MIT License.
Dhruv
GitHub: https://github.com/Dhruv-Cmds
This project was built as a real-world backend engineering practice project demonstrating:
- API architecture
- JWT authentication
- RBAC authorization
- async FastAPI patterns
- Dockerized deployment
- database integration
- load testing
- production-style backend design