AlmaLinuxRHEL Based

How To Install MEAN Stack on AlmaLinux 10

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.

VPS Manage Service Offer
If you don’t have time to do all of this stuff, or if this is not your area of expertise, we offer a service to do “VPS Manage Service Offer”, starting from $10 (Paypal payment). Please contact us to get the best deal!

r00t

r00t is an experienced Linux enthusiast and technical writer with a passion for open-source software. With years of hands-on experience in various Linux distributions, r00t has developed a deep understanding of the Linux ecosystem and its powerful tools. He holds certifications in SCE and has contributed to several open-source projects. r00t is dedicated to sharing her knowledge and expertise through well-researched and informative articles, helping others navigate the world of Linux with confidence.
Back to top button