Welcome to the E-Learning Management System (LMS)! This project consists of two main components: the Frontend (built with Angular) and the Backend (developed using Django and Django REST Framework), combined with CI/CD technologies such as Docker and Jenkins. The LMS is a full-featured web application designed to manage users, courses, lessons, quizzes, and much more. This README provides a complete guide on how to set up, run, and contribute to both parts of the system.
Visit the live demo app here: E-Learning Management System
The E-Learning Management System is a web-based platform designed to facilitate online education and training. It provides a comprehensive set of features for managing courses, lessons, users, quizzes, and more. The system is composed of:
Dockerfile and docker-compose.yml for containerization and deployment, as well as a Jenkinsfile for CI/CD pipelines and Kubernetes configuration files for orchestration.Because we use MongoDB, Angular, and Django, we call this a MAD-Stack application! (Just a fun name to remember the technologies used)
The MAD-Stack is a modern web development stack that combines the following technologies:
The MAD-Stack is a powerful combination that allows developers to build scalable, responsive, and feature-rich web applications. It leverages the strengths of each technology to create a seamless user experience.
Sounds mad, but itβs actually a great stack for building modern web applications!
For a comprehensive and detailed architecture documentation, please refer to ARCHITECTURE.md.
The system follows a modern three-tier architecture with clear separation of concerns:
graph TB
    subgraph "Client Layer"
        A[Web Browser]
        B[Mobile Browser]
    end
    subgraph "Frontend - Angular SPA"
        C[Angular Components]
        D[Angular Services]
        E[HTTP Interceptors]
        F[State Management]
    end
    subgraph "API Gateway"
        G[NGINX Reverse Proxy]
    end
    subgraph "Backend - Django REST API"
        H[Django REST Framework]
        I[Authentication Layer]
        J[Business Logic]
        K[Serializers & ViewSets]
    end
    subgraph "Caching Layer"
        L[Redis Cache]
    end
    subgraph "Data Persistence"
        M[(MongoDB - Course Data)]
        N[(SQLite - Auth Data)]
    end
    A --> C
    B --> C
    C --> D
    D --> E
    E --> G
    G --> H
    H --> I
    I --> J
    J --> K
    K --> L
    K --> M
    I --> N
graph LR
    subgraph "Frontend Stack"
        A[Angular 18]
        B[TypeScript]
        C[Bootstrap 5]
        D[RxJS]
    end
    subgraph "Backend Stack"
        E[Django 4.2]
        F[Django REST Framework]
        G[Python 3.12]
        H[MongoEngine ODM]
    end
    subgraph "Database Stack"
        I[(MongoDB 5.0)]
        J[(SQLite 3)]
        K[(Redis 6)]
    end
    subgraph "DevOps Stack"
        L[Docker]
        M[Kubernetes]
        N[Jenkins]
        O[GitHub Actions]
    end
    A --> E
    E --> I
    E --> J
    E --> K
    L --> M
    N --> O
    style A fill:#dd0031
    style E fill:#092e20
    style I fill:#47a248
    style K fill:#dc382d
    style L fill:#2496ed
The system uses MongoDB for storing course-related data with the following entity relationships:
erDiagram
    USER ||--o{ COURSE : instructs
    USER ||--o{ ENROLLMENT : enrolls
    USER ||--o{ PROGRESS : tracks
    USER ||--o{ NOTIFICATION : receives
    CATEGORY ||--o{ COURSE : categorizes
    COURSE ||--o{ LESSON : contains
    COURSE ||--o{ ENROLLMENT : has
    LESSON ||--o{ QUIZ : includes
    LESSON ||--o{ PROGRESS : tracks
    QUIZ ||--o{ QUESTION : contains
    QUESTION ||--o{ CHOICE : has
    USER {
        ObjectId id PK
        string username UK
        string email UK
        boolean is_instructor
        boolean is_student
        string bio
        string profile_picture
    }
    COURSE {
        ObjectId id PK
        string title
        string description
        ObjectId instructor_id FK
        ObjectId category_id FK
        decimal price
        boolean published
        datetime created_at
    }
    LESSON {
        ObjectId id PK
        string title
        ObjectId course_id FK
        string content
        string video_url
        datetime created_at
    }
    ENROLLMENT {
        ObjectId id PK
        ObjectId student_id FK
        ObjectId course_id FK
        datetime enrolled_at
    }
    PROGRESS {
        ObjectId id PK
        ObjectId student_id FK
        ObjectId lesson_id FK
        boolean completed
        datetime completed_at
    }
The system uses JWT-based authentication with token storage:
sequenceDiagram
    participant User
    participant Angular
    participant Django
    participant SQLite
    participant Redis
    User->>Angular: Enter Credentials
    Angular->>Django: POST /api/auth/login/
    Django->>SQLite: Verify Credentials
    alt Valid Credentials
        SQLite-->>Django: User Valid
        Django->>Django: Generate JWT Token
        Django->>Redis: Cache Token
        Django-->>Angular: {token, user}
        Angular->>Angular: Store in localStorage
        Angular-->>User: Redirect to Dashboard
    else Invalid Credentials
        SQLite-->>Django: Invalid
        Django-->>Angular: 401 Unauthorized
        Angular-->>User: Show Error
    end
    Note over User,Redis: Subsequent Requests
    User->>Angular: Access Protected Route
    Angular->>Django: Request + Bearer Token
    Django->>SQLite: Validate Token
    alt Valid Token
        Django->>Redis: Check Cache
        Redis-->>Django: Data
        Django-->>Angular: Protected Resource
        Angular-->>User: Display Content
    else Invalid Token
        Django-->>Angular: 401 Unauthorized
        Angular-->>User: Redirect to Login
    end
graph TB
    subgraph "Frontend Components"
        A[Login Component]
        B[Course List Component]
        C[Lesson List Component]
        D[Enrollment Component]
        E[Progress Component]
    end
    subgraph "Angular Services"
        F[Auth Service]
        G[Course Service]
        H[Lesson Service]
        I[Enrollment Service]
        J[Progress Service]
    end
    subgraph "Backend ViewSets"
        K[CourseViewSet]
        L[LessonViewSet]
        M[EnrollmentViewSet]
        N[ProgressViewSet]
    end
    subgraph "Data Models"
        O[(Course Model)]
        P[(Lesson Model)]
        Q[(Enrollment Model)]
        R[(Progress Model)]
    end
    A --> F
    B --> G
    C --> H
    D --> I
    E --> J
    F --> K
    G --> K
    H --> L
    I --> M
    J --> N
    K --> O
    L --> P
    M --> Q
    N --> R
graph TB
    subgraph "Cloud Infrastructure"
        subgraph "Frontend Hosting - Vercel"
            A[Vercel CDN]
            B[Static Assets]
        end
        subgraph "Backend Hosting - Render"
            C[Django Application]
            D[Auto-scaling]
        end
        subgraph "Database Services"
            E[(MongoDB Atlas)]
            F[(Redis Cloud)]
        end
    end
    subgraph "CI/CD Pipeline"
        G[GitHub]
        H[GitHub Actions]
        I[Jenkins]
    end
    subgraph "Containerization"
        J[Docker Images]
        K[Kubernetes Cluster]
    end
    A --> B
    C --> D
    E --> F
    G --> H
    H --> I
    I --> J
    J --> K
    B --> C
    D --> E
    D --> F
    style A fill:#000000
    style E fill:#47a248
    style F fill:#dc382d
    style G fill:#181717
sequenceDiagram
    participant Client
    participant NGINX
    participant Django
    participant Redis
    participant MongoDB
    Client->>NGINX: HTTP Request
    NGINX->>Django: Forward Request
    alt Cache Hit
        Django->>Redis: Check Cache
        Redis-->>Django: Cached Data
        Django-->>Client: Response (Fast)
    else Cache Miss
        Django->>Redis: Check Cache
        Redis-->>Django: Cache Miss
        Django->>MongoDB: Query Database
        MongoDB-->>Django: Fresh Data
        Django->>Redis: Store Cache (TTL)
        Django-->>Client: Response
    end
    Note over Client,MongoDB: Write Operations Invalidate Cache
    Client->>Django: POST/PUT/DELETE Request
    Django->>MongoDB: Update Database
    MongoDB-->>Django: Success
    Django->>Redis: Invalidate Related Caches
    Django-->>Client: Response
graph LR
    subgraph "Source Control"
        A[GitHub Repository]
        B[Push/PR]
    end
    subgraph "CI Pipeline"
        C[Run Tests]
        D[Lint Code]
        E[Build Docker Image]
    end
    subgraph "CD Pipeline"
        F[Deploy to Staging]
        G{Tests Pass?}
        H[Deploy to Production]
    end
    subgraph "Monitoring"
        I[Health Checks]
        J[Performance Monitoring]
    end
    A --> B
    B --> C
    C --> D
    D --> E
    E --> F
    F --> G
    G -->|Yes| H
    G -->|No| A
    H --> I
    I --> J
Our E-Learning Management System comes packed with a variety of features to enhance the learning experience:
The project is currently deployed live! You can access the live deployment using the following link: E-Learning Management System.
The backend is deployed on Render: Backend API.
Feel free to explore the platform, create an account, and test out the features!
[!IMPORTANT] Note: Our backend server may spin down due to inactivity, so you may experience delays in loading data initially as the backend is hosted on the free tier of Render. If you encounter any issues, please let me know.
Home Page:
   
Course List:
   
Lesson List:
   
User List:
   
Enrollment List:
   
Progress List:
   
Registration Page:
   
Login Page:
   
Unauthorized Access (when not logged in):
   
Not Found Page:
   
Footer:
   
Responsive Design: The frontend is fully responsive and optimized for all devices. Here is an example of the mobile view:
   
And many more pages & features. Feel free to explore the frontend and backend to see all the functionalities!
| Endpoint | Method | Description | 
|---|---|---|
| /api/users/ | GET | Retrieve a list of all users. | 
| /api/users/{id}/ | GET | Retrieve a specific user instance. | 
| /api/users/ | POST | Create a new user instance. | 
| /api/users/{id}/ | PUT | Update a specific user instance. | 
| /api/users/{id}/ | DELETE | Delete a specific user instance. | 
| /api/courses/ | GET | Retrieve a list of all courses. | 
| /api/courses/{id}/ | GET | Retrieve a specific course instance. | 
| /api/courses/ | POST | Create a new course instance. | 
| /api/courses/{id}/ | PUT | Update a specific course instance. | 
| /api/courses/{id}/ | DELETE | Delete a specific course instance. | 
| /api/categories/ | GET | Retrieve a list of all categories. | 
| /api/categories/{id}/ | GET | Retrieve a specific category instance. | 
| /api/categories/ | POST | Create a new category instance. | 
| /api/categories/{id}/ | PUT | Update a specific category instance. | 
| /api/categories/{id}/ | DELETE | Delete a specific category instance. | 
| /api/lessons/ | GET | Retrieve a list of all lessons. | 
| /api/lessons/{id}/ | GET | Retrieve a specific lesson instance. | 
| /api/lessons/ | POST | Create a new lesson instance. | 
| /api/lessons/{id}/ | PUT | Update a specific lesson instance. | 
| /api/lessons/{id}/ | DELETE | Delete a specific lesson instance. | 
| /api/quizzes/ | GET | Retrieve a list of all quizzes. | 
| /api/quizzes/{id}/ | GET | Retrieve a specific quiz instance. | 
| /api/quizzes/ | POST | Create a new quiz instance. | 
| /api/quizzes/{id}/ | PUT | Update a specific quiz instance. | 
| /api/quizzes/{id}/ | DELETE | Delete a specific quiz instance. | 
| /api/questions/ | GET | Retrieve a list of all questions. | 
| /api/questions/{id}/ | GET | Retrieve a specific question instance. | 
| /api/questions/ | POST | Create a new question instance. | 
| /api/questions/{id}/ | PUT | Update a specific question instance. | 
| /api/questions/{id}/ | DELETE | Delete a specific question instance. | 
| /api/choices/ | GET | Retrieve a list of all choices. | 
| /api/choices/{id}/ | GET | Retrieve a specific choice instance. | 
| /api/choices/ | POST | Create a new choice instance. | 
| /api/choices/{id}/ | PUT | Update a specific choice instance. | 
| /api/choices/{id}/ | DELETE | Delete a specific choice instance. | 
| /api/enrollments/ | GET | Retrieve a list of all enrollments. | 
| /api/enrollments/{id}/ | GET | Retrieve a specific enrollment instance. | 
| /api/enrollments/ | POST | Create a new enrollment instance. | 
| /api/enrollments/{id}/ | PUT | Update a specific enrollment instance. | 
| /api/enrollments/{id}/ | DELETE | Delete a specific enrollment instance. | 
| /api/progress/ | GET | Retrieve a list of all progress records. | 
| /api/progress/{id}/ | GET | Retrieve a specific progress record instance. | 
| /api/progress/ | POST | Create a new progress record instance. | 
| /api/progress/{id}/ | PUT | Update a specific progress record instance. | 
| /api/progress/{id}/ | DELETE | Delete a specific progress record instance. | 
| /api/notifications/ | GET | Retrieve a list of all notifications. | 
| /api/notifications/{id}/ | GET | Retrieve a specific notification instance. | 
| /api/notifications/ | POST | Create a new notification instance. | 
| /api/notifications/{id}/ | PUT | Update a specific notification instance. | 
| /api/notifications/{id}/ | DELETE | Delete a specific notification instance. | 
The backend includes unit tests for the APIs. You can run the tests using the following command:
python manage.py test
Feel free to view and modify the tests in the core/tests.py file. Also, be sure to adjust the URLs in the test cases to match your actual URL configuration if different from the default.
The project structure is as follows:
Learning-Management-System/
βββ LMS-Backend
β   βββ .gitignore
β   βββ Dockerfile
β   βββ manage.py
β   βββ requirements.txt
β   βββ LICENSE
β   βββ db.sqlite3
β   βββ README.md
β   βββ LMSBackend/
β   β   βββ settings.py
β   β   βββ urls.py
β   β   βββ asgi.py
β   β   βββ wsgi.py
β   βββ core/
β       βββ management/
β       β   βββ commands/
β       β       βββ seed_sample_data.py
β       βββ migrations/
β       β   βββ __init__.py
β       βββ models.py
β       βββ views.py
β       βββ tests.py
β       βββ admin.py
β       βββ apps.py
β       βββ serializers.py
β       βββ urls.py
β
βββ LMS-Frontend
β   βββ angular.json
β   βββ package.json
β   βββ Dockerfile
β   βββ README.md
β   βββ LICENSE
β   βββ app/
β   β   βββ src/
β   β   β   βββ app/
β   β   β   β   βββ auth/
β   β   β   β   β   βββ login/
β   β   β   β   β   β   βββ login.component.ts
β   β   β   β   β   β   βββ login.component.html
β   β   β   β   β   β   βββ login.component.css
β   β   β   β   β   βββ register/
β   β   β   β   β   β   βββ register.component.ts
β   β   β   β   β   β   βββ register.component.html
β   β   β   β   β   β   βββ register.component.css
β   β   β   β   βββ core/
β   β   β   β   β   βββ footer/
β   β   β   β   β   β   βββ footer.component.ts
β   β   β   β   β   β   βββ footer.component.html
β   β   β   β   β   β   βββ footer.component.css
β   β   β   β   β   βββ header/
β   β   β   β   β   β   βββ header.component.ts
β   β   β   β   β   β   βββ header.component.html
β   β   β   β   β   β   βββ header.component.css
β   β   β   β   βββ pages/
β   β   β   β   β   βββ home/
β   β   β   β   β   β   βββ notfound.component.ts
β   β   β   β   β   β   βββ notfound.component.html
β   β   β   β   β   β   βββ home.component.css
β   β   β   β   β   βββ notfound/
β   β   β   β   β   β   βββ notfound.component.ts
β   β   β   β   β   β   βββ notfound.component.html
β   β   β   β   β   β   βββ notfound.component.css
β   β   β   β   βββ components/
β   β   β   β   β   βββ course-list/
β   β   β   β   β   β   βββ course-list.component.ts
β   β   β   β   β   β   βββ course-list.component.html
β   β   β   β   β   β   βββ course-list.component.css
β   β   β   β   β   βββ lesson-list/
β   β   β   β   β   β   βββ lesson-list.component.ts
β   β   β   β   β   β   βββ lesson-list.component.html
β   β   β   β   β   β   βββ lesson-list.component.css
β   β   β   β   β   βββ user-list/
β   β   β   β   β   β   βββ user-list.component.ts
β   β   β   β   β   β   βββ user-list.component.html
β   β   β   β   β   β   βββ user-list.component.css
β   β   β   β   β   βββ enrollment-list/
β   β   β   β   β   β   βββ enrollment-list.component.ts
β   β   β   β   β   β   βββ enrollment-list.component.html
β   β   β   β   β   β   βββ enrollment-list.component.css
β   β   β   β   β   βββ progress-list/
β   β   β   β   β   β   βββ progress-list.component.ts
β   β   β   β   β   β   βββ progress-list.component.html
β   β   β   β   β   β   βββ progress-list.component.css
β   β   β   β   βββ services/
β   β   β   β   β   βββ auth.interceptor.ts
β   β   β   β   β   βββ auth.service.ts
β   β   β   β   β   βββ user.service.ts
β   β   β   β   β   βββ course.service.ts
β   β   β   β   β   βββ lesson.service.ts
β   β   β   β   β   βββ enrollment.service.ts
β   β   β   β   β   βββ progress.service.ts
β   β   β   β   βββ app.routes.ts
β   β   β   β   βββ app.component.ts
β   β   β   β   βββ app.config.ts
β   β   β   β   βββ app.config.service.ts
β   β   β   β   βββ app.component.html
β   β   β   β   βββ app.component.css
β   β   β   βββ assets/
β   β   β   β   βββ <images...>
β   β   β   β   βββ .gitkeep
β   β   β   βββ main.ts
β   β   β   βββ styles.css
β   β   β   βββ manifest.json
β   β   β   βββ index.html
β   β   βββ .editorconfig
β   β   βββ .gitignore
β   β   βββ angular.json
β   β   βββ package.json
β   β   βββ package-lock.json
β   β   βββ tsconfig.json
β   β   βββ tsconfig.app.json
β   β   βββ tsconfig.spec.json
β   βββ LICENSE
β   βββ README.md
β
βββ nginx
β   βββ nginx.conf
β   βββ Dockerfile
β
βββ kubernetes
β   βββ configmap.yaml
β   βββ backend-deployment.yaml
β   βββ backend-service.yaml
β   βββ frontend-deployment.yaml
β   βββ frontend-service.yaml
β
βββ .gitignore
βββ .env.example
βββ docker-compose.yml
βββ Jenkinsfile
βββ openapi.yaml
βββ LICENSE
βββ README.md
Ensure the following prerequisites are installed:
Note: Before running the backend server, ensure MongoDB and Redis are running and accessible on your system. You can install MongoDB and Redis locally or use cloud services like MongoDB Atlas and Redis Cloud.
Clone the repository:
git clone https://github.com/hoangsonww/Learning-Management-System-Fullstack.git
cd Fullstack-Learning-Management-System/LMS-Backend
Create and activate a virtual environment:
python -m venv .venv
source .venv/bin/activate  # On Windows, use `.venv\Scripts\activate`
Install dependencies:
pip install -r requirements.txt
Configure MongoDB and Redis:
Ensure MongoDB and Redis are running and configured in settings.py. If not installed, follow the instructions to install them. It is very important to run MongoDB and Redis before running the backend server.
Additionally, edit the .env file according to the .env.example file with the correct MongoDB and Redis connection strings.
Apply migrations:
python manage.py makemigrations
python manage.py migrate
Create a superuser:
python manage.py createsuperuser
Follow the prompts to create a superuser account. Remember to note down the username and password because you will need it to authenticate when using the APIs later, as well as to access the Django admin panel.
Put the SECRET_KEY and set Debug to True in the settings.py file:
SECRET_KEY = 'your_secret_key_here'
DEBUG = True
Replace your_secret_key_here with a random string of characters. This key is used for cryptographic signing and should be kept secret. Or you can also contact me to get the secret key.
Alternatively, create an .env file in the project root directory following the format in the .env.example file:
DJANGO_SECRET_KEY=your_secret_key_here
DJANGO_DEBUG=True
(...)
Seed the database with sample data:
python manage.py seed_sample_data
Run the backend server:
python manage.py runserver
The backend server should now be running at http://127.0.0.1:8000/. If the server is run successfully, you should see the Django REST Framework browsable API interface at http://127.0.0.1:8000, as well as the following console output:
python manage.py runserver
Successfully seeded realistic sample data
Successfully seeded realistic sample data
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced).
September 08, 2024 - 20:35:21
Django version 4.2.16, using settings 'LMSBackend.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
Navigate to the frontend directory:
cd Learning-Management-System/LMS-Frontend/app
Install dependencies:
npm install
Start the development server:
ng serve
Open the application in your browser:
http://localhost:4200
Test out the PWA functionality:
Most API endpoints require authentication. Use the /api/auth/login/ endpoint to log in and obtain an authentication token.
Log in to get a token:
curl -X POST http://127.0.0.1:8000/api/auth/login/ -H "Content-Type: application/json" -d '{
  "username": "your_username",
  "password": "your_password"
}'
Use the obtained token in the Authorization header for subsequent requests:
-H "Authorization: Token <your_token_here>"
You can test the API using curl, Postman, or Swagger UI.
curlTo test the API using curl, use the commands below. Replace <your_token_here> with the token obtained from the login endpoint.
List All Users
curl -X GET http://127.0.0.1:8000/api/users/ -H "Content-Type: application/json" -H "Authorization: Token <your_token_here>"
You should get something like this:
[
  {
    "id": "66dde39af395abfee65d1f86",
    "username": "gibsonstacey",
    "email": "xcaldwell@example.org",
    "is_instructor": false,
    "is_student": false,
    "bio": "Consider red specific within chance fund successful out.",
    "profile_picture": "https://placekitten.com/970/531"
  }
]
Create a New Course
curl -X POST http://127.0.0.1:8000/api/courses/ -H "Content-Type: application/json" -H "Authorization: Token <your_token_here>" -d '{
  "title": "New Course",
  "description": "This is a new course description.",
  "instructor": "{user_id}",
  "category": "{category_id}",
  "price": 150.00,
  "published": true
}'
Repeat similar curl commands for other endpoints.
http://127.0.0.1:8000/api/users/).Token <your_token_here>) in the βAuthorizationβ header. Note that the token should be prefixed with Token and a space.Here is how the Swagger UI looks like:
   
Here is how the Redoc UI looks like:
   
For example, to view the list of all lessons, go to http://127.0.0.1:8000/api/lessons/. The interface should look like this:
   
Well, remember to log in first before accessing the APIβ¦ Donβt forget to log in!
If you want to seed the database with realistic sample data, you can also run the seed_sample_data management command:
python manage.py seed_sample_data
This command will populate the database with randomly generated users, courses, categories, lessons, quizzes, questions, choices, enrollments, progress records, and notifications.
Note: By default, the seed_sample_data command will be executed when you run the python manage.py migrate command. If you donβt want to seed the database at that time, you can disable it by setting SEED_SAMPLE_DATA_ON_MIGRATE = False in the settings.py file. Also, your data might be different from mine because the data is randomly generated.
To interact with the APIs and databases more easily, you can use the following GUI tools:
For example, you can use MongoDB Compass to view the data in your MongoDB database, RedisInsight to view the data in your Redis database, and Postman to test the API endpoints, like below:
   
This project is set up to use MongoDB Atlas as the cloud database. You can create a free account on MongoDB Atlas and set up a free cluster to use with the project. Follow these steps to set up MongoDB Atlas:
Create a MongoDB Atlas account:
Create a free cluster:
Connect to your cluster:
Get your connection string:
Set up the connection string in the Django settings:
.env configuration file with the connection string from MongoDB Atlas.Alternatively, you can use the local MongoDB server for development and testing purposes.
The Learning Management System supports multiple deployment options, from local development to production-grade cloud infrastructure.
| Option | Environment | Complexity | Cost | Scalability | Best For | 
|---|---|---|---|---|---|
| Docker Compose | Local/Dev | Low | Free | Limited | Development, Testing | 
| Kubernetes | Any | Medium | Variable | High | Self-hosted Production | 
| AWS (Terraform) | Cloud | Medium-High | ~$1400/mo | Very High | Enterprise Production | 
| Vercel + Render | Cloud | Low | ~$25/mo | Medium | Small-Medium Projects | 
graph TB
    subgraph "Development"
        LOCAL[Local Development<br/>Docker Compose]
    end
    subgraph "Staging/Testing"
        K8S[Kubernetes<br/>Self-Hosted]
    end
    subgraph "Production Options"
        AWS[AWS Full Stack<br/>ECS + RDS + DocumentDB]
        VERCEL[Vercel + Render<br/>Managed Services]
    end
    LOCAL --> K8S
    K8S --> AWS
    K8S --> VERCEL
The project includes production-ready Infrastructure as Code:
/aws - AWS deployment scripts and CloudFormation templates/terraform - Terraform modules for complete AWS infrastructure/kubernetes - Kubernetes manifests for container orchestrationSee DEPLOYMENT.md for detailed deployment instructions for each option.
The project can be containerized using Docker. The Dockerfile and docker-compose.yml files are provided in the repository. To containerize the project, follow these steps:
Change directory into the project root:
cd Learning-Management-System
Build the Docker image:
docker compose up --build
The above command will build the Docker image and start the containers for the backend, frontend, MongoDB, and Redis. You can access the application at http://localhost:4200 and the Django REST Framework API at http://localhost:8000.
The project includes Kubernetes configuration files for deploying the backend and frontend applications. The Kubernetes directory contains the following files:
To deploy the applications to a Kubernetes cluster, follow these steps:
Change directory into the Kubernetes directory:
cd Kubernetes
Create the configmap:
 kubectl apply -f configmap.yaml
Create the backend deployment:
kubectl apply -f backend-deployment.yaml
Create the backend service:
 kubectl apply -f backend-service.yaml
Create the frontend deployment:
 kubectl apply -f frontend-deployment.yaml
Create the frontend service:
 kubectl apply -f frontend-service.yaml
The above commands will create the deployments and services for the backend and frontend applications. You can access the applications using the NodePort or LoadBalancer service IP addresses.
The project includes unit tests for both the backend and frontend applications. You can run the tests using the following commands:
To run the backend tests, navigate to the LMS-Backend directory and run:
cd LMS-Backend
pytest -q
To run the frontend tests, navigate to the LMS-Frontend/app directory and run:
cd LMS-Frontend/app
# Run tests (normal mode)
npm run test
# Run tests (code coverage mode)
npm run coverage
openapi.yaml Fileopenapi.yaml file or paste its content.openapi.yaml into Postman:
    openapi.yaml.npm install @openapitools/openapi-generator-cli -g
openapi-generator-cli generate -i openapi.yaml -g <language> -o ./client
<language> with the desired programming language.openapi-generator-cli generate -i openapi.yaml -g <framework> -o ./server
<framework> with the desired framework.npm install -g @stoplight/prism-cli
prism mock openapi.yaml
openapi.yaml or paste its content to check for errors.This guide enables you to view, test, and utilize the API. You can also generate client libraries, server stubs, and run a mock server using the OpenAPI specification.
The project includes a Jenkinsfile for setting up CI/CD pipelines using Jenkins. The Jenkinsfile defines the stages for building, testing, and deploying the backend and frontend applications.
To set up the CI/CD pipelines using Jenkins, follow these steps:
Install Jenkins on your system or use a cloud-based Jenkins service.
Create a new Jenkins pipeline project.
Configure the pipeline to use the Jenkinsfile in the project repository.
Run the pipeline to build, test, and deploy the applications.
The Jenkins pipeline will automatically build the Docker images, run the unit tests, and deploy the applications to a Kubernetes cluster.
http://localhost:4200.localStorage.http://127.0.0.1:8000.pip install -r requirements.txt and npm install.npm cache clean --force and npm install.createsuperuser command.console.log statements in the frontend code to debug.print statements in the backend code to debug.Refer to the README files in the LMS-Backend and LMS-Frontend directories for more detailed information on each part of the system.
These README files contain additional information on how to run, test, and contribute to the project.
We welcome contributions! Feel free to submit issues and create pull requests.
This project is licensed under the MIT License.
If you have any questions or need further assistance, contact us at hoangson091104@gmail.com.
Alternatively, you can also open an issue in the repository here.