AlmaLinuxRHEL Based

How To Install Express.Js on AlmaLinux 10

Install Express.Js on AlmaLinux 10

Express.js stands as one of the most popular and powerful web application frameworks for Node.js, powering millions of applications worldwide. When combined with AlmaLinux 10, a robust and enterprise-grade Linux distribution, developers gain access to a stable, secure, and performance-optimized environment for building modern web applications.

AlmaLinux 10 represents the latest evolution in enterprise Linux distributions, offering enhanced security features, improved performance, and long-term support that makes it ideal for production deployments. The combination of Express.js flexibility and AlmaLinux 10’s reliability creates an exceptional foundation for scalable web development projects.

This comprehensive guide will walk you through every step of installing Express.js on AlmaLinux 10, from initial system preparation to advanced configuration techniques. Whether you’re a seasoned developer or just starting your journey with server-side JavaScript, you’ll discover multiple installation methods, troubleshooting solutions, and optimization strategies that ensure your Express.js applications run smoothly and efficiently.

By the end of this tutorial, you’ll have a fully functional Express.js development environment running on AlmaLinux 10, complete with best practices for security, performance, and maintainability. Let’s begin this exciting journey into modern web development.

Understanding the Prerequisites

System Requirements

Before diving into the installation process, ensure your AlmaLinux 10 system meets the minimum requirements for running Node.js and Express.js applications effectively. Your system should have at least 2GB of RAM, though 4GB or more is recommended for development work involving multiple applications or large projects.

The processor requirements are relatively modest – any modern 64-bit processor will suffice. However, multi-core systems provide better performance when running multiple Node.js processes or handling concurrent connections. Storage requirements depend on your project needs, but allocating at least 20GB of free disk space ensures adequate room for Node.js, npm packages, and your application files.

Administrator privileges are essential for system-level installations. You’ll need either root access or a user account with sudo privileges to install packages, modify system configurations, and manage services. Verify your access level before proceeding with the installation.

Essential Knowledge Base

Familiarity with Linux command-line operations significantly streamlines the installation process. Basic commands like ls, cd, mkdir, and text editors such as nano or vi form the foundation of server management tasks. Understanding file permissions, directory structures, and symbolic links proves invaluable when troubleshooting issues.

JavaScript fundamentals and Node.js concepts enhance your ability to leverage Express.js effectively. While not mandatory for installation, understanding asynchronous programming, modules, and package management accelerates your development workflow. Familiarity with JSON syntax helps when configuring package.json files and application settings.

Package management knowledge, particularly with DNF (Dandified YUM), AlmaLinux 10’s default package manager, enables efficient software installation and updates. Understanding repositories, dependencies, and version management prevents common installation conflicts and ensures system stability.

Pre-installation System Preparation

Begin by updating your AlmaLinux 10 system to ensure all packages reflect the latest security patches and feature updates. Execute the following command to refresh package repositories and upgrade installed software:

sudo dnf update -y

This process may require several minutes, depending on your system’s current state and available updates. The -y flag automatically confirms installation prompts, streamlining the update process.

Install essential development tools that support Node.js compilation and native module building. The “Development Tools” group package provides compilers, build utilities, and libraries required for advanced Node.js features:

sudo dnf groupinstall "Development Tools" -y

Verify network connectivity and DNS resolution, as Node.js installation requires downloading packages from internet repositories. Test connectivity with:

ping -c 4 google.com

Successful responses confirm your system can access external resources necessary for package installation.

Node.js Installation Methods on AlmaLinux 10

Method 1: Installing Node.js via DNF Package Manager

The DNF package manager offers the most straightforward approach to Node.js installation on AlmaLinux 10. This method integrates seamlessly with the system’s package management infrastructure, ensuring compatibility and simplified updates.

Search for available Node.js packages in the official repositories:

dnf search nodejs

Install Node.js and npm (Node Package Manager) simultaneously:

sudo dnf install nodejs npm -y

This command downloads and installs Node.js along with npm, providing everything needed for Express.js development. The installation process automatically resolves dependencies and configures system paths.

Verify the installation by checking installed versions:

node --version
npm --version

Expected output displays version numbers, confirming successful installation. Note that repository versions may lag behind the latest Node.js releases, which could affect compatibility with cutting-edge Express.js features.

The DNF installation method provides excellent system integration and automatic security updates through regular system maintenance. However, version limitations may require alternative installation methods for projects requiring specific Node.js versions.

Method 2: Installing Node.js via NodeSource Repository

NodeSource repository provides access to current Node.js releases, including Long Term Support (LTS) versions recommended for production environments. This method combines repository convenience with version flexibility.

Download and execute the NodeSource repository setup script for Node.js LTS:

curl -fsSL https://rpm.nodesource.com/setup_lts.x | sudo bash -

The script automatically configures repository settings and GPG keys required for secure package installation. Review the script output for any warnings or configuration messages.

Install Node.js using the newly configured repository:

sudo dnf install nodejs -y

NodeSource installations include npm by default, eliminating separate installation steps. Verify the installation:

node --version
npm --version

NodeSource repositories typically provide more recent versions than default system repositories. This approach balances ease of installation with access to modern Node.js features essential for contemporary Express.js development.

Regular updates through DNF maintain security and feature parity with official Node.js releases. The repository automatically handles dependency management and system integration.

Method 3: Using Node Version Manager (NVM)

Node Version Manager (NVM) offers unparalleled flexibility for developers working with multiple Node.js versions or requiring specific version compatibility. This method proves invaluable for testing applications across different Node.js releases.

Download and install NVM using the official installation script:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash

Restart your terminal or source the bashrc file to activate NVM:

source ~/.bashrc

Verify NVM installation:

nvm --version

List available Node.js versions:

nvm list-remote

Install the latest LTS version of Node.js:

nvm install --lts
nvm use --lts

Set the LTS version as default:

nvm alias default lts/*

NVM installations isolate Node.js versions in user directories, preventing system-wide conflicts. Switch between versions seamlessly using nvm use <version> commands. This approach excels in development environments requiring version testing or legacy application support.

Express.js Installation and Setup

Creating Project Structure

Organized project structure forms the foundation of maintainable Express.js applications. Create a dedicated directory for your project and establish logical file organization from the beginning.

Navigate to your preferred development location and create a project directory:

mkdir my-express-app
cd my-express-app

Initialize a new Node.js project with npm:

npm init -y

The -y flag accepts default values for package.json generation. Alternatively, run npm init without flags to customize project metadata interactively. The generated package.json file serves as your project’s configuration hub, managing dependencies, scripts, and metadata.

Create essential project directories:

mkdir routes views public
mkdir public/stylesheets public/javascripts public/images

This structure separates concerns effectively: routes handle application logic, views contain templates, and public directories serve static assets. Consistent organization improves code maintainability and team collaboration.

Edit the package.json file to include project-specific information:

nano package.json

Update fields such as description, author, and keywords to reflect your project’s purpose and facilitate npm registry searches if you plan to publish your application.

Installing Express.js Framework

Express.js installation offers flexibility through local or global approaches. Local installation, recommended for most projects, ensures version consistency and eliminates conflicts between different applications.

Install Express.js locally within your project:

npm install express

This command downloads Express.js and its dependencies into the node_modules directory, updating package.json with dependency information. Local installation ensures your application uses a specific Express.js version, preventing unexpected behavior from system-wide updates.

For development convenience, install additional Express.js middleware and utilities:

npm install express-generator body-parser cors helmet morgan

These packages provide essential functionality:

  • express-generator: Application scaffolding tool
  • body-parser: Request body parsing middleware
  • cors: Cross-Origin Resource Sharing configuration
  • helmet: Security-focused middleware collection
  • morgan: HTTP request logging middleware

Install development dependencies for enhanced debugging and testing:

npm install --save-dev nodemon

Nodemon automatically restarts your application when files change, accelerating development workflows. The --save-dev flag categorizes it as a development dependency, excluding it from production builds.

Update package.json scripts section to include development and production start commands:

{
  "scripts": {
    "start": "node app.js",
    "dev": "nodemon app.js"
  }
}

Express Generator Setup

Express Generator streamlines application creation by providing pre-configured project templates with established best practices and common middleware configurations.

Install Express Generator globally for system-wide accessibility:

sudo npm install -g express-generator

Global installation enables Express Generator usage from any directory, simplifying project creation workflows. Verify installation:

express --version

Create a new Express.js application with EJS templating:

express --view=ejs my-generated-app
cd my-generated-app

Install generated project dependencies:

npm install

Express Generator creates a comprehensive project structure including:

  • app.js: Main application file
  • routes/: Route definition directory
  • views/: Template files
  • public/: Static asset directory
  • bin/www: Server startup script

The generated structure follows Express.js conventions and provides immediate functionality. Start the generated application:

npm start

Access your application at http://localhost:3000 to verify successful setup. The generated application includes basic routing, error handling, and static file serving.

Creating Your First Express.js Application

Basic Express Server Setup

Building a fundamental Express.js server from scratch provides deep understanding of framework mechanics and application architecture. Create a new file named app.js in your project directory:

nano app.js

Implement a basic Express.js server:

const express = require('express');
const app = express();
const port = process.env.PORT || 3000;

// Basic middleware setup
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// Basic route definition
app.get('/', (req, res) => {
  res.json({ 
    message: 'Welcome to Express.js on AlmaLinux 10!',
    timestamp: new Date().toISOString(),
    environment: process.env.NODE_ENV || 'development'
  });
});

// Health check endpoint
app.get('/health', (req, res) => {
  res.status(200).json({
    status: 'healthy',
    uptime: process.uptime(),
    memory: process.memoryUsage()
  });
});

// Error handling middleware
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).json({ 
    error: 'Something went wrong!',
    message: process.env.NODE_ENV === 'development' ? err.message : 'Internal server error'
  });
});

// 404 handler
app.use('*', (req, res) => {
  res.status(404).json({ 
    error: 'Route not found',
    path: req.originalUrl 
  });
});

// Server startup
app.listen(port, () => {
  console.log(`Express server running on port ${port}`);
  console.log(`Environment: ${process.env.NODE_ENV || 'development'}`);
  console.log(`Access your application at: http://localhost:${port}`);
});

module.exports = app;

This implementation demonstrates Express.js fundamentals including middleware configuration, route definition, error handling, and server initialization. The code incorporates environment variable usage for flexible deployment configuration.

Testing and Verification

Thorough testing ensures your Express.js application functions correctly and handles various scenarios appropriately. Multiple testing approaches provide comprehensive verification.

Start your Express.js server:

node app.js

Successful startup displays server information including port number and environment settings. The application remains active, listening for incoming requests.

Open a new terminal window and test using curl:

curl http://localhost:3000
curl http://localhost:3000/health

Expected responses include JSON data confirming server functionality. Test error handling with invalid routes:

curl http://localhost:3000/nonexistent

The 404 response validates proper error handling implementation. For interactive testing, access the application through your web browser at http://localhost:3000.

Monitor server logs in the original terminal window to observe request handling and debug potential issues. Log output provides valuable insights into application behavior and performance characteristics.

Stop the server using Ctrl+C when testing completes. This graceful shutdown prevents resource leaks and ensures clean application termination.

Basic Application Structure

Understanding Express.js application architecture enables effective development and maintenance of complex applications. Well-structured applications separate concerns and promote code reusability.

The app.js file serves as your application’s entry point, coordinating middleware, routes, and configuration. Maintain this file’s focus on high-level application setup rather than detailed business logic.

Route organization becomes crucial as applications grow. Create separate route files for different application areas:

mkdir routes
nano routes/api.js

Implement API routes in the dedicated file:

const express = require('express');
const router = express.Router();

router.get('/users', (req, res) => {
  res.json({ users: [] });
});

router.post('/users', (req, res) => {
  res.status(201).json({ message: 'User created successfully' });
});

module.exports = router;

Import and use route modules in your main application:

const apiRoutes = require('./routes/api');
app.use('/api', apiRoutes);

Static file serving configuration enables delivery of CSS, JavaScript, and image files. Configure static file middleware in your main application:

app.use(express.static('public'));

This configuration serves files from the public directory, making them accessible via direct URL paths. Organize static assets logically within subdirectories for improved maintainability.

Advanced Configuration and Best Practices

Environment Configuration

Professional Express.js applications require environment-specific configurations for database connections, API keys, and operational parameters. Environment variables provide secure, flexible configuration management.

Create environment-specific configuration files:

nano .env.development
nano .env.production

Install the dotenv package for environment variable management:

npm install dotenv

Configure environment variables in your application:

require('dotenv').config();

const config = {
  port: process.env.PORT || 3000,
  database: {
    host: process.env.DB_HOST || 'localhost',
    port: process.env.DB_PORT || 5432,
    name: process.env.DB_NAME || 'myapp'
  },
  jwt: {
    secret: process.env.JWT_SECRET || 'fallback-secret'
  }
};

Environment separation prevents configuration conflicts between development, testing, and production environments. Never commit sensitive environment files to version control systems.

Security considerations mandate careful handling of sensitive configuration data. Use strong, unique values for secrets and API keys. Implement configuration validation to detect missing or invalid environment variables early in the application lifecycle.

Database connection setup varies depending on your chosen database system. Popular options include PostgreSQL, MySQL, and MongoDB. Install appropriate database drivers:

npm install pg  # PostgreSQL
npm install mysql2  # MySQL
npm install mongoose  # MongoDB

Process Management with PM2

Production Express.js deployments benefit significantly from process management tools that ensure application availability, performance monitoring, and automatic restart capabilities. PM2 (Production Process Manager) provides enterprise-grade process management features.

Install PM2 globally for system-wide access:

sudo npm install -g pm2

Create a PM2 configuration file for your application:

nano ecosystem.config.js

Configure PM2 settings:

module.exports = {
  apps: [{
    name: 'my-express-app',
    script: './app.js',
    instances: 'max',
    exec_mode: 'cluster',
    env: {
      NODE_ENV: 'development',
      PORT: 3000
    },
    env_production: {
      NODE_ENV: 'production',
      PORT: 8080
    },
    log_file: './logs/combined.log',
    out_file: './logs/out.log',
    error_file: './logs/error.log',
    log_date_format: 'YYYY-MM-DD HH:mm Z'
  }]
};

Start your application with PM2:

pm2 start ecosystem.config.js --env production

Monitor application status and performance:

pm2 status
pm2 logs
pm2 monit

PM2 provides automatic application restart on crashes, load balancing across CPU cores, and comprehensive logging capabilities. Configure PM2 startup scripts to ensure application availability after system reboots:

pm2 startup
pm2 save

Security Hardening

Security represents a critical aspect of production Express.js deployments. Comprehensive security measures protect applications from common vulnerabilities and attack vectors.

Configure AlmaLinux 10 firewall to restrict access to your Express.js application ports:

sudo firewall-cmd --permanent --add-port=3000/tcp
sudo firewall-cmd --reload

Implement security-focused middleware in your Express.js application:

const helmet = require('helmet');
const rateLimit = require('express-rate-limit');

// Security headers
app.use(helmet());

// Rate limiting
const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100 // limit each IP to 100 requests per windowMs
});
app.use(limiter);

Create a dedicated system user for running Express.js applications, avoiding root execution:

sudo useradd -r -s /bin/false expressjs
sudo chown -R expressjs:expressjs /path/to/your/app

Configure your application to run as the designated user through PM2 or systemd service configurations. This approach limits potential damage from security breaches.

SSL/TLS certificate integration ensures encrypted communication between clients and your Express.js application. Obtain certificates from Certificate Authorities or use Let’s Encrypt for free certificates:

sudo dnf install certbot -y
sudo certbot certonly --standalone -d yourdomain.com

Configure Express.js to use SSL certificates or implement SSL termination through reverse proxy servers like Nginx.

Troubleshooting Common Issues

Installation Problems

Node.js version compatibility issues frequently arise when applications require specific Node.js versions that differ from system-installed versions. Verify your application’s Node.js requirements in package.json and documentation.

Use NVM to install and test different Node.js versions:

nvm install 16.20.0
nvm use 16.20.0
npm install

Package manager conflicts occur when mixing npm, yarn, or other package managers within the same project. Choose one package manager and remove lock files from others:

rm yarn.lock  # If using npm
rm package-lock.json  # If using yarn

Permission denied errors during global package installation stem from npm’s default configuration. Configure npm to use a different directory for global packages:

mkdir ~/.npm-global
npm config set prefix '~/.npm-global'
echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc
source ~/.bashrc

Network and repository access problems prevent package downloads and updates. Verify internet connectivity and DNS resolution. Configure npm to use alternative registries if default registries are inaccessible:

npm config set registry https://registry.npmjs.org/

Runtime Issues

Port binding conflicts prevent Express.js applications from starting when other processes occupy the desired port. Identify processes using specific ports:

sudo netstat -tulpn | grep :3000
sudo lsof -i :3000

Terminate conflicting processes or configure your application to use alternative ports. Implement dynamic port selection in your application code:

const port = process.env.PORT || 3000;

Module not found errors indicate missing dependencies or incorrect import paths. Verify package installation and module resolution:

npm list
npm install missing-package

Check require() statements for correct relative paths and package names. Use absolute paths or path.join() for complex directory structures.

Memory and performance optimization becomes crucial for applications handling high traffic or processing large datasets. Monitor application memory usage:

ps aux | grep node
htop

Implement memory leak detection and garbage collection monitoring in your application code. Consider implementing clustering or load balancing for improved performance.

AlmaLinux-Specific Considerations

SELinux (Security-Enhanced Linux) may interfere with Express.js application functionality by restricting file access or network operations. Check SELinux status and policies:

getenforce
sudo ausearch -m avc -ts recent

Configure SELinux policies to allow Express.js operations or temporarily disable SELinux for testing:

sudo setenforce 0  # Temporary disable

For production environments, create specific SELinux policies rather than disabling security features entirely.

Systemd service integration enables automatic Express.js application startup and system-level management. Create a systemd service file:

sudo nano /etc/systemd/system/my-express-app.service

Configure the service:

[Unit]
Description=My Express.js Application
After=network.target

[Service]
Type=simple
User=expressjs
WorkingDirectory=/path/to/your/app
ExecStart=/usr/bin/node app.js
Restart=on-failure
Environment=NODE_ENV=production

[Install]
WantedBy=multi-user.target

Enable and start the service:

sudo systemctl enable my-express-app.service
sudo systemctl start my-express-app.service

Package dependency conflicts arise when system packages interfere with Node.js modules requiring specific library versions. Use npm’s bundled dependencies or containerization to isolate application dependencies from system libraries.

Performance Optimization and Monitoring

Express.js performance tuning involves multiple strategies ranging from code optimization to system-level configuration adjustments. Implement compression middleware to reduce response sizes:

const compression = require('compression');
app.use(compression());

Configure efficient static file serving with proper caching headers:

app.use(express.static('public', {
  maxAge: '1d',
  etag: true
}));

Application metrics monitoring provides insights into performance bottlenecks and resource utilization patterns. Implement custom metrics collection:

const metrics = {
  requests: 0,
  errors: 0,
  responseTime: []
};

app.use((req, res, next) => {
  const start = Date.now();
  metrics.requests++;
  
  res.on('finish', () => {
    const duration = Date.now() - start;
    metrics.responseTime.push(duration);
  });
  
  next();
});

Resource usage optimization focuses on memory management, CPU utilization, and I/O operations. Implement connection pooling for database operations and cache frequently accessed data:

const NodeCache = require('node-cache');
const cache = new NodeCache({ stdTTL: 600 });

app.get('/api/data', (req, res) => {
  const cachedData = cache.get('data');
  if (cachedData) {
    return res.json(cachedData);
  }
  
  // Fetch data from database
  // Cache the result
  cache.set('data', result);
  res.json(result);
});

Load balancing setup distributes incoming requests across multiple application instances, improving response times and fault tolerance. Configure Nginx as a reverse proxy and load balancer:

sudo dnf install nginx -y
sudo nano /etc/nginx/conf.d/express-app.conf

Nginx configuration:

upstream express_app {
    server 127.0.0.1:3000;
    server 127.0.0.1:3001;
    server 127.0.0.1:3002;
}

server {
    listen 80;
    server_name yourdomain.com;
    
    location / {
        proxy_pass http://express_app;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Maintenance and Updates

Maintaining current Node.js and Express.js versions ensures access to security patches, performance improvements, and new features. Establish regular update schedules and testing procedures.

Monitor security advisories for Node.js and npm packages:

npm audit
npm audit fix

Update Node.js using your chosen installation method. For NVM installations:

nvm install node --reinstall-packages-from=current

For repository installations:

sudo dnf update nodejs npm

Security patch management requires prompt application of critical updates while maintaining application stability. Test updates in development environments before applying to production systems.

Implement automated testing to validate application functionality after updates:

npm test
npm run integration-tests

Backup strategies protect against data loss and enable rapid recovery from system failures. Implement comprehensive backup procedures covering application code, configuration files, databases, and uploaded content:

#!/bin/bash
backup_dir="/backups/$(date +%Y%m%d_%H%M%S)"
mkdir -p "$backup_dir"

# Backup application files
tar -czf "$backup_dir/app.tar.gz" /path/to/your/app

# Backup database
pg_dump myapp > "$backup_dir/database.sql"

# Backup logs
cp -r /var/log/my-express-app "$backup_dir/logs"

Version migration best practices minimize downtime and reduce risks associated with major updates. Plan migration strategies that include rollback procedures, database schema updates, and configuration changes.

Congratulations! You have successfully installed Express.js. Thanks for using this tutorial for installing the Express.js web application framework on AlmaLinux OS 10 system. For additional help or useful information, we recommend you check the official ExpressJS 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