This is a simple full-stack LMS project that I created to practice DevOps deployment.
The project contains a frontend, backend, database, infrastructure code, and CI/CD pipeline. The main goal of this project is to understand how a real web application can be deployed on AWS using DevOps tools.
LearnHub LMS is a basic Learning Management System.
It has:
- A React frontend
- A Node.js/Express backend
- PostgreSQL database
- Docker for backend containerization
- Terraform for AWS infrastructure
- GitHub Actions for CI/CD
- AWS S3 and CloudFront for frontend hosting
- AWS EC2 for backend deployment
- AWS RDS for database
The project follows this simple deployment flow:
User
|
v
CloudFront
|
|-- Frontend files from S3
|
|-- /api requests to EC2 backend
|
v
Docker Backend
|
v
RDS PostgreSQL
- React
- Vite
- TypeScript
- Axios
- React Router
- Node.js
- Express.js
- TypeScript
- Prisma ORM
- PostgreSQL
- JWT Authentication
- Docker
- AWS EC2
- AWS RDS PostgreSQL
- AWS S3
- AWS CloudFront
- AWS SSM
- Terraform
- GitHub Actions
- DockerHub
lms-fullstack-devops-infrastructure
│
├── app
│ ├── backend
│ │ ├── src
│ │ ├── prisma
│ │ ├── Dockerfile
│ │ └── package.json
│ │
│ └── frontend
│ ├── src
│ ├── index.html
│ ├── vite.config.ts
│ └── package.json
│
├── terraform
│ ├── main.tf
│ ├── variables.tf
│ ├── outputs.tf
│ └── versions.tf
│
├── .github
│ └── workflows
│ ├── backend-gitops.yml
│ └── frontend-s3.yml
│
└── README.md
The frontend is deployed using GitHub Actions.
When changes are pushed to the frontend folder:
app/frontend
GitHub Actions will:
- Install frontend dependencies
- Build the React app
- Upload the build files to S3
- Clear the CloudFront cache
The frontend is served to users through CloudFront.
The backend is deployed as a Docker container on an EC2 instance.
When changes are pushed to the backend folder:
app/backend
GitHub Actions will:
- Build the backend Docker image
- Push the image to DockerHub
- Connect to EC2 using AWS SSM
- Pull the latest Docker image
- Stop the old backend container
- Run the new backend container
- Run Prisma database sync
- Check the backend health endpoint
The AWS infrastructure is created using Terraform.
Terraform creates:
- EC2 instance for backend
- RDS PostgreSQL database
- S3 bucket for frontend
- CloudFront distribution
- Security groups
- IAM role for SSM
- CloudFront routing for frontend and backend API
The frontend is served from CloudFront.
API requests go through this path:
/api/*
CloudFront forwards these API requests to the backend running on EC2.
This means the frontend can call the backend using:
/api
instead of directly using the EC2 public IP.
The backend has a health check endpoint:
/health
It is used to check if the backend is running properly.
There is also a readiness endpoint:
/ready
This checks if the backend can connect to the database.
The GitHub Actions workflows need secrets to work properly.
Some required secrets are:
DOCKERHUB_USERNAME
DOCKERHUB_TOKEN
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
AWS_REGION
EC2_INSTANCE_ID
DATABASE_URL
JWT_SECRET
CLIENT_URL
FRONTEND_BUCKET_NAME
CLOUDFRONT_DISTRIBUTION_ID
These secrets should be added in:
GitHub Repository > Settings > Secrets and variables > Actions
Go to the backend folder:
cd app/backendInstall dependencies:
npm installRun the backend:
npm run devBuild the backend:
npm run buildStart the backend:
npm startGo to the frontend folder:
cd app/frontendInstall dependencies:
npm installRun the frontend:
npm run devBuild the frontend:
npm run buildGo to the terraform folder:
cd terraformInitialize Terraform:
terraform initCheck the plan:
terraform planCreate AWS resources:
terraform applyDestroy AWS resources:
terraform destroyFrom this project, I learned how to:
- Structure a full-stack DevOps project
- Deploy a frontend using S3 and CloudFront
- Deploy a backend using Docker on EC2
- Use RDS PostgreSQL as a managed database
- Use Terraform to create AWS infrastructure
- Use GitHub Actions for CI/CD
- Use AWS SSM to deploy without SSH
- Connect frontend and backend through CloudFront routing
This project is mainly for learning and practice.
For a real production project, I should improve:
- Security
- Monitoring
- Logging
- HTTPS for backend origin
- Secret management
- Terraform remote state
- Better error handling
- Backup strategy
- Domain name setup
Also, sensitive files like Terraform state files and secret values should not be committed to GitHub.
This project is a beginner-friendly DevOps deployment of a full-stack LMS application.
It shows how a frontend, backend, database, infrastructure, and CI/CD pipeline work together in a real cloud deployment.