How To Install MEAN Stack on AlmaLinux 10
The MEAN stack represents one of the most powerful full-stack JavaScript development frameworks available today. Combining MongoDB, Express.js, Angular, and Node.js, this technology stack enables developers to build robust web applications using JavaScript across all layers. AlmaLinux 10 “Purple Lion” provides an ideal foundation for MEAN stack development, offering enterprise-grade stability, enhanced security features, and long-term support that makes it perfect for both development and production environments.
This comprehensive guide will walk you through the complete installation and configuration process of the MEAN stack on AlmaLinux 10, covering everything from initial system preparation to advanced security configurations and troubleshooting techniques.
Prerequisites and System Requirements
Hardware Requirements
AlmaLinux 10 requires specific hardware specifications to run the MEAN stack efficiently. The minimum system requirements include a 1.1 GHz processor, 2GB of RAM (though 3GB is recommended when running additional services), and at least 20GB of available disk space. For optimal development performance, consider upgrading to 4GB of RAM and a multi-core processor, especially when running concurrent development servers for Angular, Express.js, and MongoDB.
Software Prerequisites
Before beginning the installation process, ensure you have a fresh AlmaLinux 10 installation with root or sudo access. Basic command line knowledge and understanding of web development concepts will be beneficial throughout this process. A stable network connection is essential for downloading packages and accessing repositories during the installation process.
Understanding AlmaLinux 10 Features
Enhanced Performance and Security
AlmaLinux 10 introduces significant improvements over previous versions, featuring the Linux kernel 6.12 with enhanced performance capabilities and advanced security features. The distribution includes an updated development stack with Python 3.12, Ruby 3.3, Node.js 22, and PHP 8.3, making it particularly well-suited for modern web development projects.
The enhanced security framework includes Secure Boot support for both Intel/AMD and ARM architectures, providing additional protection against boot-level attacks. Frame pointers are enabled by default, allowing for advanced system profiling and debugging capabilities that prove invaluable during MEAN stack development.
Architecture and Compatibility
AlmaLinux 10 primarily targets the x86-64-v3 architecture while maintaining backward compatibility with x86-64-v2 systems. This extended hardware support ensures compatibility with legacy systems while taking advantage of modern processor features. The distribution also includes support for post-quantum cryptographic algorithms and enhanced SELinux userspace release 3.8, providing robust security foundations for enterprise applications.
Preparing the System
Initial System Configuration
Begin by updating your AlmaLinux 10 system to ensure all packages are current and security patches are applied:
sudo dnf update -y
sudo dnf install -y git curl wget vim epel-release development-tools
The EPEL repository provides additional packages that are essential for web development, while the development tools group includes compilers and build utilities needed for Node.js native modules.
Firewall Configuration
AlmaLinux 10 uses firewalld for network security management. Configure the firewall to allow traffic on the ports required for MEAN stack development:
sudo firewall-cmd --permanent --add-port=3000/tcp
sudo firewall-cmd --permanent --add-port=4200/tcp
sudo firewall-cmd --permanent --add-port=27017/tcp
sudo firewall-cmd --reload
These commands open port 3000 for Express.js, port 4200 for Angular development server, and port 27017 for MongoDB. The permanent flag ensures these rules persist across system reboots.
SELinux Configuration
SELinux provides mandatory access controls that enhance system security. For development environments, you may need to configure SELinux to allow web applications to function properly:
sudo setsebool -P httpd_can_network_connect 1
sudo setsebool -P httpd_can_network_connect_db 1
These settings allow HTTP services to make network connections and connect to databases, which are essential for MEAN stack applications.
Installing Node.js and npm
NodeSource Repository Setup
AlmaLinux 10 includes Node.js in its default repositories, but installing from NodeSource ensures you get the latest LTS version with optimal compatibility:
curl -fsSL https://rpm.nodesource.com/setup_22.x | sudo bash -
sudo dnf install -y nodejs
This installation method provides Node.js 22.x LTS along with npm (Node Package Manager), which is essential for managing JavaScript dependencies.
Verification and Configuration
Verify the installation by checking the versions of Node.js and npm:
node --version
npm --version
Configure npm to use a global directory that doesn’t require sudo permissions:
mkdir ~/.npm-global
npm config set prefix '~/.npm-global'
echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
This configuration prevents permission issues when installing global packages and follows security best practices.
Installing Essential Global Packages
Install commonly used global packages for MEAN stack development:
npm install -g nodemon express-generator @angular/cli typescript
Nodemon automatically restarts Node.js applications during development, express-generator creates Express.js project scaffolding, Angular CLI manages Angular projects, and TypeScript provides static typing for JavaScript.
Installing and Configuring MongoDB
MongoDB Repository Configuration
Add the official MongoDB repository for AlmaLinux 10 to ensure you receive the latest stable version:
sudo tee /etc/yum.repos.d/mongodb-org-8.0.repo <<EOF
[mongodb-org-8.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/9/mongodb-org/8.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://pgp.mongodb.com/server-8.0.asc
EOF
This configuration creates a repository file that allows DNF to install MongoDB packages directly from the official MongoDB repository.
Resolving OpenSSL Compatibility
AlmaLinux 10 uses OpenSSL v3, which may cause compatibility issues with some MongoDB components. Install the compatibility package first:
sudo dnf install -y mongodb-mongosh-shared-openssl3
sudo dnf install -y mongodb-org
Installing the OpenSSL3-compatible version of mongosh prevents dependency conflicts during the MongoDB installation process.
MongoDB Service Configuration
Enable and start the MongoDB service:
sudo systemctl enable mongod
sudo systemctl start mongod
sudo systemctl status mongod
Verify MongoDB is running correctly by checking the service status. The output should show the service as “active (running)”.
Testing MongoDB Installation
Test the MongoDB installation using the MongoDB shell:
mongosh
Within the MongoDB shell, create a test database and collection:
use testdb
db.testcollection.insertOne({name: "test", value: "Hello MEAN Stack"})
db.testcollection.find()
Exit the MongoDB shell by typing exit
. This test confirms that MongoDB is properly installed and functioning.
MongoDB Security Configuration
Configure MongoDB authentication for production security:
mongosh
use admin
db.createUser({
user: "admin",
pwd: "securepassword",
roles: ["userAdminAnyDatabase", "dbAdminAnyDatabase", "readWriteAnyDatabase"]
})
Edit the MongoDB configuration file to enable authentication:
sudo vi /etc/mongod.conf
Add the following lines to enable security:
security:
authorization: enabled
Restart MongoDB to apply the changes:
sudo systemctl restart mongod
Installing Express.js Framework
Express.js Installation and Project Setup
Express.js installation is straightforward using npm. Create a new project directory and initialize it:
mkdir mean-app && cd mean-app
npm init -y
npm install express cors helmet morgan body-parser mongoose dotenv
These packages provide essential functionality: Express.js for the web framework, CORS for cross-origin requests, Helmet for security headers, Morgan for logging, body-parser for request parsing, Mongoose for MongoDB integration, and dotenv for environment variables.
Creating a Basic Express Application
Create a basic Express.js application structure:
mkdir routes controllers middleware
touch app.js server.js
Create the main application file (app.js
):
const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const morgan = require('morgan');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
require('dotenv').config();
const app = express();
// Middleware
app.use(helmet());
app.use(cors());
app.use(morgan('combined'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
// Database connection
mongoose.connect(process.env.MONGODB_URI || 'mongodb://localhost:27017/meanapp', {
useNewUrlParser: true,
useUnifiedTopology: true
});
// Routes
app.get('/api/test', (req, res) => {
res.json({ message: 'MEAN Stack API is working!' });
});
module.exports = app;
Create the server entry point (server.js
):
const app = require('./app');
const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});
Environment Configuration
Create an environment configuration file (.env
):
PORT=3000
MONGODB_URI=mongodb://localhost:27017/meanapp
NODE_ENV=development
This configuration allows easy switching between development and production environments.
Installing Angular CLI and Framework
Angular CLI Global Installation
Install the Angular CLI globally to access Angular project management tools:
npm install -g @angular/cli
Verify the installation:
ng version
The output should display the Angular CLI version along with Node.js and npm versions.
Creating an Angular Application
Create a new Angular application within your MEAN project:
ng new frontend --routing --style=css
cd frontend
This command creates a new Angular application with routing enabled and CSS for styling. The routing flag sets up Angular Router for single-page application navigation.
Configuring Angular for API Communication
Install the Angular HTTP client for API communication:
npm install @angular/common
Configure the Angular application to communicate with the Express.js backend by creating a service:
ng generate service services/api
Edit the generated service file (src/app/services/api.service.ts
):
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class ApiService {
private baseUrl = 'http://localhost:3000/api';
constructor(private http: HttpClient) { }
testConnection(): Observable<any> {
return this.http.get(`${this.baseUrl}/test`);
}
}
Configuring Angular Development Server
Configure the Angular development server to proxy API requests to the Express.js backend. Create a proxy configuration file (proxy.conf.json
):
{
"/api/*": {
"target": "http://localhost:3000",
"secure": true,
"changeOrigin": true
}
}
Update the Angular development server command in package.json
:
{
"scripts": {
"start": "ng serve --proxy-config proxy.conf.json --host 0.0.0.0"
}
}
This configuration allows external access to the Angular development server and properly routes API calls.
Integrating the MEAN Stack Components
Full Stack Communication Setup
Configure the Angular application to communicate with the Express.js backend. Update the main component (src/app/app.component.ts
):
import { Component, OnInit } from '@angular/core';
import { ApiService } from './services/api.service';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'MEAN Stack Application';
apiResponse: any;
constructor(private apiService: ApiService) {}
ngOnInit() {
this.apiService.testConnection().subscribe(
response => {
this.apiResponse = response;
console.log('API Response:', response);
},
error => {
console.error('API Error:', error);
}
);
}
}
Update the template (src/app/app.component.html
):
<div class="container">
<h1>{{ title }}</h1>
<div *ngIf="apiResponse">
<h2>API Status</h2>
<p>{{ apiResponse.message }}</p>
</div>
</div>
Creating a Sample CRUD Application
Enhance the Express.js backend with a complete CRUD API. Create a model for data management (models/item.js
):
const mongoose = require('mongoose');
const ItemSchema = new mongoose.Schema({
name: {
type: String,
required: true,
trim: true
},
description: {
type: String,
trim: true
},
createdAt: {
type: Date,
default: Date.now
}
});
module.exports = mongoose.model('Item', ItemSchema);
Create API routes (routes/items.js
):
const express = require('express');
const router = express.Router();
const Item = require('../models/item');
// GET all items
router.get('/', async (req, res) => {
try {
const items = await Item.find();
res.json(items);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
// POST create item
router.post('/', async (req, res) => {
try {
const item = new Item(req.body);
await item.save();
res.status(201).json(item);
} catch (error) {
res.status(400).json({ error: error.message });
}
});
module.exports = router;
Development Workflow Setup
Create a development script to run both frontend and backend simultaneously. Install concurrently:
npm install --save-dev concurrently
Update the main package.json
scripts section:
{
"scripts": {
"dev": "concurrently \"npm run server\" \"npm run client\"",
"server": "cd backend && nodemon server.js",
"client": "cd frontend && ng serve --proxy-config proxy.conf.json"
}
}
This setup allows developers to run both the Express.js backend and Angular frontend with a single command, streamlining the development process.
Security Configuration and Best Practices
System-Level Security
AlmaLinux 10 provides enhanced security features that benefit MEAN stack deployments. Configure system-wide cryptographic policies:
sudo update-crypto-policies --set DEFAULT:SHA1
This command ensures that the system uses secure cryptographic algorithms by default.
Application-Level Security
Implement comprehensive security middleware in Express.js:
const rateLimit = require('express-rate-limit');
const mongoSanitize = require('express-mongo-sanitize');
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100 // limit each IP to 100 requests per windowMs
});
app.use(limiter);
app.use(mongoSanitize());
Configure Helmet for security headers:
app.use(helmet({
contentSecurityPolicy: {
directives: {
defaultSrc: ["'self'"],
styleSrc: ["'self'", "'unsafe-inline'"],
scriptSrc: ["'self'"],
imgSrc: ["'self'", "data:", "https:"]
}
}
}));
SSL/TLS Configuration
For production deployments, configure SSL/TLS certificates. Install and configure Let’s Encrypt:
sudo dnf install -y certbot
sudo certbot certonly --standalone -d yourdomain.com
Configure Express.js to use HTTPS:
const https = require('https');
const fs = require('fs');
const options = {
key: fs.readFileSync('/etc/letsencrypt/live/yourdomain.com/privkey.pem'),
cert: fs.readFileSync('/etc/letsencrypt/live/yourdomain.com/fullchain.pem')
};
https.createServer(options, app).listen(443, () => {
console.log('HTTPS Server running on port 443');
});
This configuration ensures encrypted communication between clients and the server.
Testing and Verification
Component Testing
Test each MEAN stack component individually to ensure proper functionality:
# Test Node.js
node -e "console.log('Node.js is working')"
# Test MongoDB
mongosh --eval "db.adminCommand('ismaster')"
# Test Angular CLI
ng version
# Test Express.js
cd backend && npm test
Integration Testing
Create a comprehensive test to verify full-stack communication:
# Start the backend server
cd backend && npm start &
# Start the frontend server
cd frontend && npm start &
# Test API endpoint
curl http://localhost:3000/api/test
# Test frontend
curl http://localhost:4200
Performance Testing
Monitor system resources during MEAN stack operation:
# Monitor system resources
top
htop
iostat -x 1
# Monitor MongoDB performance
mongosh --eval "db.serverStatus()"
# Monitor Node.js process
ps aux | grep node
Troubleshooting Common Issues
Node.js and npm Issues
If you encounter permission errors with npm:
sudo chown -R $(whoami) ~/.npm
sudo chown -R $(whoami) /usr/local/lib/node_modules
For EACCES errors during global package installation:
mkdir ~/.npm-global
npm config set prefix '~/.npm-global'
export PATH=~/.npm-global/bin:$PATH
MongoDB Connection Problems
If MongoDB fails to start, check the log files:
sudo tail -f /var/log/mongodb/mongod.log
Common solutions include checking disk space and fixing permission issues:
sudo chown -R mongod:mongod /var/lib/mongo
sudo chown -R mongod:mongod /var/log/mongodb
Angular Development Server Issues
If the Angular development server fails to start:
# Clear npm cache
npm cache clean --force
# Remove node_modules and reinstall
rm -rf node_modules package-lock.json
npm install
For port binding issues:
# Kill processes using port 4200
sudo lsof -ti:4200 | xargs sudo kill -9
Firewall and Network Issues
If applications cannot communicate across network boundaries:
# Check firewall status
sudo firewall-cmd --list-all
# Add custom port rules
sudo firewall-cmd --permanent --add-port=PORT/tcp
sudo firewall-cmd --reload
For SELinux-related issues:
# Check SELinux denials
sudo ausearch -m AVC -ts recent
# Configure SELinux boolean values
sudo setsebool -P httpd_can_network_connect 1
Production Deployment Considerations
Process Management
For production deployments, use PM2 for process management:
npm install -g pm2
Create a PM2 ecosystem file (ecosystem.config.js
):
module.exports = {
apps: [
{
name: 'mean-backend',
script: 'server.js',
cwd: './backend',
env: {
NODE_ENV: 'production',
PORT: 3000
},
instances: 'max',
exec_mode: 'cluster'
}
]
};
Start the application with PM2:
pm2 start ecosystem.config.js
pm2 startup
pm2 save
Database Optimization
Configure MongoDB for production performance:
sudo nano /etc/mongod.conf
Add performance optimizations:
storage:
wiredTiger:
engineConfig:
cacheSizeGB: 2
collectionConfig:
blockCompressor: snappy
indexConfig:
prefixCompression: true
Application Building and Optimization
Build the Angular application for production:
cd frontend
ng build --configuration production
Configure Express.js to serve the built Angular application:
app.use(express.static(path.join(__dirname, '../frontend/dist')));
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, '../frontend/dist/index.html'));
});
This configuration creates an optimized, single-server deployment suitable for production environments.
Congratulations! You have successfully installed MEAN Stack. Thanks for using this tutorial for installing MEAN Stack on AlmaLinux OS 10 system. For additional help or useful information, we recommend you check the official AlmaLinux website.