๐ Node.js Development Environment Setup on AlmaLinux: Complete Guide
Ready to build lightning-fast web applications with JavaScript? ๐ Today weโll set up a complete Node.js development environment on AlmaLinux - powering millions of applications including Netflix, LinkedIn, and Uber! Whether youโre building APIs, web apps, or microservices, this guide makes Node.js setup simple and powerful! ๐ฏ
๐ค Why is Node.js on AlmaLinux Important?
Node.js on AlmaLinux delivers incredible benefits:
- ๐ JavaScript everywhere - Use the same language for frontend and backend
- ๐ง Blazing fast performance - Built on Chromeโs V8 engine with event-driven architecture
- ๐ Massive ecosystem - Access to over 2 million packages on npm
- ๐ Enterprise ready - Used by Fortune 500 companies with excellent security
- โญ Perfect scalability - Handle thousands of concurrent connections efficiently
๐ฏ What You Need
Before setting up Node.js on AlmaLinux:
- โ AlmaLinux 9 system (server or desktop)
- โ Root or sudo access
- โ At least 2GB RAM (4GB+ recommended for development)
- โ 5GB+ free disk space
- โ Basic command line knowledge (weโll guide you!)
๐ Step 1: Install Node.js and npm
Letโs get the latest Node.js installed with multiple methods! ๐ ๏ธ
Method 1: Install from AlmaLinux Repository (Quick & Easy)
# Update system packages first
sudo dnf update -y
# Install Node.js and npm from default repository
sudo dnf install -y nodejs npm
# Verify Node.js installation
node --version
# v18.19.1
# Verify npm installation
npm --version
# 10.2.4
# Check installation paths
which node
which npm
echo "โ
Node.js and npm installed from repository!"
Method 2: Install Latest Node.js from NodeSource Repository
# Add NodeSource repository for latest Node.js
curl -fsSL https://rpm.nodesource.com/setup_lts.x | sudo bash -
# Install Node.js (includes npm)
sudo dnf install -y nodejs
# Install additional development tools
sudo dnf install -y gcc-c++ make
# Verify latest Node.js version
node --version
# v20.11.1
# Check npm version
npm --version
# 10.2.4
# Test Node.js installation
node -e "console.log('๐ Node.js is working!')"
echo "โ
Latest Node.js installed from NodeSource!"
Method 3: Install Using Node Version Manager (NVM) - Recommended for Development
# Install NVM (Node Version Manager)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
# Reload bash profile
source ~/.bashrc
# Verify NVM installation
nvm --version
# 0.39.7
# List available Node.js versions
nvm list-remote --lts
# Install latest LTS Node.js
nvm install --lts
# Use the installed version
nvm use --lts
# Set default Node.js version
nvm alias default node
# Verify installation
node --version
npm --version
# Install multiple Node.js versions (example)
nvm install 18
nvm install 20
nvm list
echo "โ
Node.js installed with NVM - multiple versions available!"
๐ง Step 2: Configure Development Environment
Set up essential tools and global packages:
Install Essential Global Packages
# Update npm to latest version
npm install -g npm@latest
# Install essential development tools globally
npm install -g nodemon # Auto-restart server on changes
npm install -g pm2 # Production process manager
npm install -g express-generator # Express.js project generator
npm install -g create-react-app # React application generator
npm install -g @vue/cli # Vue.js CLI
npm install -g typescript # TypeScript compiler
npm install -g ts-node # Run TypeScript directly
npm install -g eslint # JavaScript linter
npm install -g prettier # Code formatter
# Verify global installations
npm list -g --depth=0
# Check nodemon installation
nodemon --version
# Check PM2 installation
pm2 --version
echo "โ
Essential Node.js development tools installed!"
Configure npm and Set Up Development Directory
# Configure npm with your information
npm config set init-author-name "Your Name"
npm config set init-author-email "[email protected]"
npm config set init-license "MIT"
# Check npm configuration
npm config list
# Create development workspace
mkdir -p ~/nodejs-projects
cd ~/nodejs-projects
# Set npm registry (optional - use faster mirror)
# npm config set registry https://registry.npmmirror.com/
# Create .npmrc for project-specific settings
tee ~/.npmrc << 'EOF'
# Global npm configuration
save-exact=true
init-version=1.0.0
init-license=MIT
# Security settings
audit-level=moderate
fund=false
# Performance settings
prefer-offline=true
cache-max=86400000
EOF
echo "โ
Node.js development environment configured!"
๐ Step 3: Create Your First Node.js Application
Build a complete web application from scratch:
Create Express.js Web Application
# Create new project directory
mkdir my-first-node-app
cd my-first-node-app
# Initialize npm project
npm init -y
# Install Express.js framework
npm install express
# Install development dependencies
npm install --save-dev nodemon eslint prettier
# Create main application file
tee app.js << 'EOF'
// My First Node.js Application on AlmaLinux
const express = require('express');
const path = require('path');
const app = express();
const PORT = process.env.PORT || 3000;
// Middleware
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(express.static('public'));
// Routes
app.get('/', (req, res) => {
res.send(`
<h1>๐ Welcome to Node.js on AlmaLinux!</h1>
<p>Your Node.js development environment is working perfectly!</p>
<p><strong>Server Info:</strong></p>
<ul>
<li>Node.js Version: ${process.version}</li>
<li>Platform: ${process.platform}</li>
<li>Architecture: ${process.arch}</li>
<li>Process ID: ${process.pid}</li>
<li>Uptime: ${Math.floor(process.uptime())} seconds</li>
</ul>
<p><a href="/api/status">Check API Status</a> | <a href="/api/system">System Info</a></p>
`);
});
// API Routes
app.get('/api/status', (req, res) => {
res.json({
status: 'success',
message: '๐ Node.js API is running!',
timestamp: new Date().toISOString(),
environment: process.env.NODE_ENV || 'development'
});
});
app.get('/api/system', (req, res) => {
res.json({
nodeVersion: process.version,
platform: process.platform,
architecture: process.arch,
memory: {
total: Math.round(process.memoryUsage().heapTotal / 1024 / 1024) + ' MB',
used: Math.round(process.memoryUsage().heapUsed / 1024 / 1024) + ' MB'
},
uptime: Math.floor(process.uptime()) + ' seconds'
});
});
// Error handling middleware
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({
error: 'Something went wrong!',
message: err.message
});
});
// 404 handler
app.use((req, res) => {
res.status(404).json({
error: 'Page not found',
path: req.path
});
});
// Start server
app.listen(PORT, () => {
console.log(`๐ Server running on http://localhost:${PORT}`);
console.log(`๐ Environment: ${process.env.NODE_ENV || 'development'}`);
console.log(`๐ง Node.js Version: ${process.version}`);
});
module.exports = app;
EOF
# Update package.json scripts
npm pkg set scripts.start="node app.js"
npm pkg set scripts.dev="nodemon app.js"
npm pkg set scripts.test="echo \"No tests specified\" && exit 1"
# Create basic static files
mkdir public
tee public/style.css << 'EOF'
body {
font-family: Arial, sans-serif;
margin: 40px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
.container {
max-width: 800px;
margin: 0 auto;
background: rgba(255,255,255,0.1);
padding: 30px;
border-radius: 10px;
backdrop-filter: blur(10px);
}
EOF
# Test the application
npm run dev &
sleep 3
# Test API endpoints
curl http://localhost:3000
curl http://localhost:3000/api/status
curl http://localhost:3000/api/system
# Kill the test server
pkill -f nodemon
echo "โ
First Node.js application created and tested!"
Set Up Database Connection (MongoDB Example)
# Install MongoDB driver
npm install mongodb mongoose
# Install environment variable manager
npm install dotenv
# Create environment configuration
tee .env << 'EOF'
# Node.js Environment Configuration
NODE_ENV=development
PORT=3000
DB_HOST=localhost
DB_PORT=27017
DB_NAME=mynodeapp
DB_USER=nodeuser
DB_PASS=securepassword123
# Security
JWT_SECRET=your-super-secret-jwt-key-here
SESSION_SECRET=your-session-secret-here
# External APIs
API_BASE_URL=http://localhost:3000/api
EOF
# Create database configuration file
tee config/database.js << 'EOF'
// Database Configuration
require('dotenv').config();
const mongoose = require('mongoose');
const connectDB = async () => {
try {
const mongoURI = process.env.MONGODB_URI ||
`mongodb://${process.env.DB_HOST}:${process.env.DB_PORT}/${process.env.DB_NAME}`;
await mongoose.connect(mongoURI, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
console.log('๐ MongoDB connected successfully');
} catch (error) {
console.error('โ MongoDB connection error:', error.message);
process.exit(1);
}
};
module.exports = connectDB;
EOF
# Create models directory and sample model
mkdir models
tee models/User.js << 'EOF'
// User Model
const mongoose = require('mongoose');
const userSchema = new mongoose.Schema({
name: {
type: String,
required: true,
trim: true
},
email: {
type: String,
required: true,
unique: true,
lowercase: true
},
createdAt: {
type: Date,
default: Date.now
}
});
module.exports = mongoose.model('User', userSchema);
EOF
# Create config directory
mkdir -p config
echo "โ
Database configuration and models created!"
โ Step 4: Set Up Development Tools and Debugging
Configure essential development and debugging tools:
Set Up ESLint and Prettier for Code Quality
# Initialize ESLint configuration
npx eslint --init
# Create .eslintrc.js if not created automatically
tee .eslintrc.js << 'EOF'
module.exports = {
env: {
browser: true,
commonjs: true,
es2021: true,
node: true
},
extends: [
'eslint:recommended'
],
parserOptions: {
ecmaVersion: 'latest'
},
rules: {
'indent': ['error', 4],
'linebreak-style': ['error', 'unix'],
'quotes': ['error', 'single'],
'semi': ['error', 'always'],
'no-unused-vars': 'warn',
'no-console': 'off'
}
};
EOF
# Create Prettier configuration
tee .prettierrc << 'EOF'
{
"semi": true,
"trailingComma": "es5",
"singleQuote": true,
"printWidth": 80,
"tabWidth": 4,
"useTabs": false
}
EOF
# Create .prettierignore
tee .prettierignore << 'EOF'
node_modules/
dist/
build/
*.min.js
package-lock.json
EOF
# Add lint and format scripts to package.json
npm pkg set scripts.lint="eslint ."
npm pkg set scripts.lint:fix="eslint . --fix"
npm pkg set scripts.format="prettier --write ."
npm pkg set scripts.format:check="prettier --check ."
# Test linting and formatting
npm run lint
npm run format
echo "โ
Code quality tools configured!"
Set Up Debugging and Testing Environment
# Install testing framework
npm install --save-dev jest supertest
# Install debugging tools
npm install --save-dev debug
# Create Jest configuration
tee jest.config.js << 'EOF'
module.exports = {
testEnvironment: 'node',
testMatch: ['**/__tests__/**/*.js', '**/?(*.)+(spec|test).js'],
collectCoverageFrom: [
'src/**/*.js',
'!src/**/*.test.js',
'!src/**/node_modules/**'
],
coverageDirectory: 'coverage',
coverageReporters: ['text', 'lcov', 'html']
};
EOF
# Create sample test file
mkdir -p __tests__
tee __tests__/app.test.js << 'EOF'
// Application Tests
const request = require('supertest');
const app = require('../app');
describe('Node.js Application Tests', () => {
test('GET / should return welcome message', async () => {
const response = await request(app)
.get('/')
.expect(200);
expect(response.text).toContain('Welcome to Node.js on AlmaLinux');
});
test('GET /api/status should return JSON status', async () => {
const response = await request(app)
.get('/api/status')
.expect(200)
.expect('Content-Type', /json/);
expect(response.body.status).toBe('success');
expect(response.body.message).toContain('Node.js API is running');
});
test('GET /api/system should return system info', async () => {
const response = await request(app)
.get('/api/system')
.expect(200)
.expect('Content-Type', /json/);
expect(response.body).toHaveProperty('nodeVersion');
expect(response.body).toHaveProperty('platform');
expect(response.body).toHaveProperty('memory');
});
test('GET /nonexistent should return 404', async () => {
const response = await request(app)
.get('/nonexistent')
.expect(404);
expect(response.body.error).toBe('Page not found');
});
});
EOF
# Update test script in package.json
npm pkg set scripts.test="jest"
npm pkg set scripts.test:watch="jest --watch"
npm pkg set scripts.test:coverage="jest --coverage"
# Create VS Code debugging configuration
mkdir -p .vscode
tee .vscode/launch.json << 'EOF'
{
"version": "0.2.0",
"configurations": [
{
"name": "Launch Node.js App",
"type": "node",
"request": "launch",
"program": "${workspaceFolder}/app.js",
"env": {
"NODE_ENV": "development"
},
"console": "integratedTerminal",
"restart": true,
"runtimeExecutable": "node"
},
{
"name": "Debug Tests",
"type": "node",
"request": "launch",
"program": "${workspaceFolder}/node_modules/.bin/jest",
"args": ["--runInBand"],
"console": "integratedTerminal",
"env": {
"NODE_ENV": "test"
}
}
]
}
EOF
# Run tests
npm test
echo "โ
Testing and debugging environment configured!"
๐ฎ Quick Examples
Example 1: Complete REST API with Express.js ๐
# Create REST API project
mkdir nodejs-rest-api
cd nodejs-rest-api
npm init -y
# Install dependencies
npm install express cors helmet morgan compression
npm install --save-dev nodemon
# Create complete REST API
tee server.js << 'EOF'
// Complete REST API with Express.js
const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const morgan = require('morgan');
const compression = require('compression');
const app = express();
const PORT = process.env.PORT || 3000;
// Middleware
app.use(helmet()); // Security headers
app.use(cors()); // Enable CORS
app.use(compression()); // Gzip compression
app.use(morgan('combined')); // Logging
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true }));
// In-memory data store (use database in production)
let users = [
{ id: 1, name: 'John Doe', email: '[email protected]', role: 'admin' },
{ id: 2, name: 'Jane Smith', email: '[email protected]', role: 'user' }
];
// Routes
app.get('/', (req, res) => {
res.json({
message: '๐ Node.js REST API on AlmaLinux',
version: '1.0.0',
endpoints: {
users: '/api/users',
health: '/api/health'
}
});
});
// Health check endpoint
app.get('/api/health', (req, res) => {
res.json({
status: 'healthy',
timestamp: new Date().toISOString(),
uptime: process.uptime(),
memory: process.memoryUsage()
});
});
// GET all users
app.get('/api/users', (req, res) => {
const { page = 1, limit = 10, role } = req.query;
let filteredUsers = users;
if (role) {
filteredUsers = users.filter(user => user.role === role);
}
const startIndex = (page - 1) * limit;
const endIndex = page * limit;
const paginatedUsers = filteredUsers.slice(startIndex, endIndex);
res.json({
users: paginatedUsers,
pagination: {
current: parseInt(page),
total: Math.ceil(filteredUsers.length / limit),
count: paginatedUsers.length,
totalUsers: filteredUsers.length
}
});
});
// GET user by ID
app.get('/api/users/:id', (req, res) => {
const user = users.find(u => u.id === parseInt(req.params.id));
if (!user) {
return res.status(404).json({ error: 'User not found' });
}
res.json(user);
});
// POST create user
app.post('/api/users', (req, res) => {
const { name, email, role = 'user' } = req.body;
if (!name || !email) {
return res.status(400).json({ error: 'Name and email are required' });
}
if (users.some(u => u.email === email)) {
return res.status(409).json({ error: 'Email already exists' });
}
const newUser = {
id: Math.max(...users.map(u => u.id)) + 1,
name,
email,
role,
createdAt: new Date().toISOString()
};
users.push(newUser);
res.status(201).json(newUser);
});
// PUT update user
app.put('/api/users/:id', (req, res) => {
const userId = parseInt(req.params.id);
const userIndex = users.findIndex(u => u.id === userId);
if (userIndex === -1) {
return res.status(404).json({ error: 'User not found' });
}
const { name, email, role } = req.body;
users[userIndex] = { ...users[userIndex], name, email, role, updatedAt: new Date().toISOString() };
res.json(users[userIndex]);
});
// DELETE user
app.delete('/api/users/:id', (req, res) => {
const userId = parseInt(req.params.id);
const userIndex = users.findIndex(u => u.id === userId);
if (userIndex === -1) {
return res.status(404).json({ error: 'User not found' });
}
const deletedUser = users.splice(userIndex, 1)[0];
res.json({ message: 'User deleted', user: deletedUser });
});
// Error handling
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).json({ error: 'Internal server error' });
});
app.use((req, res) => {
res.status(404).json({ error: 'Endpoint not found' });
});
app.listen(PORT, () => {
console.log(`๐ REST API server running on http://localhost:${PORT}`);
console.log(`๐ Health check: http://localhost:${PORT}/api/health`);
console.log(`๐ฅ Users API: http://localhost:${PORT}/api/users`);
});
module.exports = app;
EOF
# Add scripts
npm pkg set scripts.start="node server.js"
npm pkg set scripts.dev="nodemon server.js"
# Test the REST API
npm run dev &
sleep 3
# Test API endpoints
echo "Testing REST API endpoints..."
curl -X GET http://localhost:3000/api/health
curl -X GET http://localhost:3000/api/users
curl -X POST http://localhost:3000/api/users -H "Content-Type: application/json" -d '{"name":"Bob Wilson","email":"[email protected]","role":"user"}'
pkill -f nodemon
echo "โ
Complete REST API created and tested!"
Example 2: Real-time WebSocket Application ๐
# Create WebSocket application
mkdir nodejs-websocket-app
cd nodejs-websocket-app
npm init -y
# Install Socket.IO for WebSockets
npm install express socket.io
# Create real-time chat application
tee server.js << 'EOF'
// Real-time WebSocket Application
const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const path = require('path');
const app = express();
const server = http.createServer(app);
const io = socketIo(server);
const PORT = process.env.PORT || 3000;
// Serve static files
app.use(express.static('public'));
// Store connected users
const connectedUsers = new Map();
const chatHistory = [];
// Socket.IO connection handling
io.on('connection', (socket) => {
console.log(`๐ User connected: ${socket.id}`);
// Handle user join
socket.on('user_join', (userData) => {
connectedUsers.set(socket.id, {
id: socket.id,
name: userData.name || `User${socket.id.substring(0, 6)}`,
joinTime: new Date()
});
// Send chat history to new user
socket.emit('chat_history', chatHistory);
// Broadcast user list update
io.emit('users_update', Array.from(connectedUsers.values()));
// Broadcast join message
const joinMessage = {
type: 'system',
message: `${connectedUsers.get(socket.id).name} joined the chat`,
timestamp: new Date()
};
socket.broadcast.emit('message', joinMessage);
console.log(`๐ค User ${connectedUsers.get(socket.id).name} joined`);
});
// Handle chat messages
socket.on('chat_message', (messageData) => {
const user = connectedUsers.get(socket.id);
if (!user) return;
const message = {
id: Date.now(),
user: user.name,
userId: socket.id,
message: messageData.message,
timestamp: new Date(),
type: 'user'
};
// Store message in history
chatHistory.push(message);
if (chatHistory.length > 100) {
chatHistory.shift(); // Keep only last 100 messages
}
// Broadcast message to all clients
io.emit('message', message);
console.log(`๐ฌ ${user.name}: ${message.message}`);
});
// Handle typing indicator
socket.on('typing', (data) => {
const user = connectedUsers.get(socket.id);
if (user) {
socket.broadcast.emit('user_typing', {
userId: socket.id,
userName: user.name,
isTyping: data.isTyping
});
}
});
// Handle disconnect
socket.on('disconnect', () => {
const user = connectedUsers.get(socket.id);
if (user) {
// Remove user from connected users
connectedUsers.delete(socket.id);
// Broadcast user list update
io.emit('users_update', Array.from(connectedUsers.values()));
// Broadcast leave message
const leaveMessage = {
type: 'system',
message: `${user.name} left the chat`,
timestamp: new Date()
};
socket.broadcast.emit('message', leaveMessage);
console.log(`๐ User ${user.name} disconnected`);
}
});
});
// API endpoints for stats
app.get('/api/stats', (req, res) => {
res.json({
connectedUsers: connectedUsers.size,
totalMessages: chatHistory.length,
uptime: process.uptime(),
serverTime: new Date()
});
});
server.listen(PORT, () => {
console.log(`๐ WebSocket server running on http://localhost:${PORT}`);
console.log(`๐ Stats API: http://localhost:${PORT}/api/stats`);
});
EOF
# Create client-side HTML
mkdir public
tee public/index.html << 'EOF'
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Node.js WebSocket Chat - AlmaLinux</title>
<style>
body { font-family: Arial, sans-serif; margin: 0; background: #f0f0f0; }
.container { max-width: 800px; margin: 0 auto; background: white; height: 100vh; display: flex; flex-direction: column; }
.header { background: #007acc; color: white; padding: 20px; text-align: center; }
.chat-area { flex: 1; padding: 20px; overflow-y: auto; }
.message { margin: 10px 0; padding: 10px; border-radius: 5px; }
.user-message { background: #e3f2fd; }
.system-message { background: #f3e5f5; font-style: italic; }
.input-area { padding: 20px; background: #fafafa; border-top: 1px solid #ddd; }
.input-area input { width: 70%; padding: 10px; border: 1px solid #ddd; border-radius: 5px; }
.input-area button { width: 25%; padding: 10px; background: #007acc; color: white; border: none; border-radius: 5px; margin-left: 10px; cursor: pointer; }
.users-list { background: #f9f9f9; padding: 15px; border-bottom: 1px solid #ddd; }
.typing { font-style: italic; color: #666; }
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>๐ Node.js WebSocket Chat</h1>
<p>Real-time messaging powered by AlmaLinux</p>
</div>
<div class="users-list">
<strong>Online Users:</strong> <span id="usersList">None</span>
</div>
<div class="chat-area" id="chatArea"></div>
<div class="typing" id="typingIndicator"></div>
<div class="input-area">
<input type="text" id="messageInput" placeholder="Type your message..." maxlength="500">
<button onclick="sendMessage()">Send</button>
</div>
</div>
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io();
const chatArea = document.getElementById('chatArea');
const messageInput = document.getElementById('messageInput');
const usersList = document.getElementById('usersList');
const typingIndicator = document.getElementById('typingIndicator');
let userName = prompt('Enter your name:') || 'Anonymous';
let typingTimer;
// Join the chat
socket.emit('user_join', { name: userName });
// Listen for messages
socket.on('message', (data) => {
const messageDiv = document.createElement('div');
messageDiv.className = `message ${data.type}-message`;
messageDiv.innerHTML = `
<strong>${data.user || 'System'}:</strong> ${data.message}
<small style="float: right; color: #666;">${new Date(data.timestamp).toLocaleTimeString()}</small>
`;
chatArea.appendChild(messageDiv);
chatArea.scrollTop = chatArea.scrollHeight;
});
// Listen for chat history
socket.on('chat_history', (history) => {
chatArea.innerHTML = '';
history.forEach(msg => {
socket.emit('message', msg);
});
});
// Listen for user updates
socket.on('users_update', (users) => {
usersList.textContent = users.map(u => u.name).join(', ') || 'None';
});
// Listen for typing indicators
socket.on('user_typing', (data) => {
if (data.isTyping) {
typingIndicator.textContent = `${data.userName} is typing...`;
} else {
typingIndicator.textContent = '';
}
});
// Send message function
function sendMessage() {
const message = messageInput.value.trim();
if (message) {
socket.emit('chat_message', { message });
messageInput.value = '';
socket.emit('typing', { isTyping: false });
}
}
// Handle Enter key
messageInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
sendMessage();
} else {
// Handle typing indicator
socket.emit('typing', { isTyping: true });
clearTimeout(typingTimer);
typingTimer = setTimeout(() => {
socket.emit('typing', { isTyping: false });
}, 1000);
}
});
console.log('๐ Connected to WebSocket server!');
</script>
</body>
</html>
EOF
# Add scripts
npm pkg set scripts.start="node server.js"
npm pkg set scripts.dev="nodemon server.js"
echo "โ
Real-time WebSocket application created!"
echo "Visit: http://localhost:3000 to test the chat application"
Example 3: Production Deployment with PM2 โก
# Production deployment setup
echo "=== Production Deployment with PM2 ==="
# Install PM2 globally if not already installed
npm install -g pm2
# Create production configuration
tee ecosystem.config.js << 'EOF'
module.exports = {
apps: [{
name: 'nodejs-app',
script: './app.js',
instances: 'max',
exec_mode: 'cluster',
env: {
NODE_ENV: 'development',
PORT: 3000
},
env_production: {
NODE_ENV: 'production',
PORT: 8080
},
// Logging
log_file: './logs/combined.log',
out_file: './logs/out.log',
error_file: './logs/error.log',
log_date_format: 'YYYY-MM-DD HH:mm:ss Z',
// Restart policy
restart_delay: 4000,
max_restarts: 10,
min_uptime: '10s',
// Memory and monitoring
max_memory_restart: '500M',
monitoring: true,
// Advanced features
watch: false,
ignore_watch: ['node_modules', 'logs'],
// Health monitoring
health_check_grace_period: 3000,
health_check_fatal_exceptions: true
}]
};
EOF
# Create logs directory
mkdir -p logs
# Create production startup script
tee start-production.sh << 'EOF'
#!/bin/bash
# Production deployment script
echo "๐ Starting Node.js application in production mode..."
# Create logs directory
mkdir -p logs
# Start application with PM2
pm2 start ecosystem.config.js --env production
# Save PM2 configuration
pm2 save
# Setup PM2 to start on boot
pm2 startup
echo "โ
Application started in production mode"
echo "๐ Monitor with: pm2 monit"
echo "๐ Status: pm2 status"
echo "๐ Logs: pm2 logs"
EOF
chmod +x start-production.sh
# Create monitoring and management scripts
tee manage-app.sh << 'EOF'
#!/bin/bash
# Application management script
case "$1" in
start)
echo "Starting application..."
pm2 start ecosystem.config.js --env production
;;
stop)
echo "Stopping application..."
pm2 stop nodejs-app
;;
restart)
echo "Restarting application..."
pm2 restart nodejs-app
;;
reload)
echo "Reloading application (zero-downtime)..."
pm2 reload nodejs-app
;;
status)
pm2 status
;;
logs)
pm2 logs nodejs-app
;;
monit)
pm2 monit
;;
delete)
echo "Deleting application from PM2..."
pm2 delete nodejs-app
;;
*)
echo "Usage: $0 {start|stop|restart|reload|status|logs|monit|delete}"
exit 1
;;
esac
EOF
chmod +x manage-app.sh
# Create health check endpoint in main app if not exists
echo "
// Health check for production monitoring
app.get('/health', (req, res) => {
res.status(200).json({
status: 'healthy',
uptime: process.uptime(),
timestamp: new Date().toISOString(),
version: process.version
});
});
" >> app.js
# Install production security packages
npm install helmet cors compression morgan
echo "โ
Production deployment configuration created!"
echo "๐ Start production: ./start-production.sh"
echo "๐ง Manage app: ./manage-app.sh {start|stop|restart|status|logs}"
echo "๐ Monitor: pm2 monit"
๐จ Fix Common Problems
Problem 1: Node.js Version Issues โ
Symptoms:
- App crashes with โunsupported Node.js versionโ
- Package installation fails
Try this:
# Check current Node.js version
node --version
npm --version
# Update Node.js using NVM
nvm install --lts
nvm use --lts
nvm alias default node
# Clear npm cache
npm cache clean --force
# Rebuild native modules
npm rebuild
# Check for version compatibility
npm ls
npm audit
# Update packages
npm update
Problem 2: Port Already in Use โ
Try this:
# Find process using port 3000
sudo ss -tlnp | grep :3000
# or
sudo lsof -i :3000
# Kill process using the port
sudo fuser -k 3000/tcp
# Use different port in your application
export PORT=3001
node app.js
# Check for processes
ps aux | grep node
pkill -f "node app.js"
Problem 3: Permission Errors with npm โ
Check these things:
# Fix npm permissions (preferred method)
mkdir ~/.npm-global
npm config set prefix '~/.npm-global'
# Add to ~/.bashrc
echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc
source ~/.bashrc
# Alternative: Fix npm folder permissions
sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}
# Check npm configuration
npm config list
npm config get prefix
# Clear npm cache if needed
npm cache clean --force
๐ Simple Commands Summary
Task | Command |
---|---|
๐ง Install Node.js | sudo dnf install nodejs npm |
๐ Check version | node --version |
๐ Create new project | npm init -y |
๐ Install package | npm install package-name |
โ๏ธ Run application | node app.js |
๐ Start with nodemon | nodemon app.js |
๐ List packages | npm list |
๐ก Tips for Success
- Use NVM for version management ๐ - Switch between Node.js versions easily
- Always use package.json ๐ - Track dependencies and scripts properly
- Implement error handling ๐ - Use try-catch and proper middleware
- Use environment variables ๐ - Keep sensitive data in .env files
- Regular updates ๐ - Keep Node.js and packages updated for security
๐ What You Learned
Congratulations! Now you can:
- โ Install and configure Node.js development environment on AlmaLinux
- โ Set up npm package management and development tools
- โ Build complete web applications with Express.js framework
- โ Implement real-time features with WebSocket technology
- โ Deploy and manage production applications with PM2
๐ฏ Why This Matters
Your Node.js development environment on AlmaLinux provides:
- ๐ Full-stack JavaScript development capability with one language everywhere
- ๐ Production-ready platform for building scalable web applications and APIs
- ๐ Enterprise-grade performance with event-driven, non-blocking I/O architecture
- โก Rapid development workflow with hot reloading and modern tooling
Remember: Node.js powers over 30 million websites and applications worldwide - with your AlmaLinux setup, youโre ready to build the next generation of web applications! From simple APIs to complex real-time systems, you now have a professional development environment! โญ
Youโve successfully mastered Node.js development environment setup on AlmaLinux! Your system is now ready for modern JavaScript development with all the tools and optimizations needed for success! ๐