{"id":28762810,"url":"https://github.com/learnwithfair/node-host-on-vps","last_synced_at":"2026-01-31T22:31:05.813Z","repository":{"id":293491841,"uuid":"984214453","full_name":"learnwithfair/node-host-on-vps","owner":"learnwithfair","description":"This document provides a comprehensive guide for setting up a MERN (MongoDB, Express, React, Node.js) stack application on a DigitalOcean VPS with Apache as the web server. The application is hosted under the subdomain clientoperation.2ndsource.xyz.","archived":false,"fork":false,"pushed_at":"2025-07-14T03:59:31.000Z","size":514,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-14T06:11:11.245Z","etag":null,"topics":["learnwithfair","mern-develoyment","node-development","rahatul-rabbi","rahatulrabbi","vps-setup"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/learnwithfair.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-05-15T15:12:22.000Z","updated_at":"2025-07-14T03:59:34.000Z","dependencies_parsed_at":"2025-07-14T05:22:32.127Z","dependency_job_id":"abde48d0-c364-43bb-8b65-26fdf3febef6","html_url":"https://github.com/learnwithfair/node-host-on-vps","commit_stats":null,"previous_names":["learnwithfair/node-host-on-vps"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/learnwithfair/node-host-on-vps","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/learnwithfair%2Fnode-host-on-vps","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/learnwithfair%2Fnode-host-on-vps/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/learnwithfair%2Fnode-host-on-vps/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/learnwithfair%2Fnode-host-on-vps/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/learnwithfair","download_url":"https://codeload.github.com/learnwithfair/node-host-on-vps/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/learnwithfair%2Fnode-host-on-vps/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28958341,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-31T22:20:19.638Z","status":"ssl_error","status_checked_at":"2026-01-31T22:18:07.061Z","response_time":128,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["learnwithfair","mern-develoyment","node-development","rahatul-rabbi","rahatulrabbi","vps-setup"],"created_at":"2025-06-17T08:40:51.349Z","updated_at":"2026-01-31T22:31:05.807Z","avatar_url":"https://github.com/learnwithfair.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# MERN STACK DEPLOYMENT GUIDE\r\n\r\n[![Youtube][youtube-shield]][youtube-url]\r\n[![Facebook][facebook-shield]][facebook-url]\r\n[![Instagram][instagram-shield]][instagram-url]\r\n[![LinkedIn][linkedin-shield]][linkedin-url]\r\n\r\nThanks for visiting my GitHub account!\r\n\r\n## Overview\r\nThis document provides a comprehensive guide for setting up a MERN (MongoDB, Express, React, Node.js) stack application with Apache SSL configuration, including automatic HTTPS redirection, reverse proxy for API calls, and PM2 process management on a DigitalOcean VPS with Apache as the web server. The application is hosted under the subdomain `clientoperation.2ndsource.xyz`.\r\n\r\n\r\n## DigitalOcean VPS Configuration for clientoperation.2ndsource.xyz\r\n\r\n\r\n## Table of Contents\r\n- [Overview](#overview)\r\n- [Architecture](#️-architecture)\r\n- [Prerequisites](#-prerequisites)\r\n- [MongoDB Setup](#-mongodb-setup)\r\n  - [Install MongoDB](#install-mongodb)\r\n  - [Configure MongoDB](#configure-mongodb)\r\n  - [Create Database User](#create-database-user)\r\n- [Quick Start](#-quick-start)\r\n  - [Step 1: Apache SSL Configuration](#step-1-apache-ssl-configuration)\r\n  - [Step 2: Enable Required Apache Modules](#step-2-enable-required-apache-modules)\r\n  - [Step 3: Directory Setup](#step-3-directory-setup)\r\n  - [Step 4: Node.js Environment Setup](#step-4-nodejs-environment-setup)\r\n- [Frontend Deployment (In tsstech User)](#-frontend-deployment-in-tsstech-user)\r\n  - [Step 5: Configure and Build React Frontend](#step-5-configure-and-build-react-frontend-i-have-filebrowser)\r\n  - [Deploy Built Files](#deploy-built-files)\r\n- [Backend Deployment (In tsstech User)](#️-backend-deployment-in-tsstech-user)\r\n  - [Step 6: Configure Node.js Backend](#step-6-configure-nodejs-backend-i-have-filebrowser)\r\n  - [Backend Configuration Files](#backend-configuration-files)\r\n    - [server.js: (For testing) Please remove app.use('*');](#serverjs-for-testing-please-remove-appuse)\r\n    - [db.js](#dbjs)\r\n- [Process Management](#-process-management)\r\n  - [Step 7: Configure PM2 Process Manager](#step-7-configure-pm2-process-manager)\r\n  - [Testing Backend](#testing-backend)\r\n- [Service Management](#-service-management)\r\n  - [Step 8: Enable and Start Apache](#step-8-enable-and-start-apache)\r\n- [Testing \u0026 Verification](#-testing--verification)\r\n  - [Step 9: Verify Deployment](#step-9-verify-deployment)\r\n  - [Test Backend Health](#test-backend-health)\r\n  - [Test Frontend Access](#test-frontend-access)\r\n  - [Service Status Checks](#service-status-checks)\r\n- [Maintenance \u0026 Updates](#-maintenance--updates)\r\n  - [Frontend Updates](#frontend-updates)\r\n  - [Backend Updates](#backend-updates)\r\n  - [SSL Certificate Renewal](#ssl-certificate-renewal)\r\n- [Troubleshooting](#-troubleshooting)\r\n  - [Common Issues and Solutions](#common-issues-and-solutions)\r\n    - [1. Apache Configuration Errors](#1-apache-configuration-errors)\r\n    - [2. SSL Certificate Issues](#2-ssl-certificate-issues)\r\n    - [3. Backend Connection Issues](#3-backend-connection-issues)\r\n    - [4. Frontend Not Loading](#4-frontend-not-loading)\r\n  - [Log Locations](#log-locations)\r\n- [Performance Monitoring](#-performance-monitoring)\r\n- [Security Considerations](#-security-considerations)\r\n  - [Firewall Configuration](#firewall-configuration)\r\n  - [File Permissions](#file-permissions)\r\n  - [Environment Variables](#environment-variables)\r\n- [Quick Reference Commands](#-quick-reference-commands)\r\n- [Directory Structure](#-directory-structure)\r\n- [Contributing](#-contributing)\r\n- [License](#-license)\r\n\r\n**System Configuration:**\r\n- **Main Domain:** 2ndsource.xyz\r\n- **Subdomain:** clientoperation.2ndsource.xyz\r\n- **Frontend Port:** 3000 (React)\r\n- **Backend Port:** 5000 (Node.js)\r\n- **Web Server:** Apache with Reverse Proxy\r\n- **Database:** MongoDB\r\n\r\n## DNS Configuration\r\n\r\nEnsure the subdomain points to your VPS IP address by creating an A record:\r\n\r\n| Type | Name | Value | TTL |\r\n|------|------|-------|-----|\r\n| A | clientoperation | [YOUR_VPS_IP_ADDRESS] | 3600 |\r\n\r\n\r\n## 🏗️ Architecture\r\n\r\n```\r\nInternet → Apache (Port 80/443) → Static Files (/var/www/html/clientoperation)\r\n                                → API Proxy → Node.js Backend (Port 5000)\r\n```\r\n\r\n## 📋 Prerequisites\r\n\r\n- Ubuntu/Debian server with sudo access\r\n- Domain name configured (clientoperation.2ndsource.xyz)\r\n- SSL certificates obtained via Let's Encrypt\r\n- Apache2 installed\r\n- Basic familiarity with command line\r\n\r\n## 🍃 MongoDB Setup\r\n\r\nBefore starting the deployment, ensure MongoDB is properly configured:\r\n\r\n### Install MongoDB\r\n\r\n```bash\r\n# Import the public key used by the package management system\r\nwget -qO - https://www.mongodb.org/static/pgp/server-6.0.asc | sudo apt-key add -\r\n\r\n# Create a list file for MongoDB\r\necho \"deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/6.0 multiverse\" | sudo tee /etc/apt/sources.list.d/mongodb-org-6.0.list\r\n\r\n# Reload local package database\r\nsudo apt-get update\r\n\r\n# Install MongoDB packages\r\nsudo apt-get install -y mongodb-org\r\n```\r\n\r\n### Configure MongoDB\r\n\r\n```bash\r\n# Start MongoDB\r\nsudo systemctl start mongod\r\n\r\n# Enable MongoDB to start on boot\r\nsudo systemctl enable mongod\r\n\r\n# Check MongoDB status\r\nsudo systemctl status mongod\r\n```\r\n\r\n### Create Database User\r\n\r\n```bash\r\n# Connect to MongoDB\r\nmongo\r\n\r\n# Switch to admin database\r\nuse admin\r\n\r\n# Create admin user\r\ndb.createUser({\r\n  user: \"adminUser\",\r\n  pwd: \"YourDBPassword\",\r\n  roles: [ { role: \"userAdminAnyDatabase\", db: \"admin\" }, \"readWriteAnyDatabase\" ]\r\n})\r\n\r\n# Create application database\r\nuse ClientOperation\r\n\r\n# Create application user (optional)\r\ndb.createUser({\r\n  user: \"appUser\",\r\n  pwd: \"YourAppPassword\",\r\n  roles: [ { role: \"readWrite\", db: \"ClientOperation\" } ]\r\n})\r\n\r\n# Exit MongoDB shell\r\nexit\r\n```\r\n\r\n## 🚀 Quick Start\r\n\r\n### Step 1: Apache SSL Configuration\r\n\r\nCreate Apache Virtual Host Configuration:\r\n\r\n**File Path:** `/etc/apache2/sites-available/clientoperation.2ndsource.xyz.conf`\r\n\r\n```bash\r\nsudo nano /etc/apache2/sites-available/clientoperation.2ndsource.xyz.conf\r\n```\r\n\r\n**Configuration Content:**\r\n\r\n```apache\r\n# HTTP to HTTPS Redirect\r\n\u003cVirtualHost *:80\u003e\r\n    ServerName clientoperation.2ndsource.xyz\r\n    Redirect permanent / https://clientoperation.2ndsource.xyz/\r\n   RewriteEngine on\r\n   RewriteCond %{SERVER_NAME} =clientoperation.2ndsource.xyz\r\n   RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]\r\n   \r\n\u003c/VirtualHost\u003e\r\n\r\n# HTTPS Virtual Host\r\n\u003cVirtualHost *:443\u003e\r\n    ServerName clientoperation.2ndsource.xyz\r\n    ServerAdmin webmaster@localhost\r\n    \r\n    # SSL Configuration\r\n    SSLEngine on\r\n    SSLCertificateFile /etc/letsencrypt/live/clientoperation.2ndsource.xyz/fullchain.pem\r\n    SSLCertificateKeyFile /etc/letsencrypt/live/clientoperation.2ndsource.xyz/privkey.pem\r\n    Include /etc/letsencrypt/options-ssl-apache.conf\r\n    \r\n    # Log Configuration\r\n    ErrorLog ${APACHE_LOG_DIR}/clientoperation.2ndsource.xyz-error.log\r\n    CustomLog ${APACHE_LOG_DIR}/clientoperation.2ndsource.xyz-access.log combined\r\n    \r\n    # Document Root for React Build\r\n    DocumentRoot /var/www/html/clientoperation\r\n    \r\n    # Static File Serving\r\n    \u003cDirectory \"/var/www/html/clientoperation\"\u003e\r\n        Options Indexes FollowSymLinks\r\n        AllowOverride All\r\n        Require all granted\r\n        \r\n        # React Router SPA Configuration\r\n        RewriteEngine On\r\n        RewriteBase /\r\n        RewriteRule ^index\\.html$ - [L]\r\n        RewriteCond %{REQUEST_FILENAME} !-f\r\n        RewriteCond %{REQUEST_FILENAME} !-d\r\n        RewriteRule . /index.html [L]\r\n    \u003c/Directory\u003e\r\n    \r\n    # MIME Type Configuration\r\n    \u003cFiles \"*.js\"\u003e\r\n        Header set Content-Type \"application/javascript\"\r\n    \u003c/Files\u003e\r\n    \r\n    \u003cFiles \"*.css\"\u003e\r\n        Header set Content-Type \"text/css\"\r\n    \u003c/Files\u003e\r\n    \r\n    # API Reverse Proxy\r\n    ProxyPass /api/ http://localhost:5000/api/\r\n    ProxyPassReverse /api/ http://localhost:5000/api/\r\n\u003c/VirtualHost\u003e\r\n```\r\n\r\n### Step 2: Enable Required Apache Modules\r\n\r\n```bash\r\n# Enable URL rewriting for SPA\r\nsudo a2enmod rewrite\r\n\r\n# Enable HTTP headers modification\r\nsudo a2enmod headers\r\n\r\n# Enable SSL support\r\nsudo a2enmod ssl\r\n\r\n# Enable reverse proxy functionality\r\nsudo a2enmod proxy\r\nsudo a2enmod proxy_http\r\n```\r\n\r\n**Expected Output:**\r\n```\r\nEnabling module rewrite.\r\nEnabling module headers.\r\nEnabling module ssl.\r\nEnabling module proxy.\r\nEnabling module proxy_http.\r\nTo activate the new configuration, you need to run:\r\n  systemctl reload apache2\r\n```\r\n\r\n### Step 3: Directory Setup\r\n\r\n```bash\r\n# Create main web directory\r\nsudo mkdir -p /var/www/html/clientoperation\r\n\r\n# Set proper ownership for Apache\r\nsudo chown -R www-data:www-data /var/www/html/clientoperation\r\n\r\n# Set appropriate permissions\r\nsudo chmod -R 755 /var/www/html/clientoperation\r\n```\r\n\r\n**Directory Structure:**\r\n```\r\n/var/www/html/clientoperation/\r\n├── index.html\r\n├── static/\r\n│   ├── css/\r\n│   ├── js/\r\n│   └── media/\r\n├── manifest.json\r\n└── favicon.ico\r\n```\r\n\r\n### Step 4: Node.js Environment Setup\r\n\r\n```bash\r\n# Install Node.js 18.x\r\ncurl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -\r\nsudo apt-get install -y nodejs\r\n\r\n# Verify installation\r\nnode --version\r\nnpm --version\r\n\r\n# Install PM2 globally for process management\r\nsudo npm install -g pm2\r\n```\r\n\r\n**Expected Output:**\r\n```bash\r\n$ node --version\r\nv18.17.0\r\n$ npm --version\r\n9.6.7\r\n$ pm2 --version\r\n5.3.0\r\n```\r\n\r\n## 🎨 Frontend Deployment (In tsstech User)\r\n\r\n### Step 5: Configure and Build React Frontend (I have filebrowser)\r\n\r\n**Base Path:** `/home/tsstech/nodeapp/clientoperation/frontend`\r\n\r\n```bash\r\n# Navigate to frontend directory\r\ncd /home/tsstech/nodeapp/clientoperation/frontend\r\n\r\n# Create production environment configuration\r\ncat \u003e .env.production \u003c\u003c EOF\r\nREACT_APP_API_URL=https://clientoperation.2ndsource.xyz\r\nREACT_APP_ENV=production\r\nGENERATE_SOURCEMAP=false\r\nEOF\r\n\r\n# Install dependencies\r\nnpm install\r\n\r\n# Create production build\r\nnpm run build\r\n```\r\n\r\n**Build Output Example:**\r\n```\r\nCreating an optimized production build...\r\nCompiled successfully.\r\n\r\nFile sizes after gzip:\r\n  46.61 KB  build/static/js/2.8e5b5f6d.chunk.js\r\n  1.4 KB    build/static/js/main.2f4b5c8a.chunk.js\r\n  1.17 KB   build/static/js/runtime-main.e8e9c4f6.js\r\n  312 B     build/static/css/main.a617e044.chunk.css\r\n\r\nThe build folder is ready to be deployed.\r\n```\r\n\r\n### Deploy Built Files\r\n\r\n```bash\r\n# Copy build files to web directory\r\nsudo cp -r build/* /var/www/html/clientoperation/\r\n\r\n# Set proper ownership\r\nsudo chown -R www-data:www-data /var/www/html/clientoperation/\r\n\r\n# Verify deployment\r\nls -la /var/www/html/clientoperation/\r\n```\r\n\r\n## ⚙️ Backend Deployment (In tsstech User)\r\n\r\n### Step 6: Configure Node.js Backend (I have filebrowser)\r\n\r\n**Base Path:** `/home/tsstech/nodeapp/clientoperation/backend`\r\n\r\n```bash\r\n# Navigate to backend directory\r\ncd /home/tsstech/nodeapp/clientoperation/backend\r\n\r\n# Create production environment file\r\ncat \u003e .env \u003c\u003c EOF\r\nPORT=5000\r\nNODE_ENV=production\r\nFRONTEND_URL=https://clientoperation.2ndsource.xyz\r\n#Add your database and other configurations:\r\n#MONGO_URI=mongodb://localhost:27017/clientoperation\r\nMONGO_URI=mongodb://adminUser:YourDBPassword@localhost:27017/ClientOperation?authSource=admin\r\nJWT_SECRET=your-super-secret-jwt-key\r\nEOF\r\n\r\n# Install production dependencies\r\nnpm install --production\r\n```\r\n\r\n### Backend Configuration Files\r\n\r\n#### server.js: (For testing) Please remove app.use('*');\r\n\r\n```javascript\r\nimport express from 'express';\r\nimport connectDB from './config/db.js';\r\nimport cors from 'cors';\r\nimport dotenv from 'dotenv';\r\n\r\ndotenv.config();\r\nconst app = express();\r\n\r\nconnectDB();\r\n\r\n// Allowed origins for CORS\r\nconst allowedOrigins = [\r\n    'https://clientoperation.2ndsource.xyz', // Production domain\r\n    'http://localhost:3000',                  // React dev server\r\n    'http://localhost:3001'                   // Alternate dev port\r\n];\r\n\r\n// Configure CORS middleware\r\napp.use(cors({\r\n    origin: (origin, callback) =\u003e {\r\n        if (!origin || allowedOrigins.includes(origin)) {\r\n            callback(null, true);\r\n        } else {\r\n            console.log('CORS blocked origin:', origin);\r\n            callback(new Error('Not allowed by CORS'));\r\n        }\r\n    },\r\n    credentials: true,\r\n    methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],\r\n    allowedHeaders: ['Content-Type', 'Authorization', 'Cookie']\r\n}));\r\n\r\n// Health check route\r\napp.get('/api/health', (req, res) =\u003e {\r\n    res.json({\r\n        status: 'OK',\r\n        message: 'Backend server is running',\r\n        timestamp: new Date().toISOString(),\r\n    });\r\n});\r\n\r\n// Error handling middleware\r\napp.use((err, req, res, next) =\u003e {\r\n    console.error('Error:', err.message);\r\n    res.status(500).json({\r\n        error: 'Internal Server Error',\r\n        message: process.env.NODE_ENV === 'development' ? err.message : 'Something went wrong',\r\n    });\r\n});\r\n\r\n// Start server\r\nconst PORT = process.env.PORT || 5001;\r\napp.listen(PORT, () =\u003e {\r\n    console.log(`Server is running on port ${PORT}`);\r\n    console.log(`Environment: ${process.env.NODE_ENV || 'development'}`);\r\n    console.log('Allowed Origins:', allowedOrigins);\r\n});\r\n```\r\n\r\n#### db.js:\r\n\r\n```javascript\r\n// config/db.js\r\nimport mongoose from 'mongoose';\r\nimport dotenv from 'dotenv';\r\n\r\ndotenv.config();\r\n\r\nconst connectDB = async () =\u003e {\r\n    try {\r\n        const conn = await mongoose.connect(process.env.MONGO_URI, {\r\n            useNewUrlParser: true,\r\n            useUnifiedTopology: true,\r\n        });\r\n        console.log(`MongoDB Connected: ${conn.connection.host}`);\r\n    } catch (error) {\r\n        console.error(`MongoDB connection failed: ${error.message}`);\r\n        process.exit(1);\r\n    }\r\n};\r\n\r\nexport default connectDB;\r\n```\r\n\r\n## 🔧 Process Management\r\n\r\n### Step 7: Configure PM2 Process Manager\r\n\r\nCreate PM2 Ecosystem File:\r\n\r\n```bash\r\n# Create PM2 configuration\r\ncat \u003e ecosystem.config.cjs \u003c\u003c EOF\r\nmodule.exports = {\r\n  apps: [{\r\n    name: 'clientoperation-backend',\r\n    script: './server.js',\r\n    instances: 1,\r\n    exec_mode: 'fork',  //For mongoDB atlas use 'cluster' \r\n    env: {\r\n      NODE_ENV: 'production',\r\n      PORT: 5001,\r\n    },\r\n    env_production: {\r\n      NODE_ENV: 'production',\r\n      MONGO_URI: process.env.MONGO_URI,  // Uses .env file\r\n      JWT_SECRET: process.env.JWT_SECRET,\r\n    },\r\n    error_file: './logs/err.log',\r\n    out_file: './logs/out.log',\r\n    log_file: './logs/combined.log',\r\n    time: true\r\n  }]\r\n};\r\nEOF\r\n```\r\n\r\n### Testing Backend\r\n\r\n```bash\r\n# Create logs directory\r\nmkdir -p logs\r\n\r\n# Testing purpose\r\ncd /home/tsstech/nodeapp/clientoperation/backend\r\nnode server.js\r\n```\r\n\r\nIf shown a message like `MongoDB connected:` then everything is okay.\r\n\r\n```bash\r\ncurl http://localhost:5000/api/health\r\n```\r\n\r\nFinally stop server then run below:\r\n\r\n```bash\r\n# Start application with PM2\r\npm2 start ecosystem.config.js\r\n\r\n# Save PM2 configuration\r\npm2 save\r\n\r\n# Setup PM2 to start on system boot\r\npm2 startup\r\n```\r\n\r\n**PM2 Status Output:**\r\n```\r\n┌─────┬──────────────────────────┬─────────────┬──────┬────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐\r\n│ id  │ name                     │ namespace   │ ver  │ mode   │ pid      │ uptime │ ↺    │ status    │ cpu      │ mem      │ user     │ watching │\r\n├─────┼──────────────────────────┼─────────────┼──────┼────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤\r\n│ 0   │ clientoperation-backend  │ default     │ 1.0  │ cluster│ 12345    │ 5m     │ 0    │ online    │ 0%       │ 45.2mb   │ tsstech  │ disabled │\r\n└─────┴──────────────────────────┴─────────────┴──────┴────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘\r\n```\r\n\r\n## 🌐 Service Management\r\n\r\n### Step 8: Enable and Start Apache\r\n\r\n```bash\r\n# Enable the site\r\nsudo a2ensite clientoperation.2ndsource.xyz.conf\r\n\r\n# Test Apache configuration\r\nsudo apache2ctl configtest\r\n\r\n# Restart Apache to apply changes\r\nsudo systemctl restart apache2\r\n\r\n# Enable Apache to start on boot\r\nsudo systemctl enable apache2\r\n```\r\n\r\n**Configuration Test Output:**\r\n```\r\nSyntax OK\r\n```\r\n\r\n## ✅ Testing \u0026 Verification\r\n\r\n### Step 9: Verify Deployment\r\n\r\n#### Test Backend Health:\r\n\r\n```bash\r\n# Test backend directly\r\ncurl http://localhost:5000/api/health\r\n\r\n# Expected response\r\n{\"status\":\"OK\",\"timestamp\":\"2024-01-15T10:30:00.000Z\"}\r\n```\r\n\r\n#### Test Frontend Access:\r\n\r\n```bash\r\n# Test HTTPS redirect\r\ncurl -I http://clientoperation.2ndsource.xyz\r\n\r\n# Expected response\r\nHTTP/1.1 301 Moved Permanently\r\nLocation: https://clientoperation.2ndsource.xyz/\r\n\r\n# Test HTTPS access\r\ncurl -I https://clientoperation.2ndsource.xyz\r\n\r\n# Expected response\r\nHTTP/1.1 200 OK\r\nContent-Type: text/html\r\n```\r\n\r\n#### Service Status Checks:\r\n\r\n```bash\r\n# Check Apache status\r\nsudo systemctl status apache2\r\n\r\n# Check PM2 status\r\npm2 status\r\n\r\n# Check application logs\r\npm2 logs clientoperation-backend --lines 50\r\n```\r\n\r\n## 🔄 Maintenance \u0026 Updates\r\n\r\n### Frontend Updates\r\n\r\n```bash\r\n# Navigate to frontend directory\r\ncd /home/tsstech/nodeapp/clientoperation/frontend\r\n\r\n# Pull latest changes (if using Git)\r\ngit pull origin main\r\n\r\n# Install new dependencies (if any)\r\nnpm install\r\n\r\n# Create new build\r\nnpm run build\r\n\r\n# Deploy updated build\r\nsudo cp -r build/* /var/www/html/clientoperation/\r\nsudo chown -R www-data:www-data /var/www/html/clientoperation/\r\n\r\n# Clear browser cache or add cache-busting\r\nsudo systemctl reload apache2\r\n```\r\n\r\n### Backend Updates\r\n\r\n```bash\r\n# Navigate to backend directory\r\ncd /home/tsstech/nodeapp/clientoperation/backend\r\n\r\n# Pull latest changes\r\ngit pull origin main\r\n\r\n# Install new dependencies\r\nnpm install --production\r\n\r\n# Restart application\r\npm2 restart clientoperation-backend\r\n\r\n# Monitor restart\r\npm2 logs clientoperation-backend --lines 20\r\n```\r\n\r\n### SSL Certificate Renewal\r\n\r\n```bash\r\n# Test certificate renewal (dry run)\r\nsudo certbot renew --dry-run\r\n\r\n# Renew certificates\r\nsudo certbot renew\r\n\r\n# Reload Apache after renewal\r\nsudo systemctl reload apache2\r\n```\r\n\r\n## 🐛 Troubleshooting\r\n\r\n### Common Issues and Solutions\r\n\r\n#### 1. Apache Configuration Errors\r\n\r\n**Problem:** `apache2ctl configtest` fails\r\n\r\n```bash\r\n# Check syntax errors\r\nsudo apache2ctl configtest\r\n\r\n# View detailed error logs\r\nsudo tail -f /var/log/apache2/error.log\r\n```\r\n\r\n**Solution:** Review configuration file for typos or missing modules.\r\n\r\n#### 2. SSL Certificate Issues\r\n\r\n**Problem:** SSL certificate not found\r\n\r\n```bash\r\n# Check certificate files exist\r\nls -la /etc/letsencrypt/live/clientoperation.2ndsource.xyz/\r\n\r\n# Test certificate validity\r\nopenssl x509 -in /etc/letsencrypt/live/clientoperation.2ndsource.xyz/cert.pem -text -noout\r\n```\r\n\r\n#### 3. Backend Connection Issues\r\n\r\n**Problem:** API requests failing\r\n\r\n```bash\r\n# Check if backend is running\r\npm2 status\r\n\r\n# Check backend logs\r\npm2 logs clientoperation-backend\r\n\r\n# Test backend directly\r\ncurl -v http://localhost:5000/api/health\r\n\r\n# Check port binding\r\nnetstat -tlnp | grep :5000\r\n```\r\n\r\n#### 4. Frontend Not Loading\r\n\r\n**Problem:** React app shows blank page\r\n\r\n```bash\r\n# Check if files exist\r\nls -la /var/www/html/clientoperation/\r\n\r\n# Check Apache error logs\r\nsudo tail -f /var/log/apache2/clientoperation.2ndsource.xyz-error.log\r\n\r\n# Check browser console for JavaScript errors\r\n# Verify MIME types are set correctly\r\n```\r\n\r\n### Log Locations\r\n\r\n```bash\r\n# Apache Logs\r\n/var/log/apache2/clientoperation.2ndsource.xyz-error.log\r\n/var/log/apache2/clientoperation.2ndsource.xyz-access.log\r\n\r\n# PM2 Logs\r\n/home/tsstech/nodeapp/clientoperation/backend/logs/err.log\r\n/home/tsstech/nodeapp/clientoperation/backend/logs/out.log\r\n/home/tsstech/nodeapp/clientoperation/backend/logs/combined.log\r\n\r\n# System Logs\r\n/var/log/syslog\r\n/var/log/apache2/error.log\r\n```\r\n\r\n## 📊 Performance Monitoring\r\n\r\n```bash\r\n# Monitor system resources\r\nhtop\r\n\r\n# Monitor Apache processes\r\nps aux | grep apache\r\n\r\n# Monitor Node.js process\r\npm2 monit\r\n\r\n# Check disk usage\r\ndf -h\r\ndu -sh /var/www/html/clientoperation/\r\n```\r\n\r\n## 🔒 Security Considerations\r\n\r\n### Firewall Configuration:\r\n\r\n```bash\r\n# Allow HTTP and HTTPS\r\nsudo ufw allow 80\r\nsudo ufw allow 443\r\n\r\n# Block direct access to Node.js port\r\nsudo ufw deny 5000\r\n```\r\n\r\n### File Permissions:\r\n\r\n```bash\r\n# Ensure proper ownership\r\nsudo chown -R www-data:www-data /var/www/html/clientoperation/\r\nsudo chmod -R 755 /var/www/html/clientoperation/\r\n```\r\n\r\n### Environment Variables:\r\n\r\n- Never commit `.env` files to version control\r\n- Use strong, unique secrets for JWT and database connections\r\n- Regularly rotate API keys and passwords\r\n\r\n## 🔧 Quick Reference Commands\r\n\r\n```bash\r\n# Restart all services\r\nsudo systemctl restart apache2\r\npm2 restart all\r\n\r\n# View all logs\r\nsudo tail -f /var/log/apache2/*error.log\r\npm2 logs\r\n\r\n# Update and deploy\r\ncd /path/to/frontend \u0026\u0026 npm run build \u0026\u0026 sudo cp -r build/* /var/www/html/clientoperation/\r\ncd /path/to/backend \u0026\u0026 pm2 restart clientoperation-backend\r\n\r\n# Check service status\r\nsudo systemctl status apache2\r\npm2 status\r\ncurl -I https://clientoperation.2ndsource.xyz\r\n```\r\n\r\n## 📁 Directory Structure\r\n\r\n```\r\n/var/www/html/clientoperation/\r\n├── index.html\r\n├── static/\r\n│   ├── css/\r\n│   ├── js/\r\n│   └── media/\r\n├── manifest.json\r\n└── favicon.ico\r\n```\r\n\r\n\r\n### Common Commands\r\n\r\n- **Restart Apache:**\r\n  ```bash\r\n  sudo systemctl restart apache2\r\n  ```\r\n\r\n- **Restart MongoDB:**\r\n  ```bash\r\n  sudo systemctl restart mongod\r\n  ```\r\n\r\n- **Restart Node.js Applications:**\r\n  ```bash\r\n  pm2 restart clientoperation-backend\r\n  pm2 restart clientoperation-frontend\r\n  ```\r\n\r\n- **Check Service Status:**\r\n  ```bash\r\n  sudo systemctl status apache2\r\n  sudo systemctl status mongod\r\n  pm2 status\r\n  ```\r\n\r\n- **Test Apache Configuration:**\r\n  ```bash\r\n  sudo apachectl configtest\r\n  ```\r\n\r\n## Security Best Practices\r\n\r\n### Firewall Configuration\r\n\r\n```bash\r\nsudo ufw enable\r\nsudo ufw allow ssh\r\nsudo ufw allow 80\r\nsudo ufw allow 443\r\n```\r\n\r\n### Regular System Updates\r\n\r\n```bash\r\nsudo apt update\r\nsudo apt upgrade\r\n```\r\n\r\n### MongoDB Security\r\n\r\n- Ensure MongoDB is only listening on localhost (default)\r\n- Use strong passwords for all MongoDB users\r\n- Regularly review database users and permissions\r\n\r\n### SSL/TLS Maintenance\r\n\r\n- Certificates will automatically renew via Certbot\r\n- Test renewal process:\r\n  ```bash\r\n  sudo certbot renew --dry-run\r\n  ```\r\n\r\n### Regular Backups\r\n\r\n- Verify backup integrity periodically:\r\n  ```bash\r\n  # Restore to a temporary database for testing\r\n  mongorestore --authenticationDatabase admin -u adminUser -p SecurePassword123 --db test_restore ~/mongodb-backups/[BACKUP_DATE]/clientoperationdb\r\n  ```\r\n\r\n### Important Security Notes\r\n\r\n1. Never expose MongoDB port (27017) to the internet\r\n2. Store sensitive credentials in environment variables, not in code\r\n3. Keep all software updated (Node.js, MongoDB, system packages)\r\n4. Consider implementing rate limiting for API endpoints\r\n5. Implement proper authentication and authorization in your application\r\n\r\n---\r\n\r\n*This documentation was generated on May 28, 2025. Some commands or configurations may need updates based on newer software versions.*\r\n\r\n\r\n\r\n###  **Document: PM2 Setup for Frontend App (clientoperation-frontend)**\r\n\r\n---\r\n\r\n#### Step 1: Navigate to the Frontend Directory\r\n\r\n```bash\r\ncd ~/nodeapp/clientoperation/frontend\r\n```\r\n\r\n---\r\n\r\n#### Step 2: Start the Frontend with PM2\r\n\r\n##### Option A: If you're using `npm run start`\r\n\r\n```bash\r\npm2 start npm --name clientoperation-frontend -- run start\r\n```\r\n\r\n**Expected Output:**\r\n\r\n```\r\n[PM2] Starting /usr/bin/npm in fork_mode (1 instance)\r\n[PM2] Done.\r\n┌─────┬───────────────────────────┬────────┬──────┬─────┬────────┬────────┐\r\n│ id  │ name                      │ mode   │ ↺    │ status │ cpu  │ memory │\r\n├─────┼───────────────────────────┼────────┼──────┼────────┼──────┼────────┤\r\n│ 1   │ clientoperation-frontend │ fork   │ 0    │ online │ 0%   │ 80.0mb │\r\n└─────┴───────────────────────────┴────────┴──────┴────────┴──────┴────────┘\r\n```\r\n\r\n\r\n---\r\n\r\n#### Step 3: Save the PM2 Process List\r\n\r\n```bash\r\npm2 save\r\n```\r\n\r\n**Expected Output:**\r\n\r\n```\r\n[PM2] Saving current process list...\r\n[PM2] Successfully saved in /home/deploy/.pm2/dump.pm2\r\n```\r\n\r\n---\r\n\r\n#### Step 4: Enable PM2 on System Boot\r\n\r\n```bash\r\npm2 startup systemd\r\n```\r\n\r\nThen, run the command it suggests. Example:\r\n\r\n```bash\r\nsudo env PATH=$PATH:/home/deploy/.nvm/versions/node/v18.16.0/bin pm2 startup systemd -u deploy --hp /home/deploy\r\n```\r\n\r\n**Expected Output:**\r\n\r\n```\r\n[PM2] Init system already enabled\r\n[PM2] To setup the startup script, copy/paste the following:\r\nsudo env PATH=... pm2 startup systemd -u deploy --hp /home/deploy\r\n```\r\n\r\n---\r\n\r\n#### Step 5: Restart the Frontend App Any Time\r\n\r\n```bash\r\npm2 restart clientoperation-frontend\r\n```\r\n\r\n**Expected Output:**\r\n\r\n```\r\n[PM2] Applying action restartProcessId on app [clientoperation-frontend](id:1)\r\n  ✓\r\n[PM2] Process successfully restarted\r\n```\r\n\r\n---\r\n\r\n####  Step 6: Check PM2 Status\r\n\r\n```bash\r\npm2 status\r\n```\r\n\r\n**Expected Output:**\r\n\r\n```\r\n┌─────┬───────────────────────────┬────────┬──────┬────────┬──────┬────────┐\r\n│ id  │ name                      │ mode   │ ↺    │ status │ cpu  │ memory │\r\n├─────┼───────────────────────────┼────────┼──────┼────────┼──────┼────────┤\r\n│ 0   │ clientoperation-backend  │ fork   │ 0    │ online │ 0%   │ 102mb  │\r\n│ 1   │ clientoperation-frontend │ fork   │ 0    │ online │ 0%   │ 80mb   │\r\n└─────┴───────────────────────────┴────────┴──────┴────────┴──────┴────────┘\r\n```\r\n\r\n---\r\n\r\n## 🤝 Contributing\r\n\r\nThis documentation provides a complete reference for deploying and maintaining a React/Node.js application with Apache SSL configuration. Keep this guide updated as your infrastructure evolves.\r\n\r\n## 📝 License\r\n\r\nThis deployment guide is provided as-is for educational and operational purposes.\r\n\r\n## Follow Me\r\n\r\n[\u003cimg src='https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/github.svg' alt='github' height='40'\u003e](https://github.com/learnwithfair) [\u003cimg src='https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/facebook.svg' alt='facebook' height='40'\u003e](https://www.facebook.com/learnwithfair/) [\u003cimg src='https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/instagram.svg' alt='instagram' height='40'\u003e](https://www.instagram.com/learnwithfair/) [\u003cimg src='https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/twitter.svg' alt='twitter' height='40'\u003e](https://www.twiter.com/learnwithfair/) [\u003cimg src='https://cdn.jsdelivr.net/npm/simple-icons@3.0.1/icons/youtube.svg' alt='YouTube' height='40'\u003e](https://www.youtube.com/@learnwithfair)\r\n\r\n\u003c!-- MARKDOWN LINKS \u0026 IMAGES --\u003e\r\n\r\n[youtube-shield]: https://img.shields.io/badge/-Youtube-black.svg?style=flat-square\u0026logo=youtube\u0026color=555\u0026logoColor=white\r\n[youtube-url]: https://youtube.com/@learnwithfair\r\n[facebook-shield]: https://img.shields.io/badge/-Facebook-black.svg?style=flat-square\u0026logo=facebook\u0026color=555\u0026logoColor=white\r\n[facebook-url]: https://facebook.com/learnwithfair\r\n[instagram-shield]: https://img.shields.io/badge/-Instagram-black.svg?style=flat-square\u0026logo=instagram\u0026color=555\u0026logoColor=white\r\n[instagram-url]: https://instagram.com/learnwithfair\r\n[linkedin-shield]: https://img.shields.io/badge/-LinkedIn-black.svg?style=flat-square\u0026logo=linkedin\u0026colorB=555\r\n[linkedin-url]: https://www.linkedin.com/in/rahatul-rabbi/\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flearnwithfair%2Fnode-host-on-vps","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flearnwithfair%2Fnode-host-on-vps","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flearnwithfair%2Fnode-host-on-vps/lists"}