<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Abdallateef Shohdy</title>
    <description>The latest articles on DEV Community by Abdallateef Shohdy (@abdallateef_sa).</description>
    <link>https://dev.to/abdallateef_sa</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2812397%2F48622d71-11ca-489b-816b-9c7139a319a4.jpg</url>
      <title>DEV Community: Abdallateef Shohdy</title>
      <link>https://dev.to/abdallateef_sa</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/abdallateef_sa"/>
    <language>en</language>
    <item>
      <title>🚀 Deploy Node.js Apps on AWS EC2 - Complete Guide</title>
      <dc:creator>Abdallateef Shohdy</dc:creator>
      <pubDate>Sun, 12 Oct 2025 21:19:21 +0000</pubDate>
      <link>https://dev.to/abdallateef_sa/deploy-nodejs-apps-on-aws-ec2-complete-guide-46p9</link>
      <guid>https://dev.to/abdallateef_sa/deploy-nodejs-apps-on-aws-ec2-complete-guide-46p9</guid>
      <description>&lt;h2&gt;
  
  
  📑 Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Architecture Overview&lt;/li&gt;
&lt;li&gt;Request Flow Explained&lt;/li&gt;
&lt;li&gt;systemd vs PM2&lt;/li&gt;
&lt;li&gt;Step by Step Deployment Guide&lt;/li&gt;
&lt;li&gt;Process Management Deep Dive&lt;/li&gt;
&lt;li&gt;Monitoring and Logs&lt;/li&gt;
&lt;li&gt;Troubleshooting and Best Practices&lt;/li&gt;
&lt;li&gt;Summary&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Architecture Overview
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Complete Server Architecture
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────────────────────┐
│                    Internet (External World)            │
│                   https://yourdomain.com                │
└────────────────────────┬────────────────────────────────┘
                         │
                         │ DNS Resolution
                         │
                         ▼
┌─────────────────────────────────────────────────────────┐
│              AWS EC2 Instance (Ubuntu)                  │
│              Public IP: xx.xx.xx.xx                     │
│                                                         │
│  ┌────────────────────────────────────────────────┐     │
│  │         Caddy (Reverse Proxy)                  │     │
│  │         Port 80 (HTTP) → 443 (HTTPS)           │     │
│  │         ✅ Auto SSL Certificate                │     │
│  └──────────────┬─────────────────┬───────────────┘     │
│                 │                 │                     │
│                 │                 │                     │
│     ┌───────────▼──────────┐  ┌──▼──────────────-┐      │
│     │   Frontend (Next.js) │  │  Backend (Node)  │       │
│     │   Port: 3000         │  │  Port: 5000      │      │
│     │   Managed by:        │  │  Managed by:     │      │
│     │   • systemd OR       │  │  • systemd OR    │      │
│     │   • PM2              │  │  • PM2           │      │
│     └──────────────────────┘  └──────────────────┘      │
│                                                         │
│  ┌────────────────────────────────────────────────┐     │
│  │         Operating System Layer                 │     │
│  │         • systemd (init system)                │     │
│  │         • Process monitoring                   │     │
│  │         • Auto-restart on crash                │     │
│  └────────────────────────────────────────────────┘     │
└─────────────────────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Key Components Explained
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Port&lt;/th&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Caddy&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Reverse Proxy &amp;amp; SSL&lt;/td&gt;
&lt;td&gt;80, 443&lt;/td&gt;
&lt;td&gt;Go-based web server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Frontend&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;User Interface&lt;/td&gt;
&lt;td&gt;3000&lt;/td&gt;
&lt;td&gt;Next.js / React&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Backend&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;API / Business Logic&lt;/td&gt;
&lt;td&gt;5000&lt;/td&gt;
&lt;td&gt;Node.js / Express&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;systemd/PM2&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Process Manager&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;Linux service / Node tool&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Request Flow Explained
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How a Request Travels Through Your Server
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Step 1: User Request
┌─────────────────┐
│   User Browser  │  User types: https://yourdomain.com
│   (Chrome/etc)  │
└────────┬────────┘
         │
         │ ① DNS Lookup (domain → IP address)
         │
         ▼
┌─────────────────┐
│   DNS Server    │  Returns: 54.123.45.67 (EC2 Public IP)
└────────┬────────┘
         │
         │ ② HTTPS Request to IP:443
         │
         ▼
┌─────────────────────────────────────────┐
│         AWS EC2 Instance                │
│                                         │
│  Step 3: Caddy Receives Request         │
│  ┌───────────────────────────────┐     │
│  │  Caddy (Port 443)             │     │
│  │  • Terminates SSL             │     │
│  │  • Checks Caddyfile rules     │     │
│  │  • Decides where to route     │     │
│  └──────────┬────────────────────┘     │
│             │                           │
│   ┌─────────┴──────────┐               │
│   │                    │               │
│   │ If route = /       │ If route = /api│
│   │                    │               │
│   ▼                    ▼               │
│  ┌─────────┐      ┌─────────┐         │
│  │Frontend │      │Backend  │         │
│  │localhost│      │localhost│         │
│  │:3000    │      │:5000    │         │
│  │         │      │         │         │
│  │Next.js  │      │Node.js  │         │
│  │App      │      │Express  │         │
│  └────┬────┘      └────┬────┘         │
│       │                │               │
│       │ ④ Process      │ ④ Process     │
│       │   Request      │   Request     │
│       │                │               │
│       ▼                ▼               │
│  ┌─────────┐      ┌─────────┐         │
│  │HTML/CSS/│      │JSON     │         │
│  │JS       │      │Response │         │
│  └────┬────┘      └────┬────┘         │
│       │                │               │
│       └────────┬───────┘               │
│                │                       │
│  ⑤ Response    │                       │
│  back through  │                       │
│  Caddy         │                       │
│  ┌─────────────▼─────────────┐        │
│  │  Caddy adds headers       │        │
│  │  • Security headers       │        │
│  │  • Compression           │        │
│  └─────────────┬─────────────┘        │
└────────────────┼──────────────────────┘
                 │
                 │ ⑥ HTTPS Response
                 │
                 ▼
         ┌─────────────────┐
         │   User Browser  │  Renders the page
         └─────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Request Flow Examples
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Example 1: Frontend Request
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User → https://yourdomain.com
     ↓
Caddy receives on :443
     ↓
Caddyfile rule: yourdomain.com {
    reverse_proxy localhost:3000
}
     ↓
Forwards to Next.js on localhost:3000
     ↓
Next.js returns HTML
     ↓
Caddy sends response back to user
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Example 2: API Request
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User → https://api.yourdomain.com/users
     ↓
Caddy receives on :443
     ↓
Caddyfile rule: api.yourdomain.com {
    reverse_proxy localhost:5000
}
     ↓
Forwards to Node.js backend on localhost:5000
     ↓
Express processes /users endpoint
     ↓
Returns JSON data
     ↓
Caddy sends response back to user
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  systemd vs PM2
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is systemd?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;systemd&lt;/strong&gt; is the &lt;strong&gt;init system&lt;/strong&gt; for Linux. It's responsible for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Starting services when the server boots&lt;/li&gt;
&lt;li&gt;Managing all system processes&lt;/li&gt;
&lt;li&gt;Monitoring and restarting crashed processes&lt;/li&gt;
&lt;li&gt;Managing system logs
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────┐
│     Linux Boot Process              │
│                                     │
│  ① Kernel loads                     │
│       ↓                             │
│  ② systemd starts (PID 1)           │
│       ↓                             │
│  ③ systemd reads service files      │
│     /etc/systemd/system/*.service   │
│       ↓                             │
│  ④ Starts enabled services          │
│     • backend.service               │
│     • frontend.service              │
│     • caddy.service                 │
└─────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What is PM2?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;PM2&lt;/strong&gt; is a &lt;strong&gt;process manager&lt;/strong&gt; specifically for Node.js applications. Features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cluster mode (multi-core CPU usage)&lt;/li&gt;
&lt;li&gt;Zero-downtime reload&lt;/li&gt;
&lt;li&gt;Built-in load balancer&lt;/li&gt;
&lt;li&gt;Rich monitoring dashboard&lt;/li&gt;
&lt;li&gt;Log management
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────┐
│     PM2 Architecture                │
│                                     │
│  PM2 Daemon (God Process)           │
│       │                             │
│       ├── App 1 (backend)           │
│       │    ├── Instance 1           │
│       │    ├── Instance 2           │
│       │    └── Instance 3           │
│       │                             │
│       └── App 2 (frontend)          │
│            └── Instance 1           │
└─────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Comparison Table
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;systemd&lt;/th&gt;
&lt;th&gt;PM2&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Platform&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Linux only&lt;/td&gt;
&lt;td&gt;Cross-platform&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Language&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Any&lt;/td&gt;
&lt;td&gt;Node.js focused&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Clustering&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Manual setup&lt;/td&gt;
&lt;td&gt;Built-in&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Zero-downtime reload&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Monitoring UI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;journalctl (CLI)&lt;/td&gt;
&lt;td&gt;Web dashboard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Memory usage&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Very low&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Complexity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Easy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Auto-start on boot&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Native&lt;/td&gt;
&lt;td&gt;✅ Via systemd&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Log rotation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅ Built-in&lt;/td&gt;
&lt;td&gt;✅ Built-in&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Process restart&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Load balancing&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Best for&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Production servers&lt;/td&gt;
&lt;td&gt;Node.js apps&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  When to Use What?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Use systemd when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You want minimal dependencies&lt;/li&gt;
&lt;li&gt;You're comfortable with Linux tools&lt;/li&gt;
&lt;li&gt;You have non-Node.js services too&lt;/li&gt;
&lt;li&gt;You want tight OS integration&lt;/li&gt;
&lt;li&gt;You prefer standard Linux tools&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Use PM2 when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need cluster mode (multi-core)&lt;/li&gt;
&lt;li&gt;You want zero-downtime deployments&lt;/li&gt;
&lt;li&gt;You need advanced monitoring&lt;/li&gt;
&lt;li&gt;You want easier log management&lt;/li&gt;
&lt;li&gt;Your team prefers Node.js tools&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Use BOTH when:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You want PM2 features + systemd reliability&lt;/li&gt;
&lt;li&gt;PM2 managed by systemd for auto-restart&lt;/li&gt;
&lt;li&gt;Best of both worlds approach&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step by Step Deployment Guide
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prerequisites Checklist
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] AWS EC2 instance running Ubuntu 22.04+&lt;/li&gt;
&lt;li&gt;[ ] SSH key for access&lt;/li&gt;
&lt;li&gt;[ ] Domain name configured (optional but recommended)&lt;/li&gt;
&lt;li&gt;[ ] Security Group allows ports: 22 (SSH), 80 (HTTP), 443 (HTTPS)&lt;/li&gt;
&lt;li&gt;[ ] Git repositories ready (backend &amp;amp; frontend)&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Part 1: Initial Server Setup
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1.1 Connect to EC2
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# From your local machine&lt;/span&gt;
ssh &lt;span class="nt"&gt;-i&lt;/span&gt; /path/to/your-key.pem ubuntu@your-ec2-ip

&lt;span class="c"&gt;# Example:&lt;/span&gt;
ssh &lt;span class="nt"&gt;-i&lt;/span&gt; ~/aws-keys/my-app-key.pem ubuntu@54.123.45.67
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  1.2 Update System
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt upgrade &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  1.3 Install Essential Tools
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; git curl build-essential
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  1.4 Configure Firewall
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Enable firewall&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw &lt;span class="nb"&gt;enable&lt;/span&gt;

&lt;span class="c"&gt;# Allow SSH (important - don't lock yourself out!)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow 22/tcp

&lt;span class="c"&gt;# Allow HTTP &amp;amp; HTTPS&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow 80/tcp
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow 443/tcp

&lt;span class="c"&gt;# Check status&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Part 2: Install Node.js
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install Node.js LTS (v20.x)&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://deb.nodesource.com/setup_20.x | &lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; bash -
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; nodejs

&lt;span class="c"&gt;# Verify installation&lt;/span&gt;
node &lt;span class="nt"&gt;-v&lt;/span&gt;  &lt;span class="c"&gt;# Should show v20.x.x&lt;/span&gt;
npm &lt;span class="nt"&gt;-v&lt;/span&gt;   &lt;span class="c"&gt;# Should show 10.x.x&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Part 3: Clone and Setup Backend
&lt;/h3&gt;

&lt;h4&gt;
  
  
  3.1 Clone Repository
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /home/ubuntu
git clone https://github.com/yourusername/backend-app.git
&lt;span class="nb"&gt;cd &lt;/span&gt;backend-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3.2 Create Environment File
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano .env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add your configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PORT=5000
NODE_ENV=production

# Database
MONGO_URI=mongodb+srv://username:password@cluster.mongodb.net/dbname
# or
DATABASE_URL=postgresql://user:pass@host:5432/db

# Security
JWT_SECRET=your-super-secret-jwt-key-change-this
JWT_EXPIRE=7d

# API Keys
STRIPE_SECRET_KEY=sk_live_xxxxx
SENDGRID_API_KEY=SG.xxxxx

# CORS
ALLOWED_ORIGINS=https://yourdomain.com,https://www.yourdomain.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Security tip:&lt;/strong&gt; Make sure .env is in .gitignore!&lt;/p&gt;

&lt;h4&gt;
  
  
  3.3 Install Dependencies
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--production&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3.4 Test Backend Locally
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Test run&lt;/span&gt;
npm start

&lt;span class="c"&gt;# You should see something like:&lt;/span&gt;
&lt;span class="c"&gt;# Server running on port 5000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Press &lt;code&gt;Ctrl + C&lt;/code&gt; to stop.&lt;/p&gt;




&lt;h3&gt;
  
  
  Part 4: Clone and Setup Frontend
&lt;/h3&gt;

&lt;h4&gt;
  
  
  4.1 Clone Repository
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /home/ubuntu
git clone https://github.com/yourusername/frontend-app.git
&lt;span class="nb"&gt;cd &lt;/span&gt;frontend-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  4.2 Create Environment File
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano .env.production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add your configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# API Configuration
NEXT_PUBLIC_API_URL=https://api.yourdomain.com
NEXT_PUBLIC_API_TIMEOUT=10000

# App Configuration
NEXT_PUBLIC_APP_NAME=My Awesome App
NEXT_PUBLIC_APP_URL=https://yourdomain.com

# Analytics (optional)
NEXT_PUBLIC_GA_ID=G-XXXXXXXXXX

# Feature Flags
NEXT_PUBLIC_ENABLE_FEATURE_X=true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  4.3 Install and Build
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install
&lt;/span&gt;npm run build

&lt;span class="c"&gt;# This creates the .next folder with optimized production build&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  4.4 Test Frontend Locally
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm start

&lt;span class="c"&gt;# Should start on port 3000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Press &lt;code&gt;Ctrl + C&lt;/code&gt; to stop.&lt;/p&gt;




&lt;h3&gt;
  
  
  Part 5: Process Management - Option A (systemd)
&lt;/h3&gt;

&lt;h4&gt;
  
  
  5.1 Create Backend Service
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/systemd/system/backend.service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add this configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[Unit]&lt;/span&gt;
&lt;span class="py"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Backend API Service&lt;/span&gt;
&lt;span class="py"&gt;Documentation&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;https://github.com/yourusername/backend-app&lt;/span&gt;
&lt;span class="py"&gt;After&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;network.target&lt;/span&gt;

&lt;span class="nn"&gt;[Service]&lt;/span&gt;
&lt;span class="py"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;simple&lt;/span&gt;
&lt;span class="py"&gt;User&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;ubuntu&lt;/span&gt;
&lt;span class="py"&gt;WorkingDirectory&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/home/ubuntu/backend-app&lt;/span&gt;
&lt;span class="py"&gt;EnvironmentFile&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/home/ubuntu/backend-app/.env&lt;/span&gt;
&lt;span class="py"&gt;ExecStart&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/usr/bin/node /home/ubuntu/backend-app/src/server.js&lt;/span&gt;

&lt;span class="c"&gt;# Restart policy
&lt;/span&gt;&lt;span class="py"&gt;Restart&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;always&lt;/span&gt;
&lt;span class="py"&gt;RestartSec&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;10&lt;/span&gt;

&lt;span class="c"&gt;# Resource limits
&lt;/span&gt;&lt;span class="py"&gt;LimitNOFILE&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;65536&lt;/span&gt;

&lt;span class="c"&gt;# Security
&lt;/span&gt;&lt;span class="py"&gt;NoNewPrivileges&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;PrivateTmp&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;

&lt;span class="c"&gt;# Logging
&lt;/span&gt;&lt;span class="py"&gt;StandardOutput&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;journal&lt;/span&gt;
&lt;span class="py"&gt;StandardError&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;journal&lt;/span&gt;
&lt;span class="py"&gt;SyslogIdentifier&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;backend&lt;/span&gt;

&lt;span class="nn"&gt;[Install]&lt;/span&gt;
&lt;span class="py"&gt;WantedBy&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;multi-user.target&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  5.2 Create Frontend Service
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/systemd/system/frontend.service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add this configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[Unit]&lt;/span&gt;
&lt;span class="py"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Frontend Next.js Application&lt;/span&gt;
&lt;span class="py"&gt;Documentation&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;https://github.com/yourusername/frontend-app&lt;/span&gt;
&lt;span class="py"&gt;After&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;network.target&lt;/span&gt;

&lt;span class="nn"&gt;[Service]&lt;/span&gt;
&lt;span class="py"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;simple&lt;/span&gt;
&lt;span class="py"&gt;User&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;ubuntu&lt;/span&gt;
&lt;span class="py"&gt;WorkingDirectory&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/home/ubuntu/frontend-app&lt;/span&gt;
&lt;span class="py"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"NODE_ENV=production"&lt;/span&gt;
&lt;span class="py"&gt;ExecStart&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/usr/bin/npm start&lt;/span&gt;

&lt;span class="c"&gt;# Restart policy
&lt;/span&gt;&lt;span class="py"&gt;Restart&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;always&lt;/span&gt;
&lt;span class="py"&gt;RestartSec&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;10&lt;/span&gt;

&lt;span class="c"&gt;# Resource limits
&lt;/span&gt;&lt;span class="py"&gt;LimitNOFILE&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;65536&lt;/span&gt;

&lt;span class="c"&gt;# Security
&lt;/span&gt;&lt;span class="py"&gt;NoNewPrivileges&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;
&lt;span class="py"&gt;PrivateTmp&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;true&lt;/span&gt;

&lt;span class="c"&gt;# Logging
&lt;/span&gt;&lt;span class="py"&gt;StandardOutput&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;journal&lt;/span&gt;
&lt;span class="py"&gt;StandardError&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;journal&lt;/span&gt;
&lt;span class="py"&gt;SyslogIdentifier&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;frontend&lt;/span&gt;

&lt;span class="nn"&gt;[Install]&lt;/span&gt;
&lt;span class="py"&gt;WantedBy&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;multi-user.target&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  5.3 Enable and Start Services
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Reload systemd to read new service files&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl daemon-reload

&lt;span class="c"&gt;# Enable services (start on boot)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;backend
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;frontend

&lt;span class="c"&gt;# Start services now&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start backend
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start frontend

&lt;span class="c"&gt;# Check status&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status backend
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status frontend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  5.4 Useful systemd Commands
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# View logs&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; backend &lt;span class="nt"&gt;-f&lt;/span&gt;        &lt;span class="c"&gt;# Follow backend logs&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; frontend &lt;span class="nt"&gt;-f&lt;/span&gt;       &lt;span class="c"&gt;# Follow frontend logs&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; backend &lt;span class="nt"&gt;--since&lt;/span&gt; &lt;span class="s2"&gt;"1 hour ago"&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; backend &lt;span class="nt"&gt;-n&lt;/span&gt; 100    &lt;span class="c"&gt;# Last 100 lines&lt;/span&gt;

&lt;span class="c"&gt;# Service management&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart backend       &lt;span class="c"&gt;# Restart service&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl stop backend          &lt;span class="c"&gt;# Stop service&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start backend         &lt;span class="c"&gt;# Start service&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl disable backend       &lt;span class="c"&gt;# Don't start on boot&lt;/span&gt;

&lt;span class="c"&gt;# System status&lt;/span&gt;
systemctl list-units &lt;span class="nt"&gt;--type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;service  &lt;span class="c"&gt;# List all services&lt;/span&gt;
systemctl is-active backend          &lt;span class="c"&gt;# Check if running&lt;/span&gt;
systemctl is-enabled backend         &lt;span class="c"&gt;# Check if starts on boot&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Part 6: Process Management - Option B (PM2)
&lt;/h3&gt;

&lt;h4&gt;
  
  
  6.1 Install PM2 Globally
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; pm2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  6.2 Start Applications with PM2
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Start backend&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; /home/ubuntu/backend-app
pm2 start src/server.js &lt;span class="nt"&gt;--name&lt;/span&gt; backend

&lt;span class="c"&gt;# Start frontend&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; /home/ubuntu/frontend-app
pm2 start npm &lt;span class="nt"&gt;--name&lt;/span&gt; frontend &lt;span class="nt"&gt;--&lt;/span&gt; start

&lt;span class="c"&gt;# Or for cluster mode (multiple instances):&lt;/span&gt;
pm2 start src/server.js &lt;span class="nt"&gt;--name&lt;/span&gt; backend &lt;span class="nt"&gt;-i&lt;/span&gt; max  &lt;span class="c"&gt;# Uses all CPU cores&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  6.3 Configure PM2 with ecosystem.config.js
&lt;/h4&gt;

&lt;p&gt;Create a config file for better management:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /home/ubuntu
nano ecosystem.config.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add this configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;apps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;backend&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;cwd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/home/ubuntu/backend-app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src/server.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;instances&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;// or 'max' for all CPU cores&lt;/span&gt;
      &lt;span class="na"&gt;exec_mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cluster&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;NODE_ENV&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;error_file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/home/ubuntu/logs/backend-error.log&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;out_file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/home/ubuntu/logs/backend-out.log&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;log_date_format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YYYY-MM-DD HH:mm:ss Z&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;merge_logs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;autorestart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;max_memory_restart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1G&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;frontend&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;cwd&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/home/ubuntu/frontend-app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;npm&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;start&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;instances&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;exec_mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fork&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;NODE_ENV&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;production&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;PORT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;error_file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/home/ubuntu/logs/frontend-error.log&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;out_file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/home/ubuntu/logs/frontend-out.log&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;log_date_format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YYYY-MM-DD HH:mm:ss Z&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;merge_logs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;autorestart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;max_memory_restart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;500M&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;watch&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  6.4 Start with Ecosystem File
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create logs directory&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /home/ubuntu/logs

&lt;span class="c"&gt;# Start all apps&lt;/span&gt;
pm2 start ecosystem.config.js

&lt;span class="c"&gt;# Save PM2 process list&lt;/span&gt;
pm2 save

&lt;span class="c"&gt;# Make PM2 start on system boot&lt;/span&gt;
pm2 startup systemd &lt;span class="nt"&gt;-u&lt;/span&gt; ubuntu &lt;span class="nt"&gt;--hp&lt;/span&gt; /home/ubuntu
&lt;span class="c"&gt;# Run the command it outputs (starts with sudo)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  6.5 Useful PM2 Commands
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Process management&lt;/span&gt;
pm2 list                    &lt;span class="c"&gt;# List all processes&lt;/span&gt;
pm2 status                  &lt;span class="c"&gt;# Same as list&lt;/span&gt;
pm2 restart backend         &lt;span class="c"&gt;# Restart specific app&lt;/span&gt;
pm2 restart all             &lt;span class="c"&gt;# Restart all apps&lt;/span&gt;
pm2 reload backend          &lt;span class="c"&gt;# Zero-downtime reload&lt;/span&gt;
pm2 stop backend            &lt;span class="c"&gt;# Stop app&lt;/span&gt;
pm2 delete backend          &lt;span class="c"&gt;# Remove app from PM2&lt;/span&gt;

&lt;span class="c"&gt;# Monitoring&lt;/span&gt;
pm2 monit                   &lt;span class="c"&gt;# Real-time monitoring dashboard&lt;/span&gt;
pm2 logs                    &lt;span class="c"&gt;# View all logs&lt;/span&gt;
pm2 logs backend            &lt;span class="c"&gt;# View specific app logs&lt;/span&gt;
pm2 logs backend &lt;span class="nt"&gt;--lines&lt;/span&gt; 100  &lt;span class="c"&gt;# Last 100 lines&lt;/span&gt;
pm2 flush                   &lt;span class="c"&gt;# Clear all logs&lt;/span&gt;

&lt;span class="c"&gt;# Information&lt;/span&gt;
pm2 describe backend        &lt;span class="c"&gt;# Detailed info about app&lt;/span&gt;
pm2 show backend            &lt;span class="c"&gt;# Same as describe&lt;/span&gt;

&lt;span class="c"&gt;# Cluster management&lt;/span&gt;
pm2 scale backend 4         &lt;span class="c"&gt;# Scale to 4 instances&lt;/span&gt;
pm2 scale backend +2        &lt;span class="c"&gt;# Add 2 more instances&lt;/span&gt;

&lt;span class="c"&gt;# Updates&lt;/span&gt;
pm2 update                  &lt;span class="c"&gt;# Update PM2 daemon&lt;/span&gt;
pm2 save                    &lt;span class="c"&gt;# Save current process list&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Part 7: Install and Configure Caddy
&lt;/h3&gt;

&lt;h4&gt;
  
  
  7.1 Install Caddy
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install dependencies&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; debian-keyring debian-archive-keyring apt-transport-https

&lt;span class="c"&gt;# Add Caddy repository&lt;/span&gt;
curl &lt;span class="nt"&gt;-1sLf&lt;/span&gt; &lt;span class="s1"&gt;'https://dl.cloudsmith.io/public/caddy/stable/gpg.key'&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nb"&gt;sudo &lt;/span&gt;gpg &lt;span class="nt"&gt;--dearmor&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /usr/share/keyrings/caddy-stable-archive-keyring.gpg

curl &lt;span class="nt"&gt;-1sLf&lt;/span&gt; &lt;span class="s1"&gt;'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt'&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/apt/sources.list.d/caddy-stable.list

&lt;span class="c"&gt;# Update and install&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;caddy &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  7.2 Configure Caddyfile
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/caddy/Caddyfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Basic Configuration:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Frontend
yourdomain.com {
    reverse_proxy localhost:3000

    # Optional: Compression
    encode gzip

    # Optional: Security headers
    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
        X-Content-Type-Options "nosniff"
        X-Frame-Options "SAMEORIGIN"
        X-XSS-Protection "1; mode=block"
    }
}

# Backend API
api.yourdomain.com {
    reverse_proxy localhost:5000

    encode gzip

    header {
        Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
        X-Content-Type-Options "nosniff"
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Advanced Configuration with Load Balancing:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Frontend with multiple instances
yourdomain.com {
    reverse_proxy localhost:3000 localhost:3001 {
        lb_policy round_robin
        health_uri /
        health_interval 10s
    }

    encode gzip zstd

    header {
        Strict-Transport-Security "max-age=31536000"
        X-Content-Type-Options "nosniff"
    }

    # Rate limiting
    rate_limit {
        zone static_rl {
            key {remote_host}
            window 1m
            events 100
        }
    }
}

# Backend API with authentication
api.yourdomain.com {
    reverse_proxy localhost:5000 localhost:5001 {
        lb_policy least_conn
        health_uri /health
        health_interval 30s
    }

    encode gzip

    # CORS headers
    header {
        Access-Control-Allow-Origin "https://yourdomain.com"
        Access-Control-Allow-Methods "GET, POST, PUT, DELETE"
        Access-Control-Allow-Headers "Content-Type, Authorization"
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  7.3 Validate and Restart Caddy
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Validate configuration&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;caddy validate &lt;span class="nt"&gt;--config&lt;/span&gt; /etc/caddy/Caddyfile

&lt;span class="c"&gt;# If valid, reload Caddy&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl reload caddy

&lt;span class="c"&gt;# Check status&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status caddy

&lt;span class="c"&gt;# View logs&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; caddy &lt;span class="nt"&gt;-f&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  7.4 Caddy will automatically:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Get SSL certificates from Let's Encrypt&lt;/li&gt;
&lt;li&gt;Renew certificates before expiration&lt;/li&gt;
&lt;li&gt;Redirect HTTP to HTTPS&lt;/li&gt;
&lt;li&gt;Handle TLS termination&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Process Management Deep Dive
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How systemd Manages Processes
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;System Boot Sequence:
──────────────────────

① BIOS/UEFI
    ↓
② Bootloader (GRUB)
    ↓
③ Linux Kernel loads
    ↓
④ systemd starts (PID 1)
    ↓
⑤ systemd reads target
   (multi-user.target)
    ↓
⑥ Starts all enabled services
   • backend.service
   • frontend.service
   • caddy.service
   • ssh.service
   • etc.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What happens when a process crashes?&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Process Flow with systemd:
─────────────────────────

① App running (PID 1234)
    ↓
② App crashes (exit code 1)
    ↓
③ systemd detects termination
    ↓
④ Checks Restart= policy
   (Restart=always)
    ↓
⑤ Waits RestartSec seconds (10s)
    ↓
⑥ Starts app again (new PID 1567)
    ↓
⑦ Logs event to journald
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  How PM2 Manages Processes
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PM2 Architecture:
────────────────

┌──────────────────────────┐
│   PM2 Daemon (God)       │  ← Main PM2 process
│   PID: 789               │
└────────┬─────────────────┘
         │
         ├─→ ┌──────────────────┐
         │   │ backend (cluster)│
         │   ├── Worker 1 (1234)│
         │   ├── Worker 2 (1235)│
         │   ├── Worker 3 (1236)│
         │   └── Worker 4 (1237)│
         │   └──────────────────┘
         │
         └─→ ┌──────────────────┐
             │ frontend (fork)  │
             └── Process (1238) │
             └──────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Cluster Mode Explained:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Without Cluster (1 instance):
────────────────────────────
CPU Core 1: [████████] Backend running
CPU Core 2: [        ] Idle
CPU Core 3: [        ] Idle
CPU Core 4: [        ] Idle

With Cluster Mode (4 instances):
───────────────────────────────
CPU Core 1: [████████] Backend Worker 1
CPU Core 2: [████████] Backend Worker 2
CPU Core 3: [████████] Backend Worker 3
CPU Core 4: [████████] Backend Worker 4

Load Balancer distributes requests across all workers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;What happens when a PM2 process crashes?&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Process Flow with PM2:
─────────────────────

① Worker 2 crashes
    ↓
② PM2 God process detects
    ↓
③ Immediately spawns new worker
    ↓
④ New worker starts in &amp;lt;1 second
    ↓
⑤ Logs crash to PM2 logs
    ↓
⑥ Cluster continues serving traffic
   (Workers 1, 3, 4 still running)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Monitoring and Logs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  systemd Monitoring
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Check Service Status
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Quick status check&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status backend
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status frontend

&lt;span class="c"&gt;# Is the service running?&lt;/span&gt;
systemctl is-active backend   &lt;span class="c"&gt;# Returns: active or inactive&lt;/span&gt;

&lt;span class="c"&gt;# Will it start on boot?&lt;/span&gt;
systemctl is-enabled backend  &lt;span class="c"&gt;# Returns: enabled or disabled&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  View Logs
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# View all logs for a service&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; backend

&lt;span class="c"&gt;# Follow logs in real-time (like tail -f)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; backend &lt;span class="nt"&gt;-f&lt;/span&gt;

&lt;span class="c"&gt;# Show last 50 lines&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; backend &lt;span class="nt"&gt;-n&lt;/span&gt; 50

&lt;span class="c"&gt;# Show logs from last hour&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; backend &lt;span class="nt"&gt;--since&lt;/span&gt; &lt;span class="s2"&gt;"1 hour ago"&lt;/span&gt;

&lt;span class="c"&gt;# Show logs from specific time&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; backend &lt;span class="nt"&gt;--since&lt;/span&gt; &lt;span class="s2"&gt;"2024-03-20 10:00:00"&lt;/span&gt;

&lt;span class="c"&gt;# Show logs between times&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; backend &lt;span class="nt"&gt;--since&lt;/span&gt; &lt;span class="s2"&gt;"2024-03-20"&lt;/span&gt; &lt;span class="nt"&gt;--until&lt;/span&gt; &lt;span class="s2"&gt;"2024-03-21"&lt;/span&gt;

&lt;span class="c"&gt;# Show only errors&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; backend &lt;span class="nt"&gt;-p&lt;/span&gt; err

&lt;span class="c"&gt;# Export logs to file&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; backend &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; backend-logs.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  PM2 Monitoring
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Monitor Dashboard
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Real-time monitoring (press Ctrl+C to exit)&lt;/span&gt;
pm2 monit

&lt;span class="c"&gt;# Shows:&lt;/span&gt;
&lt;span class="c"&gt;# - CPU usage&lt;/span&gt;
&lt;span class="c"&gt;# - Memory usage&lt;/span&gt;
&lt;span class="c"&gt;# - Process status&lt;/span&gt;
&lt;span class="c"&gt;# - Logs in real-time&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Check Status
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# List all processes&lt;/span&gt;
pm2 list

&lt;span class="c"&gt;# Detailed info&lt;/span&gt;
pm2 describe backend

&lt;span class="c"&gt;# JSON output (for scripts)&lt;/span&gt;
pm2 jlist
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  View Logs
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# All logs&lt;/span&gt;
pm2 logs

&lt;span class="c"&gt;# Specific app&lt;/span&gt;
pm2 logs backend

&lt;span class="c"&gt;# Last 100 lines&lt;/span&gt;
pm2 logs backend &lt;span class="nt"&gt;--lines&lt;/span&gt; 100

&lt;span class="c"&gt;# Follow logs&lt;/span&gt;
pm2 logs backend &lt;span class="nt"&gt;-f&lt;/span&gt;

&lt;span class="c"&gt;# Error logs only&lt;/span&gt;
pm2 logs backend &lt;span class="nt"&gt;--err&lt;/span&gt;

&lt;span class="c"&gt;# Clear all logs&lt;/span&gt;
pm2 flush
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  System Information
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# PM2 system info&lt;/span&gt;
pm2 info

&lt;span class="c"&gt;# Show PM2 version&lt;/span&gt;
pm2 &lt;span class="nt"&gt;-v&lt;/span&gt;

&lt;span class="c"&gt;# Show memory usage&lt;/span&gt;
pm2 list | &lt;span class="nb"&gt;grep &lt;/span&gt;MB
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Troubleshooting and Best Practices
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Common Issues and Solutions
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Issue 1: Service Won't Start
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Symptoms:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status backend
&lt;span class="c"&gt;# Shows: failed (Result: exit-code)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Solutions:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check the logs:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; backend &lt;span class="nt"&gt;-n&lt;/span&gt; 50
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Common causes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Missing .env file&lt;/li&gt;
&lt;li&gt;Wrong file paths in service file&lt;/li&gt;
&lt;li&gt;Port already in use&lt;/li&gt;
&lt;li&gt;Missing dependencies&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Test manually:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /home/ubuntu/backend-app
node src/server.js
&lt;span class="c"&gt;# See what error appears&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Check permissions:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; /home/ubuntu/backend-app
&lt;span class="c"&gt;# Make sure ubuntu user owns the files&lt;/span&gt;
&lt;span class="nb"&gt;sudo chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; ubuntu:ubuntu /home/ubuntu/backend-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Issue 2: Port Already in Use
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Symptoms:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Error: listen EADDRINUSE: address already in use :::5000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Solutions:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Find what's using the port:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;lsof &lt;span class="nt"&gt;-i&lt;/span&gt; :5000
&lt;span class="nb"&gt;sudo &lt;/span&gt;netstat &lt;span class="nt"&gt;-tulpn&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;5000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Kill the process:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo kill&lt;/span&gt; &lt;span class="nt"&gt;-9&lt;/span&gt; &amp;lt;PID&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Or change your app's port in .env&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Issue 3: Caddy Can't Get SSL Certificate
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Symptoms:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;certificate retrieval failed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Solutions:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Make sure DNS is pointing to your server:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dig yourdomain.com
nslookup yourdomain.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Check if ports 80 and 443 are open:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw status
&lt;span class="c"&gt;# Should show 80/tcp and 443/tcp ALLOW&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Check Caddy logs:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; caddy &lt;span class="nt"&gt;-f&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Verify domain ownership:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Make sure A record points to your EC2 IP&lt;/span&gt;
curl &lt;span class="nt"&gt;-I&lt;/span&gt; http://yourdomain.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Test Caddy config:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;caddy validate &lt;span class="nt"&gt;--config&lt;/span&gt; /etc/caddy/Caddyfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Issue 4: High Memory Usage
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Symptoms:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Server becomes slow&lt;/li&gt;
&lt;li&gt;Out of memory errors&lt;/li&gt;
&lt;li&gt;Applications crash randomly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Solutions:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check memory usage:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;free &lt;span class="nt"&gt;-h&lt;/span&gt;
htop  &lt;span class="c"&gt;# Install with: sudo apt install htop&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Find memory-hungry processes:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ps aux &lt;span class="nt"&gt;--sort&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;-%mem | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; 10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;For systemd, add memory limits:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[Service]&lt;/span&gt;
&lt;span class="py"&gt;MemoryMax&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;512M&lt;/span&gt;
&lt;span class="py"&gt;MemoryHigh&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;400M&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;For PM2, configure max memory restart:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;max_memory_restart&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;500M&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Optimize Node.js memory:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# In your service file or PM2 config&lt;/span&gt;
&lt;span class="nv"&gt;NODE_OPTIONS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"--max-old-space-size=512"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Issue 5: Application Crashes After Deployment
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Symptoms:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;App works locally but crashes on server&lt;/li&gt;
&lt;li&gt;"Module not found" errors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Solutions:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check Node.js version matches:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;span class="c"&gt;# Compare with your local version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Reinstall dependencies:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /home/ubuntu/backend-app
&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; node_modules package-lock.json
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--production&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Check for missing environment variables:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Add console.log to verify .env is loaded&lt;/span&gt;
console.log&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Environment:'&lt;/span&gt;, process.env.NODE_ENV&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Verify file permissions:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; ubuntu:ubuntu /home/ubuntu/backend-app
&lt;span class="nb"&gt;chmod&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; 755 /home/ubuntu/backend-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Issue 6: Frontend Shows 502 Bad Gateway
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Symptoms:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Caddy returns 502 error&lt;/li&gt;
&lt;li&gt;"upstream connect error"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Solutions:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check if frontend is actually running:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl localhost:3000
&lt;span class="c"&gt;# Should return HTML&lt;/span&gt;

&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status frontend
&lt;span class="c"&gt;# Should show "active (running)"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Check frontend logs:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; frontend &lt;span class="nt"&gt;-n&lt;/span&gt; 50
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Verify port in Caddyfile matches your app:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# In Caddyfile should be:&lt;/span&gt;
reverse_proxy localhost:3000

&lt;span class="c"&gt;# In your Next.js app:&lt;/span&gt;
&lt;span class="nv"&gt;PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3000 npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Test connection manually:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;telnet localhost 3000
&lt;span class="c"&gt;# Should connect successfully&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Best Practices
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Security Best Practices
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Never expose .env files:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Make sure .env is in .gitignore&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;".env"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; .gitignore
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;".env.*"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; .gitignore

&lt;span class="c"&gt;# Set proper permissions&lt;/span&gt;
&lt;span class="nb"&gt;chmod &lt;/span&gt;600 /home/ubuntu/backend-app/.env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Use environment-specific secrets:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Different secrets for dev/staging/production&lt;/span&gt;
&lt;span class="nv"&gt;JWT_SECRET_DEV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;dev-secret-key
&lt;span class="nv"&gt;JWT_SECRET_PROD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;super-complex-prod-key-12345
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Keep dependencies updated:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check for vulnerabilities&lt;/span&gt;
npm audit

&lt;span class="c"&gt;# Fix automatically (test first!)&lt;/span&gt;
npm audit fix

&lt;span class="c"&gt;# Update dependencies&lt;/span&gt;
npm update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Use SSH keys only (disable password auth):&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/ssh/sshd_config

&lt;span class="c"&gt;# Set these values:&lt;/span&gt;
PasswordAuthentication no
PermitRootLogin no
PubkeyAuthentication &lt;span class="nb"&gt;yes

sudo &lt;/span&gt;systemctl restart sshd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Configure fail2ban to prevent brute force:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;fail2ban &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;fail2ban
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start fail2ban
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Performance Best Practices
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Use PM2 cluster mode for CPU-intensive apps:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;backend&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;instances&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;max&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;// Uses all CPU cores&lt;/span&gt;
  &lt;span class="nx"&gt;exec_mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cluster&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Enable Caddy compression:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yourdomain.com {
    encode gzip zstd
    reverse_proxy localhost:3000
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Use production builds:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Next.js&lt;/span&gt;
&lt;span class="nv"&gt;NODE_ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production npm run build

&lt;span class="c"&gt;# React&lt;/span&gt;
npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Implement health checks:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// In your Express app&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/health&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;status&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; 
    &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ok&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="na"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; 
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Use CDN for static assets:&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Images, CSS, JS should be on S3 + CloudFront&lt;/li&gt;
&lt;li&gt;Reduces server load&lt;/li&gt;
&lt;li&gt;Faster delivery worldwide&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Deployment Best Practices
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Use Git tags for versions:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Tag your releases&lt;/span&gt;
git tag &lt;span class="nt"&gt;-a&lt;/span&gt; v1.0.0 &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Production release 1.0.0"&lt;/span&gt;
git push origin v1.0.0

&lt;span class="c"&gt;# Deploy specific version&lt;/span&gt;
git checkout v1.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create deployment script:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nano /home/ubuntu/deploy-backend.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt;  &lt;span class="c"&gt;# Exit on error&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"🚀 Starting deployment..."&lt;/span&gt;

&lt;span class="nb"&gt;cd&lt;/span&gt; /home/ubuntu/backend-app

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"📥 Pulling latest code..."&lt;/span&gt;
git pull origin main

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"📦 Installing dependencies..."&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--production&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"🧪 Running tests..."&lt;/span&gt;
npm &lt;span class="nb"&gt;test

echo&lt;/span&gt; &lt;span class="s2"&gt;"🔄 Restarting service..."&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart backend

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"✅ Deployment complete!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make executable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x /home/ubuntu/deploy-backend.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./deploy-backend.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Implement zero-downtime deployment with PM2:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Instead of restart, use reload&lt;/span&gt;
pm2 reload backend

&lt;span class="c"&gt;# This:&lt;/span&gt;
&lt;span class="c"&gt;# 1. Starts new instances&lt;/span&gt;
&lt;span class="c"&gt;# 2. Waits for them to be ready&lt;/span&gt;
&lt;span class="c"&gt;# 3. Stops old instances&lt;/span&gt;
&lt;span class="c"&gt;# 4. Zero downtime!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Keep backup of previous version:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Before deploying&lt;/span&gt;
&lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; /home/ubuntu/backend-app /home/ubuntu/backend-app.backup

&lt;span class="c"&gt;# If deployment fails, rollback:&lt;/span&gt;
&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /home/ubuntu/backend-app
&lt;span class="nb"&gt;mv&lt;/span&gt; /home/ubuntu/backend-app.backup /home/ubuntu/backend-app
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart backend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Use separate staging environment:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Different ports for staging&lt;/span&gt;
&lt;span class="nv"&gt;STAGING_PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5001
&lt;span class="nv"&gt;PRODUCTION_PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5000

&lt;span class="c"&gt;# Different subdomains&lt;/span&gt;
staging.yourdomain.com → localhost:5001
api.yourdomain.com → localhost:5000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Monitoring Best Practices
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Set up log rotation:&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For systemd:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/systemd/journald.conf

&lt;span class="c"&gt;# Add these settings:&lt;/span&gt;
&lt;span class="nv"&gt;SystemMaxUse&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;500M
&lt;span class="nv"&gt;SystemKeepFree&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1G
&lt;span class="nv"&gt;MaxRetentionSec&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1week
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For PM2:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;log_date_format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;YYYY-MM-DD HH:mm:ss&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;merge_logs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;max_size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;10M&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;retain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;  &lt;span class="c1"&gt;// Keep 7 log files&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Monitor disk space:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check disk usage&lt;/span&gt;
&lt;span class="nb"&gt;df&lt;/span&gt; &lt;span class="nt"&gt;-h&lt;/span&gt;

&lt;span class="c"&gt;# Find large files&lt;/span&gt;
&lt;span class="nb"&gt;du&lt;/span&gt; &lt;span class="nt"&gt;-sh&lt;/span&gt; /home/ubuntu/&lt;span class="k"&gt;*&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-rh&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; 10

&lt;span class="c"&gt;# Clean up PM2 logs&lt;/span&gt;
pm2 flush

&lt;span class="c"&gt;# Clean up system logs&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;journalctl &lt;span class="nt"&gt;--vacuum-time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;7d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Set up alerts (optional):&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install monitoring tools&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;monitoring-plugins &lt;span class="nt"&gt;-y&lt;/span&gt;

&lt;span class="c"&gt;# Or use cloud monitoring:&lt;/span&gt;
&lt;span class="c"&gt;# - AWS CloudWatch&lt;/span&gt;
&lt;span class="c"&gt;# - Datadog&lt;/span&gt;
&lt;span class="c"&gt;# - New Relic&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Regular backups:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Backup script&lt;/span&gt;
&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nv"&gt;DATE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%Y%m%d_%H%M%S&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-czf&lt;/span&gt; /home/ubuntu/backups/app-&lt;span class="nv"&gt;$DATE&lt;/span&gt;.tar.gz &lt;span class="se"&gt;\&lt;/span&gt;
  /home/ubuntu/backend-app &lt;span class="se"&gt;\&lt;/span&gt;
  /home/ubuntu/frontend-app &lt;span class="se"&gt;\&lt;/span&gt;
  /etc/caddy/Caddyfile

&lt;span class="c"&gt;# Keep only last 7 backups&lt;/span&gt;
&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; /home/ubuntu/backups/&lt;span class="k"&gt;*&lt;/span&gt;.tar.gz | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; +8 | xargs &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add to crontab:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;crontab &lt;span class="nt"&gt;-e&lt;/span&gt;

&lt;span class="c"&gt;# Run backup daily at 2 AM&lt;/span&gt;
0 2 &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; /home/ubuntu/backup.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Deployment Workflow Comparison
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Manual Deployment (Basic)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────┐
│ 1. Developer pushes code to GitHub     │
└──────────────────┬──────────────────────┘
                   │
                   ↓
┌─────────────────────────────────────────┐
│ 2. SSH into EC2 server                  │
└──────────────────┬──────────────────────┘
                   │
                   ↓
┌─────────────────────────────────────────┐
│ 3. cd /home/ubuntu/backend-app          │
│    git pull origin main                 │
└──────────────────┬──────────────────────┘
                   │
                   ↓
┌─────────────────────────────────────────┐
│ 4. npm install                          │
│    npm run build (if needed)            │
└──────────────────┬──────────────────────┘
                   │
                   ↓
┌─────────────────────────────────────────┐
│ 5. sudo systemctl restart backend       │
│    OR                                   │
│    pm2 reload backend                   │
└──────────────────┬──────────────────────┘
                   │
                   ↓
┌─────────────────────────────────────────┐
│ 6. Test the application                 │
└─────────────────────────────────────────┘

⏱️ Time: 5-10 minutes
👤 Manual effort required
⚠️ Potential downtime
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Automated Deployment with GitHub Actions (Advanced)
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .github/workflows/deploy.yml&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to EC2&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;main&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout code&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to EC2&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;appleboy/ssh-action@master&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.EC2_HOST }}&lt;/span&gt;
        &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu&lt;/span&gt;
        &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.EC2_SSH_KEY }}&lt;/span&gt;
        &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;cd /home/ubuntu/backend-app&lt;/span&gt;
          &lt;span class="s"&gt;git pull origin main&lt;/span&gt;
          &lt;span class="s"&gt;npm install --production&lt;/span&gt;
          &lt;span class="s"&gt;pm2 reload backend&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌─────────────────────────────────────────┐
│ 1. Developer pushes to GitHub           │
└──────────────────┬──────────────────────┘
                   │
                   ↓ (automatic)
┌─────────────────────────────────────────┐
│ 2. GitHub Actions triggered             │
└──────────────────┬──────────────────────┘
                   │
                   ↓
┌─────────────────────────────────────────┐
│ 3. Runs tests automatically             │
└──────────────────┬──────────────────────┘
                   │
                   ↓
┌─────────────────────────────────────────┐
│ 4. SSH to EC2 and deploy                │
└──────────────────┬──────────────────────┘
                   │
                   ↓
┌─────────────────────────────────────────┐
│ 5. Zero-downtime reload with PM2        │
└──────────────────┬──────────────────────┘
                   │
                   ↓
┌─────────────────────────────────────────┐
│ 6. Send notification (Discord/Slack)    │
└─────────────────────────────────────────┘

⏱️ Time: 2-3 minutes
👤 Zero manual effort
✅ No downtime
🔔 Automatic notifications
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  System Architecture Diagrams
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Complete Request Flow with All Components
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    🌍 Internet
                        │
                        │ HTTPS Request
                        │ https://yourdomain.com/api/users
                        │
                        ▼
        ┌───────────────────────────────────┐
        │      AWS Security Group           │
        │   • Allow 80 (HTTP)               │
        │   • Allow 443 (HTTPS)             │
        │   • Allow 22 (SSH - your IP only) │
        └───────────────┬───────────────────┘
                        │
                        ▼
        ┌───────────────────────────────────┐
        │         UFW Firewall              │
        │   • Port 80 → Allow               │
        │   • Port 443 → Allow              │
        │   • Port 22 → Allow               │
        │   • Other ports → Deny            │
        └───────────────┬───────────────────┘
                        │
                        ▼
        ┌───────────────────────────────────┐
        │    Caddy (Reverse Proxy)          │
        │    • Receives on port 443         │
        │    • Terminates SSL/TLS           │
        │    • Checks Caddyfile rules       │
        │    • Routes to backend/frontend   │
        └───────────────┬───────────────────┘
                        │
        ┌───────────────┴───────────────┐
        │                               │
        │ if /api/*                     │ if /*
        ▼                               ▼
┌──────────────┐                ┌──────────────┐
│   Backend    │                │   Frontend   │
│   Node.js    │                │   Next.js    │
│              │                │              │
│ Port: 5000   │                │ Port: 3000   │
│              │                │              │
│ Managed by:  │                │ Managed by:  │
│ ┌──────────┐ │                │ ┌──────────┐ │
│ │ systemd  │ │                │ │ systemd  │ │
│ │   OR     │ │                │ │   OR     │ │
│ │   PM2    │ │                │ │   PM2    │ │
│ └──────────┘ │                │ └──────────┘ │
│              │                │              │
│ ┌──────────┐ │                │              │
│ │ Process  │ │                │              │
│ │ Monitor  │ │                │              │
│ │ • Auto   │ │                │              │
│ │ restart  │ │                │              │
│ │ • Logs   │ │                │              │
│ └──────────┘ │                │              │
└──────┬───────┘                └──────────────┘
       │
       │ Database queries
       ▼
┌─────────────────┐
│   Database      │
│ • MongoDB       │
│ • PostgreSQL    │
│ • MySQL         │
│ (External)      │
└─────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Process Lifecycle with systemd
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;System Boot
    │
    ▼
┌───────────────────────────────────────┐
│ systemd (PID 1) starts                │
│ Reads: /etc/systemd/system/*.service  │
└───────────────┬───────────────────────┘
                │
    ┌───────────┼───────────┐
    │           │           │
    ▼           ▼           ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ backend │ │frontend │ │  caddy  │
│ service │ │ service │ │ service │
└────┬────┘ └────┬────┘ └────┬────┘
     │           │           │
     │ Starts    │ Starts    │ Starts
     │ Process   │ Process   │ Process
     ▼           ▼           ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ node    │ │ npm     │ │ caddy   │
│ server  │ │ start   │ │ run     │
│ PID:1234│ │ PID:1235│ │ PID:1236│
└────┬────┘ └────┬────┘ └────┬────┘
     │           │           │
     │ Running   │ Running   │ Running
     │           │           │
     ▼           ▼           ▼
┌────────────────────────────────────┐
│     systemd monitors all           │
│     • Collects logs (journald)     │
│     • Monitors health              │
│     • Auto-restart on crash        │
└────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If process crashes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Process Crash Detected
        │
        ▼
┌───────────────────┐
│ systemd detects   │
│ process exit      │
└─────────┬─────────┘
          │
          ▼
┌───────────────────┐
│ Check Restart=    │
│ policy            │
└─────────┬─────────┘
          │
          ▼
┌───────────────────┐
│ Wait RestartSec   │
│ (default 10s)     │
└─────────┬─────────┘
          │
          ▼
┌───────────────────┐
│ Start new process │
│ (new PID)         │
└─────────┬─────────┘
          │
          ▼
┌───────────────────┐
│ Log to journald   │
└───────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Process Lifecycle with PM2
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PM2 Startup
    │
    ▼
┌───────────────────────────────────────┐
│ PM2 Daemon (God Process) starts       │
│ Reads: ecosystem.config.js            │
│ PID: 789                              │
└───────────────┬───────────────────────┘
                │
    ┌───────────┴───────────┐
    │                       │
    ▼                       ▼
┌─────────────────┐   ┌──────────────┐
│ Backend App     │   │ Frontend App │
│ • Cluster Mode  │   │ • Fork Mode  │
│ • 4 instances   │   │ • 1 instance │
└────┬────────────┘   └──────┬───────┘
     │                       │
     ├──┬──┬──┬──            │
     ▼  ▼  ▼  ▼              ▼
    W1 W2 W3 W4             W1
    PID PID PID PID         PID
    1234 1235 1236 1237     1238

All workers report to PM2 Daemon
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Request distribution in Cluster Mode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Incoming Requests
        │
        ▼
┌────────────────────┐
│ PM2 Load Balancer  │
│ (Round Robin)      │
└────────┬───────────┘
         │
    ┌────┼────┬────┬────┐
    │    │    │    │    │
    ▼    ▼    ▼    ▼    ▼
   W1   W2   W3   W4   W1
  Req1 Req2 Req3 Req4 Req5

Each worker handles requests independently
If one crashes, others continue serving
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Quick Reference Commands
&lt;/h3&gt;

&lt;h4&gt;
  
  
  systemd Commands Cheat Sheet
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Service Management&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start &amp;lt;service&amp;gt;      &lt;span class="c"&gt;# Start service&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl stop &amp;lt;service&amp;gt;       &lt;span class="c"&gt;# Stop service&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart &amp;lt;service&amp;gt;    &lt;span class="c"&gt;# Restart service&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl reload &amp;lt;service&amp;gt;     &lt;span class="c"&gt;# Reload config&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status &amp;lt;service&amp;gt;     &lt;span class="c"&gt;# Check status&lt;/span&gt;

&lt;span class="c"&gt;# Enable/Disable (auto-start on boot)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable&lt;/span&gt; &amp;lt;service&amp;gt;     &lt;span class="c"&gt;# Enable auto-start&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl disable &amp;lt;service&amp;gt;    &lt;span class="c"&gt;# Disable auto-start&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl is-enabled &amp;lt;service&amp;gt; &lt;span class="c"&gt;# Check if enabled&lt;/span&gt;

&lt;span class="c"&gt;# Logs&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; &amp;lt;service&amp;gt;        &lt;span class="c"&gt;# All logs&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; &amp;lt;service&amp;gt; &lt;span class="nt"&gt;-f&lt;/span&gt;     &lt;span class="c"&gt;# Follow logs&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; &amp;lt;service&amp;gt; &lt;span class="nt"&gt;-n&lt;/span&gt; 50  &lt;span class="c"&gt;# Last 50 lines&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; &amp;lt;service&amp;gt; &lt;span class="nt"&gt;--since&lt;/span&gt; &lt;span class="s2"&gt;"1 hour ago"&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;journalctl &lt;span class="nt"&gt;-u&lt;/span&gt; &amp;lt;service&amp;gt; &lt;span class="nt"&gt;--since&lt;/span&gt; &lt;span class="s2"&gt;"2024-03-20 10:00"&lt;/span&gt;

&lt;span class="c"&gt;# System Management&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl daemon-reload        &lt;span class="c"&gt;# Reload service files&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl list-units          &lt;span class="c"&gt;# List all units&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl list-units &lt;span class="nt"&gt;--failed&lt;/span&gt; &lt;span class="c"&gt;# Failed services&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  PM2 Commands Cheat Sheet
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Start/Stop&lt;/span&gt;
pm2 start app.js &lt;span class="nt"&gt;--name&lt;/span&gt; myapp      &lt;span class="c"&gt;# Start app&lt;/span&gt;
pm2 start ecosystem.config.js      &lt;span class="c"&gt;# Start from config&lt;/span&gt;
pm2 stop myapp                     &lt;span class="c"&gt;# Stop app&lt;/span&gt;
pm2 restart myapp                  &lt;span class="c"&gt;# Restart app&lt;/span&gt;
pm2 reload myapp                   &lt;span class="c"&gt;# Zero-downtime reload&lt;/span&gt;
pm2 delete myapp                   &lt;span class="c"&gt;# Remove from PM2&lt;/span&gt;

&lt;span class="c"&gt;# Cluster Mode&lt;/span&gt;
pm2 start app.js &lt;span class="nt"&gt;-i&lt;/span&gt; 4              &lt;span class="c"&gt;# 4 instances&lt;/span&gt;
pm2 start app.js &lt;span class="nt"&gt;-i&lt;/span&gt; max            &lt;span class="c"&gt;# All CPU cores&lt;/span&gt;
pm2 scale myapp 4                  &lt;span class="c"&gt;# Scale to 4 instances&lt;/span&gt;
pm2 scale myapp +2                 &lt;span class="c"&gt;# Add 2 instances&lt;/span&gt;

&lt;span class="c"&gt;# Information&lt;/span&gt;
pm2 list                           &lt;span class="c"&gt;# List all apps&lt;/span&gt;
pm2 describe myapp                 &lt;span class="c"&gt;# Detailed info&lt;/span&gt;
pm2 monit                         &lt;span class="c"&gt;# Real-time monitor&lt;/span&gt;

&lt;span class="c"&gt;# Logs&lt;/span&gt;
pm2 logs                          &lt;span class="c"&gt;# All logs&lt;/span&gt;
pm2 logs myapp                    &lt;span class="c"&gt;# App logs&lt;/span&gt;
pm2 logs myapp &lt;span class="nt"&gt;--lines&lt;/span&gt; 100        &lt;span class="c"&gt;# Last 100 lines&lt;/span&gt;
pm2 flush                         &lt;span class="c"&gt;# Clear logs&lt;/span&gt;

&lt;span class="c"&gt;# Startup&lt;/span&gt;
pm2 startup                       &lt;span class="c"&gt;# Generate startup script&lt;/span&gt;
pm2 save                          &lt;span class="c"&gt;# Save process list&lt;/span&gt;
pm2 resurrect                     &lt;span class="c"&gt;# Restore saved processes&lt;/span&gt;

&lt;span class="c"&gt;# Updates&lt;/span&gt;
pm2 update                        &lt;span class="c"&gt;# Update PM2 daemon&lt;/span&gt;
pm2 reset myapp                   &lt;span class="c"&gt;# Reset restart counter&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Git Deployment Commands
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Pull latest changes&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; /home/ubuntu/backend-app
git pull origin main

&lt;span class="c"&gt;# Check current branch/version&lt;/span&gt;
git branch                        &lt;span class="c"&gt;# Current branch&lt;/span&gt;
git log &lt;span class="nt"&gt;-1&lt;/span&gt;                        &lt;span class="c"&gt;# Last commit&lt;/span&gt;
git status                        &lt;span class="c"&gt;# Working directory status&lt;/span&gt;

&lt;span class="c"&gt;# Deploy specific version&lt;/span&gt;
git fetch &lt;span class="nt"&gt;--tags&lt;/span&gt;
git checkout v1.0.0
git checkout main                 &lt;span class="c"&gt;# Back to main&lt;/span&gt;

&lt;span class="c"&gt;# Undo changes (dangerous!)&lt;/span&gt;
git reset &lt;span class="nt"&gt;--hard&lt;/span&gt; origin/main      &lt;span class="c"&gt;# Reset to remote&lt;/span&gt;
git clean &lt;span class="nt"&gt;-fd&lt;/span&gt;                     &lt;span class="c"&gt;# Remove untracked files&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Server Maintenance Commands
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Disk Space&lt;/span&gt;
&lt;span class="nb"&gt;df&lt;/span&gt; &lt;span class="nt"&gt;-h&lt;/span&gt;                             &lt;span class="c"&gt;# Disk usage&lt;/span&gt;
&lt;span class="nb"&gt;du&lt;/span&gt; &lt;span class="nt"&gt;-sh&lt;/span&gt; /path/&lt;span class="k"&gt;*&lt;/span&gt;                    &lt;span class="c"&gt;# Directory sizes&lt;/span&gt;
ncdu /home/ubuntu                 &lt;span class="c"&gt;# Interactive disk usage&lt;/span&gt;

&lt;span class="c"&gt;# Memory&lt;/span&gt;
free &lt;span class="nt"&gt;-h&lt;/span&gt;                           &lt;span class="c"&gt;# Memory usage&lt;/span&gt;
htop                             &lt;span class="c"&gt;# Interactive process viewer&lt;/span&gt;
ps aux &lt;span class="nt"&gt;--sort&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;-%mem | &lt;span class="nb"&gt;head&lt;/span&gt;       &lt;span class="c"&gt;# Top memory processes&lt;/span&gt;

&lt;span class="c"&gt;# Processes&lt;/span&gt;
ps aux                           &lt;span class="c"&gt;# All processes&lt;/span&gt;
ps aux | &lt;span class="nb"&gt;grep &lt;/span&gt;node               &lt;span class="c"&gt;# Find node processes&lt;/span&gt;
&lt;span class="nb"&gt;kill&lt;/span&gt; &lt;span class="nt"&gt;-9&lt;/span&gt; &amp;lt;PID&amp;gt;                    &lt;span class="c"&gt;# Kill process&lt;/span&gt;
pkill &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"node"&lt;/span&gt;                  &lt;span class="c"&gt;# Kill by name&lt;/span&gt;

&lt;span class="c"&gt;# Network&lt;/span&gt;
netstat &lt;span class="nt"&gt;-tulpn&lt;/span&gt;                   &lt;span class="c"&gt;# Open ports&lt;/span&gt;
ss &lt;span class="nt"&gt;-tulpn&lt;/span&gt;                        &lt;span class="c"&gt;# Socket statistics&lt;/span&gt;
lsof &lt;span class="nt"&gt;-i&lt;/span&gt; :3000                    &lt;span class="c"&gt;# What's on port 3000&lt;/span&gt;

&lt;span class="c"&gt;# Logs&lt;/span&gt;
&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/syslog          &lt;span class="c"&gt;# System log&lt;/span&gt;
&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/nginx/error.log &lt;span class="c"&gt;# Nginx errors&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;journalctl &lt;span class="nt"&gt;-f&lt;/span&gt;               &lt;span class="c"&gt;# All system logs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Key Takeaways
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Architecture&lt;/strong&gt;: Internet → DNS → EC2 → Caddy → Backend/Frontend → Database&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Process Managers&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;systemd&lt;/strong&gt;: Native Linux, minimal overhead, works with any language&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PM2&lt;/strong&gt;: Node.js focused, cluster mode, zero-downtime, better monitoring&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Deployment Flow&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clone repo → Install dependencies → Build (if needed) → Configure service → Start → Monitor&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Best Practices&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Always use environment variables for secrets&lt;/li&gt;
&lt;li&gt;Enable auto-restart for reliability&lt;/li&gt;
&lt;li&gt;Monitor logs regularly&lt;/li&gt;
&lt;li&gt;Keep backups&lt;/li&gt;
&lt;li&gt;Use HTTPS everywhere (Caddy handles this)&lt;/li&gt;
&lt;li&gt;Implement proper error handling&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Troubleshooting&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check logs first (&lt;code&gt;journalctl&lt;/code&gt; or &lt;code&gt;pm2 logs&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Verify ports are available&lt;/li&gt;
&lt;li&gt;Test manually before automating&lt;/li&gt;
&lt;li&gt;Keep services updated&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Quick Start Checklist
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[ ] EC2 instance running with SSH access&lt;/li&gt;
&lt;li&gt;[ ] Node.js installed&lt;/li&gt;
&lt;li&gt;[ ] Git repositories cloned&lt;/li&gt;
&lt;li&gt;[ ] Environment files (.env) configured&lt;/li&gt;
&lt;li&gt;[ ] Dependencies installed (npm install)&lt;/li&gt;
&lt;li&gt;[ ] Production build created (npm run build)&lt;/li&gt;
&lt;li&gt;[ ] Process manager configured (systemd or PM2)&lt;/li&gt;
&lt;li&gt;[ ] Services enabled and started&lt;/li&gt;
&lt;li&gt;[ ] Caddy installed and configured&lt;/li&gt;
&lt;li&gt;[ ] DNS pointing to EC2 IP&lt;/li&gt;
&lt;li&gt;[ ] SSL certificate obtained (automatic with Caddy)&lt;/li&gt;
&lt;li&gt;[ ] Firewall configured (ports 80, 443, 22)&lt;/li&gt;
&lt;li&gt;[ ] Services tested and monitored&lt;/li&gt;
&lt;li&gt;[ ] Deployment script created&lt;/li&gt;
&lt;li&gt;[ ] Backup strategy in place&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;You're now ready to deploy and manage production applications on AWS EC2!&lt;/strong&gt; 🚀&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>node</category>
      <category>devops</category>
      <category>aws</category>
    </item>
  </channel>
</rss>
