How To Install MERN Stack on Ubuntu 24.04 LTS
In this tutorial, we will show you how to install MERN Stack on Ubuntu 24.04 LTS. The MERN stack has become increasingly popular among developers for creating dynamic web applications. This comprehensive guide will walk you through the process of installing and configuring MongoDB, Express.js, React.js, and Node.js on the latest Ubuntu 24.04 LTS. Whether you’re a seasoned developer or just starting your journey into full-stack development, this tutorial provides detailed instructions to help you set up a powerful development environment on one of the most stable Linux distributions available.
Understanding the MERN Stack Architecture
The MERN stack represents a collection of JavaScript-based technologies used to develop web applications. Each component serves a specific purpose in the application development process:
- MongoDB: A NoSQL database that stores data in JSON-like documents with dynamic schemas, providing high performance, high availability, and easy scalability.
- Express.js: A minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications, handling routes, middleware, and HTTP requests.
- React.js: A JavaScript library for building user interfaces, particularly single-page applications. It allows developers to create reusable UI components that update efficiently when data changes.
- Node.js: A JavaScript runtime built on Chrome’s V8 JavaScript engine that executes JavaScript code outside of a web browser, enabling server-side scripting.
The MERN stack offers several advantages over other technology stacks:
- Uses JavaScript throughout the entire application (both client and server)
- JSON format for data transmission across all layers
- Open-source components with active communities
- Excellent performance for real-time applications
- Scalable architecture suitable for both small and enterprise-level projects
Unlike the MEAN stack (which uses Angular instead of React) or LAMP stack (which uses PHP and MySQL), MERN provides a more streamlined experience with JavaScript as the common language across all components.
Prerequisites
Before beginning the installation process, ensure your system meets the following requirements:
System Requirements:
- Ubuntu 24.04 LTS installed and running
- At least 4GB RAM (8GB recommended)
- 10GB free disk space
- Internet connection
User Permissions:
- Administrative (sudo) access to run installation commands
Recommended Background Knowledge:
- Basic Linux command line usage
- Fundamental understanding of JavaScript
- Familiarity with web development concepts
Tools:
- Terminal emulator
- Text editor (Visual Studio Code, Sublime Text, or similar)
- Web browser for testing
Preparing Your Ubuntu 24.04 Environment
Before installing the MERN stack components, it’s essential to prepare your Ubuntu system properly. This ensures compatibility and optimal performance.
First, update your system packages to ensure you have the latest security patches and software versions:
sudo apt update
sudo apt upgrade -y
Next, install essential development tools and dependencies that will be required during the installation process:
sudo apt install -y build-essential curl gnupg git
These packages provide necessary utilities for compiling software, downloading files, verifying package signatures, and version control.
Consider setting up a dedicated directory structure for your MERN projects to keep your work organized:
mkdir ~/mern-projects
cd ~/mern-projects
Step 1: Installing Node.js and NPM
Node.js is the foundation of the MERN stack, providing the runtime environment for JavaScript on the server side. There are several methods to install Node.js on Ubuntu 24.04, but the recommended approach is using the NodeSource repository to get the latest stable version.
Method 1: Using NodeSource Repository (Recommended)
This method provides the most up-to-date version of Node.js:
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt install -y nodejs
After installation, verify that Node.js and npm (which comes bundled with Node.js) are correctly installed by checking their versions:
node -v
npm -v
You should see output showing the installed versions, confirming successful installation.
Method 2: Using Node Version Manager (NVM)
For developers who need to work with multiple Node.js versions, NVM provides greater flexibility:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
source ~/.bashrc
nvm install --lts
nvm use --lts
Important Note About NPM Installation
Do not install npm separately using apt as it may cause conflicts. The NodeSource Node.js package already includes npm. If you need a newer version of npm, update it using npm itself:
sudo npm install -g npm@latest
Setting Up Global npm Configuration
Configure npm to avoid permission issues when installing global packages:
mkdir ~/.npm-global
npm config set prefix '~/.npm-global'
Add the following line to your ~/.bashrc file:
export PATH=~/.npm-global/bin:$PATH
Then refresh your environment:
source ~/.bashrc
Step 2: Installing MongoDB
MongoDB is the database component of the MERN stack. Ubuntu 24.04’s default repositories don’t include the latest MongoDB version, so we’ll add MongoDB’s official repository.
Adding MongoDB Repository
First, import the MongoDB public GPG key to ensure package authenticity:
curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | sudo gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmor
Next, add the MongoDB repository to your system’s sources list:
echo "deb [arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list
Installing MongoDB Packages
Update your package index to include the MongoDB repository and install MongoDB:
sudo apt update
sudo apt install -y mongodb-org
Starting and Securing MongoDB
Start the MongoDB service and enable it to launch automatically at system startup:
sudo systemctl start mongod
sudo systemctl enable mongod
Verify that MongoDB is running properly:
sudo systemctl status mongod
You should see active (running) status in the output.
Basic MongoDB Security Configuration
Create an administrative user for MongoDB to enhance security:
mongosh
In the MongoDB shell, run:
use admin
db.createUser(
{
user: "adminUser",
pwd: "securePassword",
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
}
)
exit
Enable MongoDB authentication by editing the configuration file:
sudo nano /etc/mongod.conf
Add the following lines under the #security: section:
security:
authorization: enabled
Restart MongoDB to apply the changes:
sudo systemctl restart mongod
Step 3: Configuring Express.js
Express.js provides the backend framework for your MERN applications. Let’s set it up in a new project.
Creating a Project Directory
First, create a directory for your Express.js project:
mkdir ~/mern-projects/express-app
cd ~/mern-projects/express-app
Initializing a Node.js Project
Initialize a new Node.js project using npm:
npm init -y
This creates a package.json file that will track your project’s dependencies.
Installing Express.js
Install Express.js and common middleware packages:
npm install express mongoose cors dotenv
These packages provide:
- express: The web framework
- mongoose: MongoDB object modeling tool
- cors: Cross-origin resource sharing middleware
- dotenv: Environment variable management
Creating a Basic Express Server
Create a file named server.js:
nano server.js
Add the following code to create a simple Express server:
const express = require('express');
const cors = require('cors');
const mongoose = require('mongoose');
require('dotenv').config();
// Initialize Express app
const app = express();
const PORT = process.env.PORT || 5000;
// Middleware
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// Connect to MongoDB
mongoose.connect(process.env.MONGODB_URI || 'mongodb://localhost:27017/mern_app')
.then(() => console.log('MongoDB connection established'))
.catch(err => console.log('MongoDB connection error: ', err));
// Routes
app.get('/', (req, res) => {
res.send('MERN Stack API is running');
});
// Start server
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
Create a .env file for environment variables:
nano .env
Add the following content:
PORT=5000
MONGODB_URI=mongodb://localhost:27017/mern_app
Testing Express Server
Start the Express server to verify it’s working correctly:
node server.js
You should see output indicating the server is running and connected to MongoDB.
Step 4: Setting Up React.js
React.js provides the frontend framework for your MERN applications. Let’s set it up.
Installing Create React App
The easiest way to start with React is using the create-react-app tool:
sudo npm install -g create-react-app
Creating a React Application
Navigate to your projects directory and create a new React application:
cd ~/mern-projects
npx create-react-app react-app
This command creates a new directory with a complete React application structure.
Configuring React for Development
Navigate to your React application directory and start the development server:
cd react-app
npm start
Your browser should automatically open to http://localhost:3000
, displaying the default React application page.
Connecting React to Express Backend
For your React app to communicate with your Express backend during development, add a proxy configuration to your React project’s package.json:
nano package.json
Add the following line inside the JSON object:
"proxy": "http://localhost:5000"
This allows your React development server to forward API requests to your Express backend.
Step 5: Building a Simple MERN Application
Now that all components are installed, let’s build a simple application to test our MERN stack.
Creating MongoDB Schema and Models
In your Express project, create a models directory:
cd ~/mern-projects/express-app
mkdir models
nano models/Item.js
Add the following code to define a simple schema:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const ItemSchema = new Schema({
name: {
type: String,
required: true
},
date: {
type: Date,
default: Date.now
}
});
module.exports = Item = mongoose.model('item', ItemSchema);
Building Express.js API Endpoints
Create a routes directory and API file:
mkdir routes
nano routes/api/items.js
Add the following code for CRUD operations:
const express = require('express');
const router = express.Router();
// Item Model
const Item = require('../../models/Item');
// @route GET api/items
// @desc Get All Items
router.get('/', (req, res) => {
Item.find()
.sort({ date: -1 })
.then(items => res.json(items))
.catch(err => res.status(400).json({ success: false, error: err }));
});
// @route POST api/items
// @desc Create An Item
router.post('/', (req, res) => {
const newItem = new Item({
name: req.body.name
});
newItem.save()
.then(item => res.json(item))
.catch(err => res.status(400).json({ success: false, error: err }));
});
module.exports = router;
Update your server.js to use this route:
// Add this line after your middleware setup
app.use('/api/items', require('./routes/api/items'));
Creating React Components
In your React project, create a simple component to interact with the API:
cd ~/mern-projects/react-app/src
mkdir components
nano components/ItemsList.js
Add the following code:
import React, { useState, useEffect } from 'react';
function ItemsList() {
const [items, setItems] = useState([]);
const [isLoading, setIsLoading] = useState(false);
const [itemName, setItemName] = useState('');
// Fetch items on component mount
useEffect(() => {
fetchItems();
}, []);
const fetchItems = async () => {
setIsLoading(true);
try {
const response = await fetch('/api/items');
const data = await response.json();
setItems(data);
} catch (error) {
console.error('Error fetching items:', error);
}
setIsLoading(false);
};
const handleSubmit = async (e) => {
e.preventDefault();
if (!itemName.trim()) return;
try {
const response = await fetch('/api/items', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ name: itemName }),
});
const newItem = await response.json();
setItems([newItem, ...items]);
setItemName('');
} catch (error) {
console.error('Error adding item:', error);
}
};
return (
<div>
<h2>Items List</h2>
<form onSubmit={handleSubmit}>
<input
type="text"
value={itemName}
onChange={(e) => setItemName(e.target.value)}
placeholder="Add new item"
/>
<button type="submit">Add Item</button>
</form>
{isLoading ? (
<p>Loading...</p>
) : (
<ul>
{items.map(item => (
<li key={item._id}>{item.name}</li>
))}
</ul>
)}
</div>
);
}
export default ItemsList;
Update your App.js to include this component:
nano App.js
Modify it to:
import React from 'react';
import './App.css';
import ItemsList from './components/ItemsList';
function App() {
return (
<div className="App">
<header className="App-header">
<h1>MERN Stack Application</h1>
</header>
<main>
<ItemsList />
</main>
</div>
);
}
export default App;
Deployment Strategies
For production deployment, you’ll need to configure your application properly.
Using PM2 for Node.js Process Management
Install PM2 globally:
sudo npm install -g pm2
Create an ecosystem file for PM2:
cd ~/mern-projects/express-app
pm2 ecosystem
Edit the generated ecosystem.config.js file:
nano ecosystem.config.js
Configure it like this:
module.exports = {
apps : [{
name: "mern-app",
script: "server.js",
instances: "max",
env: {
NODE_ENV: "development",
},
env_production: {
NODE_ENV: "production",
}
}]
};
Start your application with PM2:
pm2 start ecosystem.config.js --env production
Setting Up Nginx as a Reverse Proxy
Install Nginx:
sudo apt install -y nginx
Create a new Nginx configuration file:
sudo nano /etc/nginx/sites-available/mern-app
Add the following configuration:
server {
listen 80;
server_name your-domain.com;
location / {
root /home/username/mern-projects/react-app/build;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location /api {
proxy_pass http://localhost:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Enable the site and restart Nginx:
sudo ln -s /etc/nginx/sites-available/mern-app /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
Security Best Practices
Securing your MERN application is crucial for production deployments.
Securing MongoDB
Beyond the initial security setup, consider:
- Implementing IP whitelisting in MongoDB configuration
- Using non-default MongoDB ports
- Regular security audits and updates
API Security Measures
Implement these security practices for your Express API:
- Use Helmet middleware to set security-related HTTP headers:
npm install helmet
Add to your server.js:
const helmet = require('helmet');
app.use(helmet());
- Implement rate limiting to prevent abuse:
npm install express-rate-limit
Add to your server.js:
const rateLimit = require('express-rate-limit');
const apiLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100, // limit each IP to 100 requests per windowMs
message: "Too many requests, please try again later"
});
app.use('/api/', apiLimiter);
- Use environment variables for sensitive information with dotenv
Performance Optimization
Optimize your MERN application for better performance.
MongoDB Optimization
Improve MongoDB performance with these strategies:
- Create appropriate indexes for frequently queried fields:
// In your model or as a migration
YourModel.createIndex({ fieldName: 1 });
- Use projection to retrieve only necessary fields:
Model.find({}, 'field1 field2').then(results => {});
React Optimization
Enhance React performance with these techniques:
- Implement code splitting using React.lazy() and Suspense
- Use the React DevTools Profiler to identify performance bottlenecks
- Optimize component rendering with React.memo for functional components
Troubleshooting Common Issues
Node.js and NPM Issues
If you encounter Node.js or NPM problems:
- Permission errors: Use NVM or configure npm correctly to avoid sudo for global packages
- Dependency conflicts: Try clearing npm cache with
npm cache clean --force
- Version incompatibilities: Use package.json to lock dependency versions
MongoDB Connection Issues
For MongoDB connection problems:
- Service not starting: Check logs with
sudo journalctl -u mongod
- Connection refused: Verify MongoDB is running and listening on the expected port
- Authentication failures: Ensure credentials are correct and the user has appropriate permissions
React Development Server Problems
If your React development server fails:
- Port conflicts: Change the default port by setting
PORT=3001 npm start
- Hot reloading issues: Check for syntax errors in your components
- API connection failures: Verify proxy settings in package.json
Congratulation’s! You have successfully installed MERN. Thanks for using this tutorial for installing the MERN Stack on your Ubuntu 24.04 LTS system. For additional help or useful information, we recommend you check the official MERN website.