Project Outline:
Frontend: A simple HTML form to collect student details (e.g., name, email, course, address).
Backend: Node.js with Express to handle form submission.
Database: MongoDB to store student registration information.
Pre-requisites:
Ensure you have either an Ubuntu instance with Node.js, npm, Docker, and Docker Compose installed, or Docker Desktop installed on Windows or macOS.
In this project we use
Node.js (for running the backend application)
MongoDB (as the database for storing student registration data)
Docker (for containerization of the application)
Docker Compose (for managing multi-container Docker applications)
Install Tools:
Docker and DockerCompose Installation:
#!/bin/bash
# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl -y
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
# Add the repository to Apt sources:
echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
# Install docker
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
sudo systemctl start docker
sudo systemctl enable docker
# Permissions
sudo usermod -aG docker $USER
newgrp docker
sudo chmod 666 /var/run/docker.sock
Node Installation:
#!/bin/bash
# Update the package index
echo "Updating package index..."
sudo apt update
# Install prerequisites
echo "Installing prerequisites..."
sudo apt install -y curl
# Download and install the Node.js v20.x PPA (Personal Package Archive)
echo "Setting up Node.js 20.x repository..."
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
# Install Node.js
echo "Installing Node.js 20..."
sudo apt install -y nodejs
Check point:
node -v
npm -v
docker --version
docker compose version
Steps to Build the Project:
1. Setup the Project Directory
- Create a new folder for the project, e.g.,
student-registration
.
Inside the folder, initialize a Node.js project:
mkdir student-registration
cd student-registration
npm init -y #Creates package.json file
2. Install Required Packages
Install the necessary dependencies:
npm install express mongoose body-parser
3. Create the Node.js App (Backend)
Create a file called server.js
and set up a basic Express server:
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');
const path = require('path');
const app = express();
// Middleware
app.use(bodyParser.json());
// Serve static files from the 'public' directory
app.use(express.static(path.join(__dirname, 'public')));
// MongoDB Connection
mongoose.connect('mongodb://mongo:27017/studentDB', {
useNewUrlParser: true,
useUnifiedTopology: true
}).then(() => {
console.log("Connected to MongoDB");
}).catch((err) => {
console.error("Error connecting to MongoDB", err);
});
// Student Schema
const studentSchema = new mongoose.Schema({
name: String,
email: String,
course: String,
address: String,
date: { type: Date, default: Date.now }
});
const Student = mongoose.model('Student', studentSchema);
// POST route to register a student
app.post('/register', (req, res) => {
const student = new Student({
name: req.body.name,
email: req.body.email,
course: req.body.course,
address: req.body.address
});
student.save()
.then(() => res.status(201).send('Student Registered'))
.catch((err) => res.status(400).send('Error: ' + err));
});
// Serve the HTML form on the root URL
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'public', 'index.html'));
});
// Server listening
const PORT = 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
4. Create a Simple HTML Form (Frontend)
Create a new folder called public
and add below index.html
file for the registration form:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Student Registration Form</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f4f4f4;
margin: 0;
padding: 20px;
}
h1 {
text-align: center;
color: #333;
}
form {
max-width: 600px;
margin: auto;
padding: 20px;
background: #fff;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
label {
display: block;
margin-bottom: 8px;
font-weight: bold;
}
input, select {
width: calc(100% - 22px);
padding: 10px;
margin-bottom: 12px;
border: 1px solid #ddd;
border-radius: 4px;
}
input[type="submit"] {
background-color: #5cb85c;
color: #fff;
border: none;
cursor: pointer;
font-size: 16px;
}
input[type="submit"]:hover {
background-color: #4cae4c;
}
.error {
color: red;
font-size: 14px;
}
</style>
</head>
<body>
<h1>Student Registration Form</h1>
<form id="registrationForm">
<label for="name">Name:</label>
<input type="text" id="name" name="name" required>
<div id="nameError" class="error"></div>
<label for="email">Email:</label>
<input type="email" id="email" name="email" required>
<div id="emailError" class="error"></div>
<label for="address">Address:</label>
<input type="text" id="address" name="address" required>
<div id="addressError" class="error"></div>
<label for="course">Course:</label>
<select id="course" name="course" required>
<option value="">--Select a Course--</option>
<option value="DevOps">DevOps</option>
<option value="Java">Java</option>
<option value=".NET">.NET</option>
<option value="AWS">AWS</option>
<option value="Azure">Azure</option>
</select>
<input type="submit" value="Register">
</form>
<script>
const nameInput = document.getElementById('name');
const emailInput = document.getElementById('email');
const addressInput = document.getElementById('address');
const courseSelect = document.getElementById('course');
const nameError = document.getElementById('nameError');
const emailError = document.getElementById('emailError');
const addressError = document.getElementById('addressError');
const namePattern = /^[a-zA-Z\s]+$/;
const emailPattern = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
const addressPattern = /^.{5,}$/; // Minimum 5 characters for address
function validateName() {
const name = nameInput.value;
if (!namePattern.test(name)) {
nameError.textContent = 'Please enter a valid name (only letters and spaces allowed).';
return false;
} else {
nameError.textContent = '';
return true;
}
}
function validateEmail() {
const email = emailInput.value;
if (!emailPattern.test(email)) {
emailError.textContent = 'Please enter a valid email address.';
return false;
} else {
emailError.textContent = '';
return true;
}
}
function validateAddress() {
const address = addressInput.value;
if (!addressPattern.test(address)) {
addressError.textContent = 'Please enter a valid address (at least 5 characters).';
return false;
} else {
addressError.textContent = '';
return true;
}
}
nameInput.addEventListener('blur', validateName);
emailInput.addEventListener('blur', validateEmail);
addressInput.addEventListener('blur', validateAddress);
document.getElementById('registrationForm').addEventListener('submit', async (e) => {
e.preventDefault(); // Prevent default form submission behavior
const isNameValid = validateName();
const isEmailValid = validateEmail();
const isAddressValid = validateAddress();
if (!isNameValid || !isEmailValid || !isAddressValid) {
alert('Please correct the errors before submitting the form.');
return; // Stop the form from being submitted if any validation fails
}
const formData = {
name: nameInput.value,
email: emailInput.value,
address: addressInput.value,
course: courseSelect.value,
};
try {
const response = await fetch('/register', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(formData)
});
if (response.ok) {
alert('Student Registered Successfully');
// Clear the form after successful submission
document.getElementById('registrationForm').reset();
} else {
alert('Error: ' + await response.text());
}
} catch (error) {
alert('Error submitting the form. Please try again.');
}
});
</script>
</body>
</html>
5. Dockerize the Application
Create a Dockerfile
for the Node.js application:
# Use an official Node.js runtime as a parent image
FROM node:18
# Set the working directory
WORKDIR /usr/src/app
# Copy the package.json and install dependencies
COPY package*.json ./
RUN npm install
# Copy the rest of the application
COPY . .
# Expose port 3000
EXPOSE 3000
# Command to run the application
CMD ["node", "server.js"]
Create a docker-compose.yml
file to define services for Node.js and MongoDB:
services:
app:
build: .
ports:
- "3000:3000"
volumes:
- .:/usr/src/app
depends_on:
- mongo
mongo:
image: mongo:latest
ports:
- "27017:27017"
volumes:
- mongo-data:/data/db
volumes:
mongo-data:
6. Run the Application
In your project directory, run the following command to build and start the services:
docker compose up -d
This will:
Start your Node.js app on port
3000
.Start MongoDB on port
27017
.
7. Access the Form and Register Students
Open your browser and navigate to
http://localhost:3000
to see the student registration form.Submit a form and check the MongoDB database for the stored data.
Here's how you can access the list of registered students:
1. Using MongoDB Shell (CLI)
If MongoDB is running in a container (as part of your Docker Compose setup), follow these steps:
Access the MongoDB Container: Run the following command to enter the MongoDB container:
docker exec -it <mongo_container_id> bash root@bf5740722010:/# mongosh test>
Replace
<mongo_container_id>
with the name of your MongoDB container id (you can get the container ID by runningdocker ps
).see db list
test> show dbs admin 40.00 KiB config 108.00 KiB local 72.00 KiB studentDB 72.00 KiB students 40.00 KiB studentDB>
Select the Database: Inside the MongoDB shell, select the database where your students' data is stored:
use studentDB
show collections
show collections
View the Students Collection: Assuming the student data is stored in a
students
collection, you can list all registered students with:db.students.find().pretty()
To delete all student information
db.students.deleteMany({})