<?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[VictorDevops_sorcerer]]></title><description><![CDATA[VictorDevops_sorcerer]]></description><link>https://veethordevsorcerer.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Fri, 04 Sep 2026 17:48:54 GMT</lastBuildDate><atom:link href="https://veethordevsorcerer.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Complete Guide To Setting Up a Production-Ready Monitoring Stack with Prometheus, Alertmanager, Node Exporter, and Grafana on Linux]]></title><description><![CDATA[Introduction
We've all been there, scrambling at 3 AM trying to figure out why the server crashed. The worst part? Finding out your users knew about the problem before you did.
Monitoring shouldn't be complicated, but most solutions are either expens...]]></description><link>https://veethordevsorcerer.hashnode.dev/complete-guide-to-setting-up-a-production-ready-monitoring-stack-with-prometheus-alertmanager-node-exporter-and-grafana-on-linux</link><guid isPermaLink="true">https://veethordevsorcerer.hashnode.dev/complete-guide-to-setting-up-a-production-ready-monitoring-stack-with-prometheus-alertmanager-node-exporter-and-grafana-on-linux</guid><category><![CDATA[#prometheus]]></category><category><![CDATA[Grafana]]></category><category><![CDATA[Devops]]></category><category><![CDATA[Devops articles]]></category><category><![CDATA[Cloud Computing]]></category><category><![CDATA[Cloud]]></category><category><![CDATA[bash script]]></category><category><![CDATA[nano]]></category><category><![CDATA[AWS]]></category><category><![CDATA[azure-devops]]></category><category><![CDATA[Huawei]]></category><dc:creator><![CDATA[Chiemerie Victor John]]></dc:creator><pubDate>Wed, 20 Aug 2025 23:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1760475947402/f28db684-d9e2-4640-9530-59bcfe4860f8.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Introduction</strong></p>
<p>We've all been there, scrambling at 3 AM trying to figure out why the server crashed. The worst part? Finding out your users knew about the problem before you did.</p>
<p>Monitoring shouldn't be complicated, but most solutions are either expensive enterprise tools or a patchwork of scattered scripts that barely work together. That's where the Prometheus stack comes in.</p>
<p>I discovered this setup after years of juggling different monitoring tools that never quite clicked. Prometheus handles the data collection, Grafana makes it beautiful and actionable, Alertmanager notifies you before things spiral, and Node Exporter watches your system's every heartbeat.</p>
<p>The best part? It's all free, open-source, and actually works the way you'd expect it to.</p>
<p>In this guide, I'll show you exactly how to set up this entire monitoring stack from scratch. No fluff, no assumptions, just a clear path to building something that'll genuinely make your life easier.</p>
<p>By the end, you'll have real-time dashboards, smart alerts, and the kind of visibility that turns firefighting into routine maintenance.</p>
<p>Let's build it.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before we begin, ensure you have:</p>
<ul>
<li><p><strong>Ubuntu 24.04.3 or similar Linux distribution</strong> (commands may vary slightly for RHEL/CentOS)</p>
</li>
<li><p><strong>Root or sudo access</strong></p>
</li>
<li><p><strong>Minimum 2GB RAM and 2 CPU cores</strong> (for testing; scale up for production)</p>
</li>
<li><p><strong>Basic command-line knowledge</strong></p>
</li>
<li><p><strong>Firewall access</strong> to ports: 9090 (Prometheus), 9093 (Alertmanager), 9100 (Node Exporter), 3000 (Grafana)</p>
</li>
</ul>
<p>Update your system first:</p>
<p>bash</p>
<pre><code class="lang-bash">sudo apt update &amp;&amp; sudo apt upgrade -y
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760476495034/df314201-37b9-4879-b661-8e34dc22a13d.png" alt class="image--center mx-auto" /></p>
<p>In my case I did not include sudo because I am already withing the root directory so there is no need for that.</p>
<h2 id="heading-architecture-overview">Architecture Overview</h2>
<p>Before we start installing things, let's understand how these pieces fit together. Think of it like building a house, you need to know what each room does before you start hammering nails.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760915605409/793e22d7-2357-4c78-a147-2b9b11f9c913.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-how-it-all-works-together">How It All Works Together</h3>
<p><strong>1. Node Exporter - The Data Collector</strong></p>
<ul>
<li><p>Runs on your server and continuously monitors system metrics</p>
</li>
<li><p>Exposes this data on port 9100 in a format Prometheus understands</p>
</li>
<li><p>Think of it as a health monitor strapped to your server's wrist</p>
</li>
</ul>
<p><strong>2. Prometheus - The Brain</strong></p>
<ul>
<li><p>Actively scrapes (pulls) metrics from Node Exporter every 15 seconds</p>
</li>
<li><p>Stores everything in its efficient time-series database</p>
</li>
<li><p>Runs queries and evaluates alert rules you define</p>
</li>
<li><p>The central nervous system of your monitoring stack</p>
</li>
</ul>
<p><strong>3. Alertmanager - The Notification Hub</strong></p>
<ul>
<li><p>Receives alerts from Prometheus when something crosses a threshold</p>
</li>
<li><p>Groups similar alerts together (no spam!)</p>
</li>
<li><p>Routes notifications to the right people via email, Slack, PagerDuty, etc.</p>
</li>
<li><p>Your smart assistant that knows when and how to wake you up</p>
</li>
</ul>
<p><strong>4. Grafana - The Dashboard</strong></p>
<ul>
<li><p>Connects to Prometheus and queries the stored metrics</p>
</li>
<li><p>Transforms boring numbers into beautiful, interactive visualizations</p>
</li>
<li><p>Lets you create custom dashboards to monitor exactly what matters</p>
</li>
<li><p>Your mission control center</p>
</li>
</ul>
<h3 id="heading-the-data-flow-a-real-example">The Data Flow (A Real Example)</h3>
<p>Let's say your CPU usage spikes:</p>
<ol>
<li><p><strong>Node Exporter</strong> detects CPU at 95% and exposes this metric</p>
</li>
<li><p><strong>Prometheus</strong> scrapes it and sees: <code>node_cpu_usage = 95%</code></p>
</li>
<li><p><strong>Prometheus</strong> checks your rule: "Alert if CPU &gt; 80% for 5 minutes"</p>
</li>
<li><p>After 5 minutes, <strong>Prometheus</strong> fires an alert to <strong>Alertmanager</strong></p>
</li>
<li><p><strong>Alertmanager</strong> sends you an email: "High CPU on server-01"</p>
</li>
<li><p>You open <strong>Grafana</strong>, see the CPU graph spiking, and investigate</p>
</li>
<li><p>You fix the issue before users even notice</p>
</li>
</ol>
<p>This happens automatically 24/7, while you sleep. Pretty sweet, right?</p>
<h3 id="heading-ports-reference-quick-cheat-sheet">Ports Reference (Quick Cheat Sheet)</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Service</td><td>Port</td><td>Purpose</td></tr>
</thead>
<tbody>
<tr>
<td>Prometheus</td><td>9090</td><td>Web UI and API</td></tr>
<tr>
<td>Alertmanager</td><td>9093</td><td>Web UI and alert receiver</td></tr>
<tr>
<td>Node Exporter</td><td>9100</td><td>Metrics endpoint</td></tr>
<tr>
<td>Grafana</td><td>3000</td><td>Web UI for dashboards</td></tr>
</tbody>
</table>
</div><p>Now that you understand the architecture, let's get our hands dirty and start building.</p>
<h2 id="heading-installing-prometheus">Installing Prometheus</h2>
<h3 id="heading-step-1-create-a-dedicated-user">Step 1: Create a dedicated user</h3>
<pre><code class="lang-bash">sudo useradd --no-create-home --shell /bin/<span class="hljs-literal">false</span> prometheus
</code></pre>
<h3 id="heading-step-2-download-prometheus">Step 2: Download Prometheus</h3>
<p>Check for the latest version at <a target="_blank" href="https://prometheus.io/download/"><code>prometheus.io/download</code></a>. At the time of writing:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> /tmp
wget https://github.com/prometheus/prometheus/releases/download/v2.47.0/prometheus-2.47.0.linux-amd64.tar.gz
tar -xvf prometheus-2.47.0.linux-amd64.tar.gz
<span class="hljs-built_in">cd</span> prometheus-2.47.0.linux-amd64
</code></pre>
<h3 id="heading-step-3-install-binaries-and-create-directories">Step 3: Install binaries and create directories</h3>
<pre><code class="lang-bash">sudo cp prometheus /usr/<span class="hljs-built_in">local</span>/bin/
sudo cp promtool /usr/<span class="hljs-built_in">local</span>/bin/
sudo chown prometheus:prometheus /usr/<span class="hljs-built_in">local</span>/bin/prometheus
sudo chown prometheus:prometheus /usr/<span class="hljs-built_in">local</span>/bin/promtool

sudo mkdir -p /etc/prometheus
sudo mkdir -p /var/lib/prometheus
sudo chown prometheus:prometheus /etc/prometheus
sudo chown prometheus:prometheus /var/lib/prometheus
</code></pre>
<h3 id="heading-step-4-copy-configuration-files">Step 4: Copy configuration files</h3>
<pre><code class="lang-bash">sudo cp -r consoles /etc/prometheus/
sudo cp -r console_libraries /etc/prometheus/
sudo chown -R prometheus:prometheus /etc/prometheus/consoles
sudo chown -R prometheus:prometheus /etc/prometheus/console_libraries
</code></pre>
<h3 id="heading-step-5-create-prometheus-configuration">Step 5: Create Prometheus configuration</h3>
<pre><code class="lang-bash">sudo nano /etc/prometheus/prometheus.yml
</code></pre>
<p>Add this basic configuration:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">global:</span>
  <span class="hljs-attr">scrape_interval:</span> <span class="hljs-string">15s</span>
  <span class="hljs-attr">evaluation_interval:</span> <span class="hljs-string">15s</span>

<span class="hljs-attr">alerting:</span>
  <span class="hljs-attr">alertmanagers:</span>
    <span class="hljs-bullet">-</span> <span class="hljs-attr">static_configs:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">targets:</span>
          <span class="hljs-bullet">-</span> <span class="hljs-string">localhost:9093</span>

<span class="hljs-attr">rule_files:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-string">"first_rules.yml"</span>
  <span class="hljs-bullet">-</span> <span class="hljs-string">"second_rules.yml"</span>

<span class="hljs-attr">scrape_configs:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">job_name:</span> <span class="hljs-string">'prometheus'</span>
    <span class="hljs-attr">static_configs:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">targets:</span> [<span class="hljs-string">'localhost:9090'</span>]

  <span class="hljs-bullet">-</span> <span class="hljs-attr">job_name:</span> <span class="hljs-string">'node_exporter'</span>
    <span class="hljs-attr">static_configs:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">targets:</span> [<span class="hljs-string">'localhost:9100'</span>]
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760476635711/fd1cb4ee-965d-4862-afec-a3b056ab4472.png" alt class="image--center mx-auto" /></p>
<p>Set ownership:</p>
<pre><code class="lang-bash">sudo chown prometheus:prometheus /etc/prometheus/prometheus.yml
</code></pre>
<h3 id="heading-step-6-create-systemd-service">Step 6: Create systemd service</h3>
<pre><code class="lang-bash">sudo nano /etc/systemd/system/prometheus.service
</code></pre>
<p>Add:</p>
<pre><code class="lang-ini"><span class="hljs-section">[Unit]</span>
<span class="hljs-attr">Description</span>=Prometheus
<span class="hljs-attr">Wants</span>=network-<span class="hljs-literal">on</span>line.target
<span class="hljs-attr">After</span>=network-<span class="hljs-literal">on</span>line.target

<span class="hljs-section">[Service]</span>
<span class="hljs-attr">User</span>=prometheus
<span class="hljs-attr">Group</span>=prometheus
<span class="hljs-attr">Type</span>=simple
<span class="hljs-attr">ExecStart</span>=/usr/local/bin/prometheus \
  <span class="hljs-attr">--config.file</span>=/etc/prometheus/prometheus.yml \
  <span class="hljs-attr">--storage.tsdb.path</span>=/var/lib/prometheus/ \
  <span class="hljs-attr">--web.console.templates</span>=/etc/prometheus/consoles \
  <span class="hljs-attr">--web.console.libraries</span>=/etc/prometheus/console_libraries

<span class="hljs-section">[Install]</span>
<span class="hljs-attr">WantedBy</span>=multi-user.target
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760476691793/1483faad-117f-4404-a524-4a7fe19f574d.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-step-7-start-prometheus">Step 7: Start Prometheus</h3>
<pre><code class="lang-bash">sudo systemctl daemon-reload
sudo systemctl start prometheus
sudo systemctl <span class="hljs-built_in">enable</span> prometheus
sudo systemctl status prometheus
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760546440554/8ea7fd8a-b33f-4ce0-90f0-4a61a7cb5ac1.png" alt class="image--center mx-auto" /></p>
<p>Verify it's running:</p>
<pre><code class="lang-bash">curl http://localhost:9090
</code></pre>
<hr />
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760546578191/f6626eb4-5706-44e7-a405-ec9a108b85be.png" alt class="image--center mx-auto" /></p>
<p>This output simply means that prometheus is up and accessible on <code>http://localhost:9090</code></p>
<h2 id="heading-installing-node-exporter">Installing Node Exporter</h2>
<h3 id="heading-step-1-create-dedicated-user">Step 1: Create dedicated user</h3>
<pre><code class="lang-bash">sudo useradd --no-create-home --shell /bin/<span class="hljs-literal">false</span> node_exporter
</code></pre>
<h3 id="heading-step-2-download-node-exporter">Step 2: Download Node Exporter</h3>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> /tmp
wget https://github.com/prometheus/node_exporter/releases/download/v1.6.1/node_exporter-1.6.1.linux-amd64.tar.gz
tar -xvf node_exporter-1.6.1.linux-amd64.tar.gz
<span class="hljs-built_in">cd</span> node_exporter-1.6.1.linux-amd64
</code></pre>
<h3 id="heading-step-3-install-binary">Step 3: Install binary</h3>
<pre><code class="lang-bash">sudo cp node_exporter /usr/<span class="hljs-built_in">local</span>/bin/
sudo chown node_exporter:node_exporter /usr/<span class="hljs-built_in">local</span>/bin/node_exporter
</code></pre>
<h3 id="heading-step-4-create-systemd-service">Step 4: Create systemd service</h3>
<pre><code class="lang-bash">sudo nano /etc/systemd/system/node_exporter.service
</code></pre>
<p>Add:</p>
<pre><code class="lang-ini"><span class="hljs-section">[Unit]</span>
<span class="hljs-attr">Description</span>=Node Exporter
<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>=node_exporter
<span class="hljs-attr">ExecStart</span>=/usr/local/bin/node_exporter
<span class="hljs-attr">Restart</span>=<span class="hljs-literal">on</span>-failure

<span class="hljs-section">[Install]</span>
<span class="hljs-attr">WantedBy</span>=multi-user.target
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760546729745/0d8175ca-d0b4-43b5-a9d5-a31459f3b491.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-step-5-start-node-exporter">Step 5: Start Node Exporter</h3>
<pre><code class="lang-bash">sudo systemctl daemon-reload
sudo systemctl start node_exporter
sudo systemctl <span class="hljs-built_in">enable</span> node_exporter
sudo systemctl status node_exporter
</code></pre>
<p>Verify metrics:</p>
<pre><code class="lang-bash">curl http://localhost:9100/metrics
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760580310140/6d8a6b71-8592-48c5-9157-ca89edacc7ed.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-installing-alertmanager">Installing Alertmanager</h2>
<h3 id="heading-step-1-create-dedicated-user-1">Step 1: Create dedicated user</h3>
<pre><code class="lang-bash">sudo useradd --no-create-home --shell /bin/<span class="hljs-literal">false</span> alertmanager
</code></pre>
<h3 id="heading-step-2-download-alertmanager">Step 2: Download Alertmanager</h3>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> /tmp
wget https://github.com/prometheus/alertmanager/releases/download/v0.26.0/alertmanager-0.26.0.linux-amd64.tar.gz
tar -xvf alertmanager-0.26.0.linux-amd64.tar.gz
<span class="hljs-built_in">cd</span> alertmanager-0.26.0.linux-amd64
</code></pre>
<h3 id="heading-step-3-install-binaries-and-create-directories-1">Step 3: Install binaries and create directories</h3>
<pre><code class="lang-bash">sudo cp alertmanager /usr/<span class="hljs-built_in">local</span>/bin/
sudo cp amtool /usr/<span class="hljs-built_in">local</span>/bin/
sudo chown alertmanager:alertmanager /usr/<span class="hljs-built_in">local</span>/bin/alertmanager
sudo chown alertmanager:alertmanager /usr/<span class="hljs-built_in">local</span>/bin/amtool

sudo mkdir -p /etc/alertmanager
sudo mkdir -p /var/lib/alertmanager
sudo chown alertmanager:alertmanager /etc/alertmanager
sudo chown alertmanager:alertmanager /var/lib/alertmanager
</code></pre>
<h3 id="heading-step-4-create-alertmanager-configuration">Step 4: Create Alertmanager configuration</h3>
<pre><code class="lang-bash">sudo nano /etc/alertmanager/alertmanager.yml
</code></pre>
<p>Add this basic yaml configuration:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">route:</span>
  <span class="hljs-attr">group_by:</span> [<span class="hljs-string">'alertname'</span>]
  <span class="hljs-attr">group_wait:</span> <span class="hljs-string">30s</span>
  <span class="hljs-attr">group_interval:</span> <span class="hljs-string">5m</span>
  <span class="hljs-attr">repeat_interval:</span> <span class="hljs-string">1h</span>
  <span class="hljs-attr">receiver:</span> <span class="hljs-string">'web.hook'</span>
<span class="hljs-attr">receivers:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">'web.hook'</span>
    <span class="hljs-attr">webhook_configs:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">url:</span> <span class="hljs-string">'http://127.0.0.1:5001/'</span>
<span class="hljs-attr">inhibit_rules:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">source_match:</span>
      <span class="hljs-attr">severity:</span> <span class="hljs-string">'critical'</span>
    <span class="hljs-attr">target_match:</span>
      <span class="hljs-attr">severity:</span> <span class="hljs-string">'warning'</span>
    <span class="hljs-attr">equal:</span> [<span class="hljs-string">'alertname'</span>, <span class="hljs-string">'dev'</span>, <span class="hljs-string">'instance'</span>]
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760547345062/ad7b97ca-a9ff-41af-803b-818024cace27.png" alt class="image--center mx-auto" /></p>
<p>Set ownership:</p>
<pre><code class="lang-bash">sudo chown alertmanager:alertmanager /etc/alertmanager/alertmanager.yml
</code></pre>
<h3 id="heading-step-5-create-systemd-service">Step 5: Create systemd service</h3>
<p>bash</p>
<pre><code class="lang-bash">sudo nano /etc/systemd/system/alertmanager.service
</code></pre>
<p>Add:</p>
<pre><code class="lang-ini"><span class="hljs-section">[Unit]</span>
<span class="hljs-attr">Description</span>=Alertmanager
<span class="hljs-attr">Wants</span>=network-<span class="hljs-literal">on</span>line.target
<span class="hljs-attr">After</span>=network-<span class="hljs-literal">on</span>line.target

<span class="hljs-section">[Service]</span>
<span class="hljs-attr">User</span>=alertmanager
<span class="hljs-attr">Group</span>=alertmanager
<span class="hljs-attr">Type</span>=simple
<span class="hljs-attr">ExecStart</span>=/usr/local/bin/alertmanager \
  <span class="hljs-attr">--config.file</span>=/etc/alertmanager/alertmanager.yml \

<span class="hljs-section">[Install]</span>
<span class="hljs-attr">WantedBy</span>=multi-user.target
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760547542774/55f6d9d1-3e3e-4f4a-b175-62d4fa0a9896.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-step-6-start-alertmanager">Step 6: Start Alertmanager</h3>
<pre><code class="lang-bash">sudo systemctl daemon-reload
sudo systemctl start alertmanager
sudo systemctl <span class="hljs-built_in">enable</span> alertmanager
sudo systemctl status alertmanager
</code></pre>
<p>Access the CLI:</p>
<p>bash</p>
<pre><code class="lang-bash">curl http://localhost:9093
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760547861745/892b3b6e-c421-4bd4-ab41-9376d1d7f359.png" alt class="image--center mx-auto" /></p>
<p>The output shows that both Prometheus and Alertmanager are running properly on my system.<br />Prometheus is active on port 9090, and Alertmanager is responding on port 9093, which makes my monitoring and alerting setup to be working as expected.</p>
<h2 id="heading-installing-grafana">Installing Grafana</h2>
<h3 id="heading-step-1-add-grafana-repository">Step 1: Add Grafana repository</h3>
<pre><code class="lang-bash">sudo apt-get install -y software-properties-common
sudo add-apt-repository <span class="hljs-string">"deb https://packages.grafana.com/oss/deb stable main"</span>
wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -
</code></pre>
<h3 id="heading-step-2-install-grafana">Step 2: Install Grafana</h3>
<pre><code class="lang-bash">sudo apt-get update
sudo apt-get install -y grafana
</code></pre>
<h3 id="heading-step-3-start-grafana">Step 3: Start Grafana</h3>
<pre><code class="lang-bash">sudo systemctl daemon-reload
sudo systemctl start grafana-server
sudo systemctl <span class="hljs-built_in">enable</span> grafana-server
sudo systemctl status grafana-server
</code></pre>
<h3 id="heading-step-4-access-grafana">Step 4: Access Grafana</h3>
<p>Open your browser and navigate to:</p>
<pre><code class="lang-plaintext">http://your-server-ip:3000
</code></pre>
<p>Default credentials:</p>
<ul>
<li><p><strong>Username:</strong> admin</p>
</li>
<li><p><strong>Password:</strong> admin</p>
</li>
</ul>
<p>You'll be prompted to change the password on first login.</p>
<hr />
<h2 id="heading-configuring-prometheus">Configuring Prometheus</h2>
<h3 id="heading-verify-prometheus-targets">Verify Prometheus targets</h3>
<p>Open Prometheus UI:</p>
<pre><code class="lang-plaintext">http://your-server-ip:9090
</code></pre>
<p>Navigate to <strong>Status &gt; Targets</strong>. You should see:</p>
<ul>
<li><p>prometheus (localhost:9090) - UP</p>
</li>
<li><p>node_exporter (localhost:9100) - UP</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760550791175/7c3b4eea-f14f-4151-bac5-9236265efbf1.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-setting-up-alerting-rules">Setting Up Alerting Rules</h2>
<h3 id="heading-step-1-create-alert-rules-file">Step 1: Create Alert rules file</h3>
<p>bash</p>
<pre><code class="lang-bash">sudo nano /etc/prometheus/alert_rules.yml
</code></pre>
<p>Add these yaml rules:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">groups:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">system_alerts</span>
    <span class="hljs-attr">interval:</span> <span class="hljs-string">30s</span>
    <span class="hljs-attr">rules:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">alert:</span> <span class="hljs-string">InstanceDown</span>
        <span class="hljs-attr">expr:</span> <span class="hljs-string">up</span> <span class="hljs-string">==</span> <span class="hljs-number">0</span>
        <span class="hljs-attr">for:</span> <span class="hljs-string">5m</span>
        <span class="hljs-attr">labels:</span>
          <span class="hljs-attr">severity:</span> <span class="hljs-string">critical</span>
        <span class="hljs-attr">annotations:</span>
          <span class="hljs-attr">summary:</span> <span class="hljs-string">"Instance <span class="hljs-template-variable">{{ $labels.instance }}</span> down"</span>
          <span class="hljs-attr">description:</span> <span class="hljs-string">"<span class="hljs-template-variable">{{ $labels.instance }}</span> of job <span class="hljs-template-variable">{{ $labels.job }}</span> has been down for more than 5 minutes."</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">alert:</span> <span class="hljs-string">HighCPUUsage</span>
        <span class="hljs-attr">expr:</span> <span class="hljs-number">100</span> <span class="hljs-bullet">-</span> <span class="hljs-string">(avg</span> <span class="hljs-string">by(instance)</span> <span class="hljs-string">(irate(node_cpu_seconds_total{mode="idle"}[5m]))</span> <span class="hljs-string">*</span> <span class="hljs-number">100</span><span class="hljs-string">)</span> <span class="hljs-string">&gt;</span> <span class="hljs-number">30</span>
        <span class="hljs-attr">for:</span> <span class="hljs-string">5m</span>
        <span class="hljs-attr">labels:</span>
          <span class="hljs-attr">severity:</span> <span class="hljs-string">warning</span>
        <span class="hljs-attr">annotations:</span>
          <span class="hljs-attr">summary:</span> <span class="hljs-string">"High CPU usage on <span class="hljs-template-variable">{{ $labels.instance }}</span>"</span>
          <span class="hljs-attr">description:</span> <span class="hljs-string">"CPU usage is above 80% (current value: <span class="hljs-template-variable">{{ $value }}</span>%)"</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">alert:</span> <span class="hljs-string">HighMemoryUsage</span>
        <span class="hljs-attr">expr:</span> <span class="hljs-number">100</span> <span class="hljs-string">*</span> <span class="hljs-string">(1</span> <span class="hljs-bullet">-</span> <span class="hljs-string">((node_memory_MemAvailable_bytes)</span> <span class="hljs-string">/</span> <span class="hljs-string">(node_memory_MemTotal_bytes)))</span> <span class="hljs-string">&gt;</span> <span class="hljs-number">85</span>
        <span class="hljs-attr">for:</span> <span class="hljs-string">5m</span>
        <span class="hljs-attr">labels:</span>
          <span class="hljs-attr">severity:</span> <span class="hljs-string">warning</span>
        <span class="hljs-attr">annotations:</span>
          <span class="hljs-attr">summary:</span> <span class="hljs-string">"High memory usage on <span class="hljs-template-variable">{{ $labels.instance }}</span>"</span>
          <span class="hljs-attr">description:</span> <span class="hljs-string">"Memory usage is above 85% (current value: <span class="hljs-template-variable">{{ $value }}</span>%)"</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">alert:</span> <span class="hljs-string">DiskSpaceLow</span>
        <span class="hljs-attr">expr:</span> <span class="hljs-number">100</span> <span class="hljs-bullet">-</span> <span class="hljs-string">((node_filesystem_avail_bytes{mountpoint="/",fstype!="rootfs"}</span> <span class="hljs-string">*</span> <span class="hljs-number">100</span><span class="hljs-string">)</span> <span class="hljs-string">/</span> <span class="hljs-string">node_filesystem_size_bytes{mountpoint="/",fstype!="rootfs"})</span> <span class="hljs-string">&gt;</span> <span class="hljs-number">90</span>
        <span class="hljs-attr">for:</span> <span class="hljs-string">5m</span>
        <span class="hljs-attr">labels:</span>
          <span class="hljs-attr">severity:</span> <span class="hljs-string">critical</span>
        <span class="hljs-attr">annotations:</span>
          <span class="hljs-attr">summary:</span> <span class="hljs-string">"Disk space low on <span class="hljs-template-variable">{{ $labels.instance }}</span>"</span>
          <span class="hljs-attr">description:</span> <span class="hljs-string">"Disk usage is above 90% (current value: <span class="hljs-template-variable">{{ $value }}</span>%)"</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">alert:</span> <span class="hljs-string">HighNetworkTraffic</span>
        <span class="hljs-attr">expr:</span> <span class="hljs-string">rate(node_network_receive_bytes_total[5m])</span> <span class="hljs-string">&gt;</span> <span class="hljs-number">100000000</span>
        <span class="hljs-attr">for:</span> <span class="hljs-string">5m</span>
        <span class="hljs-attr">labels:</span>
          <span class="hljs-attr">severity:</span> <span class="hljs-string">warning</span>
        <span class="hljs-attr">annotations:</span>
          <span class="hljs-attr">summary:</span> <span class="hljs-string">"High network traffic on <span class="hljs-template-variable">{{ $labels.instance }}</span>"</span>
          <span class="hljs-attr">description:</span> <span class="hljs-string">"Network receiving more than 100MB/s"</span>
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760556522363/14873529-6b27-4ab0-b045-9e95462a0b0f.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-step-2-configure-alert-manager-with-gmail"><strong>Step 2: Configure Alert manager with Gmail</strong></h3>
<p>Gmail requires an App Password (not your regular password). Here's how to get it:</p>
<ol>
<li><p>Go to your Google Account: <a target="_blank" href="https://myaccount.google.com/">your prefered google account</a></p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760572258192/be0ae98a-c80f-432b-a93b-0bf545801cff.png" alt class="image--center mx-auto" /></p>
<p> Click on security on the left sidebar</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760572428662/093e8f4c-b2e8-45f0-a34f-3823b48f8e30.png" alt class="image--center mx-auto" /></p>
<p> Enable 2-Step Verification if not already enabled</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760572513257/f4ad1c4e-7454-4fbd-a953-dbb023fc7bf7.png" alt class="image--center mx-auto" /></p>
<p> Click on the search button and search for app passwords</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760572614021/d4183fae-cd2f-452f-b8fe-993543ba5840.png" alt class="image--center mx-auto" /></p>
<p> Generate a new password for “Mail” which is what I choose to name this app.</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760572808631/89ac7e91-d275-4189-8a94-162049ef0dfa.png" alt class="image--center mx-auto" /></p>
<p> Copy the 16-character password</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760572924921/99488dcc-5d97-4139-9700-5fb6f9bf9bef.png" alt class="image--center mx-auto" /></p>
<p> Replace ‘Your_App_Password_here’ in the alertmanager.yml with this password without spaces, just fill in the 16 character password that was generated together.</p>
<p> Run this command:</p>
<pre><code class="lang-bash"> sudo nano /etc/alertmanager/alertmanager.yml
</code></pre>
<pre><code class="lang-yaml"> <span class="hljs-attr">global:</span>
   <span class="hljs-attr">resolve_timeout:</span> <span class="hljs-string">5m</span>
   <span class="hljs-attr">smtp_smarthost:</span> <span class="hljs-string">'smtp.gmail.com:587'</span>
   <span class="hljs-attr">smtp_from:</span> <span class="hljs-string">'jhonvictor0077@gmail.com'</span>
   <span class="hljs-attr">smtp_auth_username:</span> <span class="hljs-string">'jhonvictor0077@gmail.com'</span>
   <span class="hljs-attr">smtp_auth_password:</span> <span class="hljs-string">'cypjkodrvlztsprk'</span>
   <span class="hljs-attr">smtp_require_tls:</span> <span class="hljs-literal">true</span>

 <span class="hljs-attr">route:</span>
   <span class="hljs-attr">group_by:</span> [<span class="hljs-string">'alertname'</span>, <span class="hljs-string">'instance'</span>]
   <span class="hljs-attr">group_wait:</span> <span class="hljs-string">10s</span>
   <span class="hljs-attr">group_interval:</span> <span class="hljs-string">10s</span>
   <span class="hljs-attr">repeat_interval:</span> <span class="hljs-string">12h</span>
   <span class="hljs-attr">receiver:</span> <span class="hljs-string">'email-notifications'</span>

 <span class="hljs-attr">receivers:</span>
   <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">'email-notifications'</span>
     <span class="hljs-attr">email_configs:</span>
       <span class="hljs-bullet">-</span> <span class="hljs-attr">to:</span> <span class="hljs-string">'jhonvictor0077@gmail.com'</span>
         <span class="hljs-attr">headers:</span>
           <span class="hljs-attr">Subject:</span> <span class="hljs-string">'ALERT: <span class="hljs-template-variable">{{ .GroupLabels.alertname }}</span> on <span class="hljs-template-variable">{{ .GroupLabels.instance }}</span>'</span>
         <span class="hljs-attr">html:</span> <span class="hljs-string">|
           &lt;h2&gt;Alert Details&lt;/h2&gt;
           &lt;p&gt;&lt;strong&gt;Alert:&lt;/strong&gt; {{ .GroupLabels.alertname }}&lt;/p&gt;
           &lt;p&gt;&lt;strong&gt;Instance:&lt;/strong&gt; {{ .GroupLabels.instance }}&lt;/p&gt;
           &lt;p&gt;&lt;strong&gt;Severity:&lt;/strong&gt; {{ .CommonLabels.severity }}&lt;/p&gt;
           &lt;p&gt;&lt;strong&gt;Summary:&lt;/strong&gt; {{ range .Alerts }}{{ .Annotations.summary }}{{ end }}&lt;/p&gt;
           &lt;p&gt;&lt;strong&gt;Description:&lt;/strong&gt; {{ range .Alerts }}{{ .Annotations.description }}{{ end }}&lt;/p&gt;
           &lt;p&gt;&lt;strong&gt;Started at:&lt;/strong&gt; {{ range .Alerts }}{{ .StartsAt }}{{ end }}&lt;/p&gt;
</span>
 <span class="hljs-attr">inhibit_rules:</span>
   <span class="hljs-bullet">-</span> <span class="hljs-attr">source_match:</span>
       <span class="hljs-attr">severity:</span> <span class="hljs-string">'critical'</span>
     <span class="hljs-attr">target_match:</span>
       <span class="hljs-attr">severity:</span> <span class="hljs-string">'warning'</span>
     <span class="hljs-attr">equal:</span> [<span class="hljs-string">'alertname'</span>, <span class="hljs-string">'instance'</span>]
</code></pre>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760573837192/b932e48c-0bb0-4f8a-bed4-a999a3b8c6d6.png" alt class="image--center mx-auto" /></p>
<p><a target="_blank" href="https://myaccount.google.com/">Set ownership:</a></p>
<p><a target="_blank" href="https://myaccount.google.com/apppasswords">bash</a></p>
<pre><code class="lang-bash">sudo chown prometheus:prometheus /etc/prometheus/alert_rules.yml
</code></pre>
<h3 id="heading-stehttpsmyaccountgooglecomp-4-validate-cohttpsmyaccountgooglecomapppasswordsnfiguration"><a target="_blank" href="https://myaccount.google.com/">Ste</a><a target="_blank" href="https://myaccount.google.com/apppasswords">p 4: Validate co</a>nfiguration</h3>
<pre><code class="lang-bash">promtool check config /etc/prometheus/prometheus.yml
promtool check rules /etc/prometheus/alert_rules.yml
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760577652634/8e2c2e71-ccff-4f2b-966c-fc363c027fd1.png" alt class="image--center mx-auto" /></p>
<p>We should get the above result after running the commands.</p>
<h3 id="heading-step-5-reload-prometheushttpsmyaccountgooglecomapppasswords"><a target="_blank" href="https://myaccount.google.com/apppasswords">Step 5: Reload Prometheus</a></h3>
<pre><code class="lang-bash">sudo systemctl restart prometheus
</code></pre>
<p>Verify alerts in Prometheus UI: <strong>Alerts</strong> tab</p>
<hr />
<h2 id="heading-creating-grafana-dashboards">Creating Grafana Dashboards</h2>
<h3 id="heading-step-1-add-prometheus-data-source">Step 1: Add Prometheus data source</h3>
<ol>
<li><p>Log in to Grafana (<a target="_blank" href="http://your-server-ip:3000">http://localhost:3000</a>)</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760578683369/f2a27e3b-871b-49f2-924a-41e7557c6669.png" alt class="image--center mx-auto" /></p>
<p> Go to <strong>Configuration</strong> (gear icon) &gt; <strong>Data Sources</strong></p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760578903778/fe3034d5-2335-4225-853a-68f64cf57456.png" alt class="image--center mx-auto" /></p>
<p> Click <strong>Add data source</strong></p>
</li>
<li><p>Select <strong>Prometheus</strong></p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760578984896/4755d429-65e4-45f1-8a1a-0699a4980b8d.png" alt class="image--center mx-auto" /></p>
<p> Set URL to: <code>http://localhost:9090</code></p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760579080001/21079ac5-cba2-4817-8fbb-fe364132375c.png" alt class="image--center mx-auto" /></p>
<p> Click <strong>Save &amp; Test</strong></p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760579114436/094de737-94b6-4d59-9be6-2f34d0e3cd36.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-step-2-import-node-exporter-dashboard">Step 2: Import Node Exporter dashboard</h3>
<ol>
<li><p>Click <strong>+</strong> (plus icon) &gt; <strong>Import</strong></p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760579486370/0a7b4f8f-2460-4d09-befe-7ca86049fdd7.png" alt class="image--center mx-auto" /></p>
<p> Enter dashboard ID: <strong>1860</strong> (Node Exporter Full)</p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760579526921/5365c5e6-29b5-4bad-a289-6d3bce6b3a9f.png" alt class="image--center mx-auto" /></p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760579582916/36707e86-e239-4bc1-a76c-dcec53e1244d.png" alt class="image--center mx-auto" /></p>
<p> Click <strong>Load</strong></p>
</li>
<li><p>Select your Prometheus data source</p>
</li>
<li><p>Click <strong>Import</strong></p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760583077478/5a7264ed-5e01-4bfa-b946-3f2d2f6c4c6d.png" alt class="image--center mx-auto" /></p>
<p>You now have a fully functional comprehensive system monitoring dashboard!</p>
<h2 id="heading-testing-and-verification">Testing and Verification</h2>
<h3 id="heading-test-1-verify-all-services-are-running">Test 1: Verify all services are running</h3>
<pre><code class="lang-bash">sudo systemctl status prometheus
sudo systemctl status node_exporter
sudo systemctl status alertmanager
sudo systemctl status grafana-server
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760579935028/103b17f5-48c2-4690-87e8-74f3371cc941.png" alt class="image--center mx-auto" /></p>
<p>All the services should be enabled and running, just as shown above.</p>
<h3 id="heading-test-2-check-prometheus-targets">Test 2: Check Prometheus targets</h3>
<p>Navigate to: <code>http://localhost:9090/targets</code></p>
<p>All targets should show <strong>UP</strong> status.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760580511845/9ba2b476-22ff-41a1-8d1c-ae195305da27.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-test-3-trigger-a-test-alert">Test 3: Trigger a test alert</h3>
<p>Create artificial high CPU load:</p>
<p>bash</p>
<pre><code class="lang-bash">stress --cpu 4 --timeout 600
</code></pre>
<p>Install stress if needed:</p>
<pre><code class="lang-bash">sudo apt-get install -y stress
</code></pre>
<p>After 5 minutes, you should see the HighCPUUsage alert fire in:</p>
<ul>
<li><p>Prometheus UI (Alerts tab)</p>
</li>
<li><p>Alertmanager UI (<a target="_blank" href="http://your-server-ip:9093">http://your-server-ip:9093</a>)</p>
</li>
<li><p>Your configured notification channel of which in my case, I used a gmail account (jhonvictor0077@gmail.com)</p>
</li>
</ul>
<h3 id="heading-test-4-verify-grafana-visualization">Test 4: Verify Grafana visualization</h3>
<ol>
<li>Open your Grafana dashboard</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760581855416/5785db80-5ef9-47fe-9967-52e313453bdd.png" alt class="image--center mx-auto" /></p>
<p>This was just before we triggered an alert.</p>
<ol start="2">
<li>Check that your metrics are updating in real-time</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760581883855/4b765b18-10b8-46ae-bce7-3b40c37bc043.jpeg" alt class="image--center mx-auto" /></p>
<p>This was gotten after we triggered an alert. Interestingly, just as we also configured gmail to always notify us when something is up with our monitoring stack, an email notification was also gotten.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760582056071/25cef2c1-f902-450d-aed5-96b7f86fe3fd.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1760582208363/74223f09-5d4c-49a3-9613-d031d7277c13.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-5-monitoring-best-practices">5. Monitoring Best Practices</h3>
<ul>
<li><p><strong>Keep Prometheus focused:</strong> Don't overload with too many targets</p>
</li>
<li><p><strong>Use service discovery</strong> for dynamic environments</p>
</li>
<li><p><strong>Set appropriate retention:</strong> Default is 15 days; adjust based on needs</p>
</li>
<li><p><strong>Label wisely:</strong> Don't use high-cardinality labels (user IDs, timestamps)</p>
</li>
<li><p><strong>Alert thoughtfully:</strong> Too many alerts = alert fatigue</p>
</li>
</ul>
<h2 id="heading-troubleshooting">Troubleshooting</h2>
<h3 id="heading-issue-service-wont-start">Issue: Service won't start</h3>
<p><strong>Check logs:</strong></p>
<p>bash</p>
<pre><code class="lang-bash">sudo journalctl -u prometheus -f
sudo journalctl -u node_exporter -f
sudo journalctl -u alertmanager -f
sudo journalctl -u grafana-server -f
</code></pre>
<p><strong>Common causes:</strong></p>
<ul>
<li><p>Configuration syntax errors</p>
</li>
<li><p>Port already in use</p>
</li>
<li><p>Permission issues</p>
</li>
<li><p>Missing directories</p>
</li>
</ul>
<h3 id="heading-issue-targets-showing-as-down">Issue: Targets showing as DOWN</h3>
<p><strong>Check connectivity:</strong></p>
<p>bash</p>
<pre><code class="lang-bash">curl http://localhost:9100/metrics
curl http://localhost:9090/-/healthy
</code></pre>
<p><strong>Check firewall:</strong></p>
<pre><code class="lang-bash">sudo ufw status
</code></pre>
<p><strong>Verify configuration:</strong></p>
<pre><code class="lang-bash">promtool check config /etc/prometheus/prometheus.yml
</code></pre>
<h3 id="heading-issue-no-data-in-grafana">Issue: No data in Grafana</h3>
<p><strong>Verify data source:</strong></p>
<ul>
<li><p>Check Prometheus URL in Grafana</p>
</li>
<li><p>Test connection in data source settings</p>
</li>
<li><p>Verify Prometheus is collecting metrics</p>
</li>
</ul>
<p><strong>Check time range:</strong></p>
<ul>
<li><p>Ensure time range in Grafana matches available data</p>
</li>
<li><p>Prometheus default retention is 15 days</p>
</li>
</ul>
<h3 id="heading-issue-alerts-not-firing">Issue: Alerts not firing</h3>
<p><strong>Check alert rules:</strong></p>
<pre><code class="lang-bash">promtool check rules /etc/prometheus/alert_rules.yml
</code></pre>
<p><strong>Verify in Prometheus UI:</strong></p>
<ul>
<li><p>Go to Alerts tab</p>
</li>
<li><p>Check if rules are loaded</p>
</li>
<li><p>Check evaluation status</p>
</li>
</ul>
<p><strong>Check Alertmanager:</strong></p>
<pre><code class="lang-bash">curl http://localhost:9093/-/healthy
</code></pre>
<h3 id="heading-issue-high-memory-usage">Issue: High memory usage</h3>
<p><strong>Reduce scrape frequency:</strong></p>
<pre><code class="lang-yaml"><span class="hljs-attr">global:</span>
  <span class="hljs-attr">scrape_interval:</span> <span class="hljs-string">30s</span>  <span class="hljs-comment"># Increase from 15s</span>
</code></pre>
<p><strong>Reduce retention:</strong></p>
<pre><code class="lang-bash">--storage.tsdb.retention.time=15d
</code></pre>
<p><strong>Limit time series:</strong></p>
<ul>
<li><p>Remove unnecessary targets</p>
</li>
<li><p>Reduce metric cardinality</p>
</li>
<li><p>Use relabeling to drop unused metrics</p>
</li>
</ul>
<hr />
<h2 id="heading-conclusion">Conclusion</h2>
<p>This project successfully implemented a complete monitoring and alerting system using Prometheus, Node Exporter, Alertmanager, and Grafana on a Linux environment. We configured real-time metric collection, set up intelligent alert rules with a 30% CPU threshold, and established email notifications through Gmail SMTP integration.</p>
<p>The setup process involved troubleshooting critical issues like hostname resolution and ensuring proper communication between Prometheus and Alertmanager. Each component now works seamlessly together: Node Exporter collects system metrics, Prometheus monitors and evaluates alert conditions, Alertmanager routes notifications, and Grafana provides visual dashboards for data interpretation.</p>
<p>This lightweight and modular infrastructure is ideal for both learning purposes and production environments. The skills gained, including configuration management, alert threshold tuning, and service integration, are directly applicable to real-world DevOps scenarios. This monitoring solution provides the foundation needed to maintain system reliability, respond proactively to issues, and ensure optimal infrastructure performance.</p>
]]></content:encoded></item><item><title><![CDATA[The Easy Way to Host a Static Website using AWS S3]]></title><description><![CDATA[Introduction
Static websites are a type of website that offers fixed content, irrespective of user interaction or data, having each page coded in HTML, CSS, and sometimes JavaScript. Unlike dynamic websites, this type of website does not have server-...]]></description><link>https://veethordevsorcerer.hashnode.dev/the-easy-way-to-host-a-static-website-using-aws-s3</link><guid isPermaLink="true">https://veethordevsorcerer.hashnode.dev/the-easy-way-to-host-a-static-website-using-aws-s3</guid><category><![CDATA[Cloud Computing]]></category><category><![CDATA[quantum computing]]></category><category><![CDATA[AWS]]></category><category><![CDATA[S3-bucket]]></category><category><![CDATA[S3 static website hosting]]></category><category><![CDATA[AWS Certified Solutions Architect Associate]]></category><category><![CDATA[aws-cdk]]></category><category><![CDATA[AWS Amplify]]></category><category><![CDATA[aws lambda]]></category><category><![CDATA[#Devopscommunity]]></category><dc:creator><![CDATA[Chiemerie Victor John]]></dc:creator><pubDate>Thu, 10 Jul 2025 13:55:57 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1751712675380/4f5658c0-c691-4a05-bad5-c40937c26e8a.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Introduction</strong></p>
<p>Static websites are a type of website that offers fixed content, irrespective of user interaction or data, having each page coded in HTML, CSS, and sometimes JavaScript. Unlike dynamic websites, this type of website does not have server-side processing; it is secure, fast, lightweight, and also easy to host.<br />For businesses and developers, hosting a static website with Amazon S3 (Simple Storage Service) may be the perfect fit and an extremely cost-effective approach. With S3, you will be able to upload static files (HTML, CSS, JavaScript, images, etc.) and serve them directly to the internet without needing a web server.</p>
<p>The Key Characteristics of AWS S3 include:</p>
<ul>
<li><p>Scalable storage: Automatically scales to handle any amount of data.</p>
</li>
<li><p>High Availability: Your website is available with 99.99% uptime.</p>
</li>
<li><p>Cost-effective: Pay-as-you-go service, perfect for small and large businesses.</p>
</li>
<li><p>Static Website Hosting: Directly hosts HTML/CSS/JS files.</p>
</li>
<li><p>Secure: Provides fine-grained access control and encryption.</p>
</li>
</ul>
<p><strong>Amazon Web Services (AWS)</strong> makes it easy and affordable to host static websites with <strong>Amazon S3 (Simple Storage Service)</strong>. Whether you're launching a personal portfolio, a documentation hub, or a sleek landing page, S3 delivers fast, reliable, and scalable performance—no servers, no stress.</p>
<p>This blog serves as a guide to help you launch your static website on the AWS Cloud storage platform — S3.</p>
<p><strong>Prerequisites</strong><br />There are some basic tools we need to set up to successfully host our static website on AWS, and they are:</p>
<ul>
<li><p>Visual Studio Code. You can download it by clicking on this link <a target="_blank" href="https://code.visualstudio.com/download">(VS code)</a></p>
</li>
<li><p>An active AWS account</p>
</li>
<li><p>The folder containing files (HTML, CSS, and JavaScript) for your website.</p>
<p>  With that being said, let’s dive right into it. First off, we are going to create an S3 storage Bucket that will house our static website.</p>
</li>
</ul>
<p>Step 1: <strong>Create an S3 Storage Bucket</strong><br />We need to navigate to the S3 section on AWS to create our bucket</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1751929171463/2a54fd7f-a2d3-432b-b604-9034abf56c97.jpeg" alt class="image--center mx-auto" /></p>
<p>Once we click on the create button, it will take us to another interface where we will give our bucket a name that is globally unique, choose the policy we wish to set for our bucket, and then create the bucket afterwards.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1751941542470/a1d5c1a7-9747-43ed-b9c0-2b2ec6a6c55a.jpeg" alt class="image--center mx-auto" /></p>
<p>So here, you give your bucket a name that is globally unique.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1751941731264/7c4b94fb-4806-4bdc-a68d-626512ab18d0.jpeg" alt class="image--center mx-auto" /></p>
<p>In this section, we will need to uncheck the ‘<em>Block all public access’</em> box. The reason for unchecking this box is so that whoever we give the object URL after we have uploaded folders into the bucket can access the content of that bucket.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1751941742648/7b740a59-b208-45db-a666-8fc10d389c9b.jpeg" alt class="image--center mx-auto" /></p>
<p>We have to check the ‘<em>acknowledge that the current settings might result in this bucket and the objects within becoming public</em>’ box.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1751941760991/5055913a-3d51-4684-91b2-404f3f4059c0.jpeg" alt class="image--center mx-auto" /></p>
<p>Afterwards, we scroll all the way down and click on the create bucket button.</p>
<p>Once we are done creating our bucket, we can then upload our object into the S3 bucket.</p>
<p><strong>Step 2: Upload your Website files to the S3 Bucket</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1751993149111/d7d010f9-1e4e-4d5e-b5be-520f4638e03e.jpeg" alt class="image--center mx-auto" /></p>
<p>Click into the bucket that has already been created</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1751993156769/4a5a4992-ad59-4b8d-b858-137c69a88050.jpeg" alt class="image--center mx-auto" /></p>
<p>Use either of the upload buttons to upload the website folder to the bucket</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1751993174555/6113f57e-fa6c-4e22-b82f-be7a7efd4224.jpeg" alt class="image--center mx-auto" /></p>
<p>After selecting the files, it will show the actual size of all the content and items in that file, then you click on the <strong>upload</strong> button.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1751993204375/7055debd-15ff-4962-a73b-7984b4fb1942.jpeg" alt class="image--center mx-auto" /></p>
<p>It usually takes a minute or two to upload this size of folder on the S3 bucket; the time spent to upload folders could vary based on the size of the folder or file.</p>
<p>After successfully uploading our folder, we need to click the cancel button to proceed.</p>
<p><strong>Step 3: Enable the Static Website Hosting and Set Bucket Policy for Public Access</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752151447329/154d6407-50cb-414f-a9c1-6db059858770.jpeg" alt class="image--center mx-auto" /></p>
<p>First, click on the <strong>properties</strong> button, then scroll down to where you have <strong>Static website hosting</strong>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752150925129/1f932d09-0870-4fe0-bd98-b885451574e2.jpeg" alt class="image--center mx-auto" /></p>
<p>Click on the <strong>edit</strong> button</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752150952224/7482522c-20d4-42d7-88d0-e4f94ebaf86f.jpeg" alt class="image--center mx-auto" /></p>
<p>Select <strong>enable</strong> under <strong>Static website hosting</strong>, and also select <strong>Host a static website</strong> under <strong>Hosting type.</strong></p>
<p>Fill in <code>index.html</code> and <code>error.html</code> respectively to enter the document file, then save. Now S3 recognizes this bucket as a website.</p>
<p>Furthermore, we will head over to the <strong>permission</strong> section</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1751993212635/4b04a408-2a48-46ef-a177-8d44259c1f0f.jpeg" alt class="image--center mx-auto" /></p>
<p>Now that our website folder has been uploaded to the bucket, we will need to edit the permission for this bucket so that it can be accessible to whoever we send the object URL to.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1751993223941/03339e81-485d-4581-8e4c-87494c0b911d.jpeg" alt class="image--center mx-auto" /></p>
<p>Under the <strong>Bucket policy</strong>, we will click the <strong>edit</strong> button then fill in the <strong>JSON</strong> rule for this permission and save it.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1751993248973/a50ac6ff-0623-4b3d-bb94-7daa53bfcb64.jpeg" alt class="image--center mx-auto" /></p>
<p>Where we have the highlighted name as <mark>victordevbucket</mark>, edit it and fill in your own bucket name.<br />Below, is the JSON rule that we used to establish access to this bucket.</p>
<p><strong>NOTE: JSON (JavaScript Object Notation)</strong> is the format used to write rules. It is a lightweight, easy-to-read way to structure data using <strong>key-value pairs</strong>.</p>
<p>So, when we say “JSON in a bucket policy,” we mean a set of access rules written in JSON format that tells the cloud service who can do what with your bucket.</p>
<pre><code class="lang-plaintext">{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "PublicReadGetObject",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::victordevbucket/*"
    }
  ]
}
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1751993255208/aeb5a3db-807f-4e57-8ed4-ac983b2f9f16.jpeg" alt class="image--center mx-auto" /></p>
<p>After filling in the JSON rule, we save and go ahead to access our website.</p>
<p><strong>Step 4: Accessing the Website</strong><br />Now, we will go back to our object, and click on the <code>index.html</code> button</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1751993259722/49459a68-fad7-47bd-b970-185da3d2ed22.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1751993263515/fa2b15e7-4886-4dbc-b5cd-4a7df63c7c7b.jpeg" alt class="image--center mx-auto" /></p>
<p>Navigate to the <strong>Object URL</strong>, copy the url and paste it in your web browser — Voilà! you have you website Live .</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752130372294/fc24a468-42f4-4b45-ac3c-e6158e7dca15.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752130379038/a6b37f4d-f0a2-4429-aee7-f57a926939eb.jpeg" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1752130390605/3984773e-0601-4508-8c4f-14236b21d98a.jpeg" alt class="image--center mx-auto" /></p>
<p><strong>SUMMARY</strong></p>
<p>Using the AWS S3 to host a static website provides a high-quality, and affordable solution for developers and businesses who want to serve powerful content on the web quickly. In this blog, we have covered how painless and stress free it is to serve static sites (such as an HTML/CSS/JavaScript single-page app or a static blog) from an S3 bucket without having to manage traditional servers. Backed by flexible and endless scalability, high availability, and integration with services such as Cloudfront and Route 53, AWS S3 makes it easy for users to securely deploy globally available websites with a small investment profile. S3 is fast, durable, and scalable, whether you’re building a small personal site, a global production system, or anything in between.</p>
]]></content:encoded></item><item><title><![CDATA[Commands that Unlock the Power of Your Terminal]]></title><description><![CDATA[Welcome to Linux and the great things you can accomplish at the command line. Becoming familiar with a few core commands goes a rather long way if you are new to Linux. This blog promises a guide that will help you get started with the most important...]]></description><link>https://veethordevsorcerer.hashnode.dev/commands-that-unlock-the-power-of-your-terminal</link><guid isPermaLink="true">https://veethordevsorcerer.hashnode.dev/commands-that-unlock-the-power-of-your-terminal</guid><category><![CDATA[AWS]]></category><category><![CDATA[Azure]]></category><category><![CDATA[azure-devops]]></category><category><![CDATA[linux for beginners]]></category><category><![CDATA[Cloud Computing]]></category><category><![CDATA[Devops]]></category><category><![CDATA[Devops articles]]></category><category><![CDATA[#Devopscommunity]]></category><category><![CDATA[linux-basics]]></category><category><![CDATA[Ubuntu]]></category><dc:creator><![CDATA[Chiemerie Victor John]]></dc:creator><pubDate>Sat, 21 Jun 2025 13:32:41 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1750078472245/384f4821-1b43-42ed-a9f3-ec9e26371402.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Welcome to Linux and the great things you can accomplish at the command line. Becoming familiar with a few core commands goes a rather long way if you are new to Linux. This blog promises a guide that will help you get started with the most important commands that can help you utilise, manage, and fix what you are working on.</p>
<p>The Linux command line can be quite intimidating at first glance, but believe me, after you’ve used it for a little while, you’ll wonder how you’d ever lived without it. Whether you are navigating directories, viewing files, or creating new users or groups, these commands will quickly become your go-to commands.</p>
<p>With that being said, let’s unlock the ultimate power of Linux and control the command line like never before.</p>
<p><strong>Linux Commands</strong></p>
<ol>
<li><p><strong>Administrative User</strong><br /> An administrative user is also called a superuser, or a root user. This user has all the administrative rights and privileges in the Linux system. With a super user, there is no limitation to accessing the database or making changes in terms of administration, control, operations, etc.</p>
<p> <strong>Example:</strong></p>
<ul>
<li><p>Type <code>sudo su -</code> in the terminal</p>
</li>
<li><p>You will be prompted to fill in your password. The password will be invisible, so you’ll just have to type and click the Enter button.</p>
</li>
<li><p>After you have logged in successfully, you will notice that your command line changed from <code>$</code> to <code>#</code>, and also have <code>root@</code> before your name. What this means is that you transitioned from being a substitute user to being a root user.</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750086017279/19496131-655c-4abe-9efd-ca9c0c102039.jpeg" alt class="image--center mx-auto" /></p>
</li>
</ul>
</li>
<li><p><strong>Package Management</strong></p>
<p> Package management is the process of installing, updating, configuring, and removing software packages on a Linux system.</p>
<ul>
<li><p>Let’s run <code>apt update</code>. What this command does is that it gives us a list of all the software available for an update, and gives us the number of software available for update.</p>
</li>
<li><p>After that, run <code>apt upgrade</code>. This command upgrades all the software packages in your Linux system, and this takes approximately 40 minutes if you are a new Linux user on the Ubuntu distribution.</p>
<p>  When you see a prompt that states, ‘<mark>Do you want to continue? [Y/n]</mark>‘ click ‘y‘ and enter.</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750253219332/82461e9b-7083-4b55-9c88-cdf99a6b371c.jpeg" alt class="image--center mx-auto" /></p>
</li>
</ul>
</li>
<li><p><strong>Create a Directory/Folder</strong></p>
<p> Directories, which can also be referred to as folders, serve as an essential organizational structure for managing files efficiently. Benefits of a directory include: organizing files in a structured manner, access control for users, hierarchical system, backup and recovery, among others. Directories can be likened to folders in the file manager of a Windows operating system.</p>
<p> <code>mkdir</code> &lt;name of directory or folder&gt;<br /> <code>cd</code> &lt;name of directory or folder&gt;“ command is used to change or open a directory.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750091766765/f2280065-ef27-4a10-b561-056ed93acbb3.jpeg" alt class="image--center mx-auto" /></p>
</li>
<li><p><strong>Create a text file</strong><br /> <code>touch &lt;file name&gt;.txt</code> is a command used to create an empty file.<br /> Moreover, we have discussed creating folders and entering those folders using the commands <code>mkdir</code> and <code>cd</code>, respectively. So we created a few folders within a directory in the image below.</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750094725258/d95b7711-84e0-4074-ad93-b191022e81d1.jpeg" alt class="image--center mx-auto" /></p>
<ol start="5">
<li><p><strong>List Contents</strong><br /> There are a few commands that are commonly used to list content in the Linux system.<br /> <code>ls</code> - command is used to list content in a directory<br /> <code>ls -l</code> command is used to give detailed information such as permissions, owner, size and date in a long format.<br /> <code>ls -r</code> command list content in a reversed order.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750101413851/3e834b2c-cc73-4f1d-b48f-79ff68f8acbc.jpeg" alt class="image--center mx-auto" /></p>
</li>
<li><p><strong>Open text editor</strong><br /> The text editor just as the name implies, is used to edit text files within the terminal so if you don’t have the tool, you need to install it using the command <code>apt install vim</code> to install it.</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750103143180/6ddf6ae4-f4c6-4469-9716-09771474b314.jpeg" alt class="image--center mx-auto" /></p>
<p>After the text editor tool has been successfully installed, we can open the text editor using the command <code>vim &lt;filename&gt;.txt</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750103715233/fb7b208a-524a-4c24-8f81-d27fdc9bc1e1.jpeg" alt class="image--center mx-auto" /></p>
<p>Once we enter this command, the text editor file will open within the terminal.<br /><strong>Example:</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750103918555/c5ff21e2-232e-424d-b73b-c6e4e1eceee9.jpeg" alt class="image--center mx-auto" /></p>
<p>Once this opens up, the next right thing to do is to click on the letter <code>i</code> because you can do literally nothing till you click the insert button. Afterwards, you can type as much as you want in here.<br />To save your typed document in this text file, you need to:</p>
<ul>
<li><p>click on the <code>esc</code> button on the top left corner of your keyboard.</p>
</li>
<li><p>then insert <code>:wq</code> and click enter. That way you will save the text file and return to the terminal’s command interface.</p>
</li>
</ul>
<ol start="7">
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750164054960/b1132240-8257-4c4a-97fb-a777745d8e0f.jpeg" alt class="image--center mx-auto" /></p>
<p> <strong>Read-only Files</strong><br /> The cat command is used to view a text file, but it cannot be edited.<br /> <code>cat &lt;filename&gt;.txt</code></p>
</li>
<li><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750164178516/cdd55518-ea61-4c83-8051-50ea126f0ce7.jpeg" alt class="image--center mx-auto" /></p>
<p> <strong>History Command</strong><br /> The <code>history</code> command shows a list of all the commands that have been previously ran in the terminal.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750164967577/392b3c9e-ccc5-4b89-9ae9-286416cb4a70.jpeg" alt class="image--center mx-auto" /></p>
</li>
<li><p><strong>Adding User</strong><br /> The command <code>sudo adduser &lt;username&gt;</code> is used to add another user to our virtual machine; however, this does not automatically grant the user root privileges on this machine, unless you specifically decide to do so.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750169772906/2ab0325e-3672-446d-b954-13c1669b517f.jpeg" alt class="image--center mx-auto" /></p>
<p> You will be prompted to add the root user’s password for this user to be added.<br /> <strong>Note:</strong> On the Linux system, passwords are always invisible when typed and entered.<br /> Afterwards, we can go ahead and set a password for the user.</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750169551580/7dee2966-25ff-43c4-8d7b-0becedc6982c.jpeg" alt class="image--center mx-auto" /></p>
<p>While setting the password, we need to make sure that all our passwords are up to 8 small letters. If you get this prompt, you don’t have to worry, just repeat the password, and it will be set successfully.</p>
<p>Moreover, we will be prompted to add this new user’s details to the system to be able to add this new user to the system.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750170086599/96c65281-cc23-43d5-93e1-91a1cdec4330.jpeg" alt class="image--center mx-auto" /></p>
<p>So this is the process of adding a new user to the system or an organization, as the case may be.</p>
<ol start="10">
<li><p><strong>Switch User</strong><br />We use the <code>su - &lt;username&gt;</code> command to switch users within the Linux system.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750170624128/e4e80789-876d-4ac1-9212-dbf59513deb3.jpeg" alt class="image--center mx-auto" /></p>
<p>Now this is the current user logged on the system at the moment. We are going to run the command <code>su - dora</code> so that our user can change from victor to dora. Kindly note that the name of the virtual machine was named ‘<mark>Victor</mark>‘ and the user was also named <mark>Victor</mark>, which is the reason we have Victor appearing twice on the system.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750171045511/092d690f-942f-4cc4-88c3-6fd9de2da372.jpeg" alt class="image--center mx-auto" /></p>
<p>However, before we can successfully log in as ‘dora‘, we will need to use Dora’s password to log in.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750171327246/f7ca6651-26ec-4cb4-9d09-7559c065563d.jpeg" alt class="image--center mx-auto" /></p>
<p>We have successfully switched users from Victor to Dora.<br />Apparently, Linux is case sensitive. In some cases, you may not be able to create a username that begins with a Capital letter. In some cases, you may need to alternate small letters.</p>
</li>
<li><p><strong>Fetch user details</strong><br />The command line to fetch a user’s details is <code>getent passwd &lt;username&gt;</code><br /><strong>Example</strong><br /><code>getent passwd dora</code></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750171961639/9b29cb93-aabe-4247-9e0b-74e1390cfdf9.jpeg" alt class="image--center mx-auto" /></p>
<p>The result of the command that we ran shows Dora’s details, which include her full name, work number, and room number.</p>
</li>
<li><p><strong>Lock and Unlock User</strong><br />As a system administrator with root privileges, you can use these commands to lock a user’s account and also unlock a user’s account.<br />The command-line to lock a user’s account is <code>sudo usermod -L &lt;username&gt;</code><br /><strong>Example</strong></p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750174505572/d3592950-94fa-4b79-9071-258004cf9ccf.jpeg" alt class="image--center mx-auto" /></p>
<p>Now we locked Dora’s account, denying the user from accessing the account, then we used the command line <code>su - dora</code> to log in to Dora’s account, but it failed to log in, because it has been locked.<br />Now, let’s unlock the account.<br />We will run the command <code>sudo usermod -U dora</code> to unlock Dora’s account.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750174892005/7e610aa6-3fce-480a-b993-916e4f0ff26a.jpeg" alt class="image--center mx-auto" /></p>
<p>After unlocking Dora’s account, we used the command line <code>su - dora</code> to switch to Dora’s account, and now we have successfully logged into Dora’s account.</p>
<ol start="13">
<li><p><strong>Delete User’s Account</strong><br />To delete a user’s account from the system, run <code>sudo userdel &lt;username&gt;</code><br />To delete a user’s account and email messages, run the command <code>sudo userdel -r &lt;username&gt;</code><br /><strong>Example:</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750260398476/f32f4704-8f01-4a41-8360-0f2b19d17f9f.jpeg" alt class="image--center mx-auto" /></p>
<p>After we ran the command, it gave this response because this user does not have any saved email messages on the account.<br />Now we ran the “getent passwd dora” command to fetch details about this user, but it came back empty because this user no longer exists.</p>
</li>
</ol>
<p><strong>Running Shell Scripts</strong></p>
<p>What is a shell script?<br />A Shell script is a file that contains a sequence of shell commands that are executed in order.<br />Meanwhile, a shell is a program that provides a text-based interface for users to interact with the operating system.</p>
<p>Popular shells include:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Shell</strong></td><td><strong>Description</strong></td></tr>
</thead>
<tbody>
<tr>
<td>sh</td><td>Bourne Shell (original UNIX shell)</td></tr>
<tr>
<td>bash</td><td>Bourne Again SHell (most common, Linux default)</td></tr>
<tr>
<td>zsh</td><td>Z Shell (more advanced features)</td></tr>
<tr>
<td>csh</td><td>C Shell (uses C-like syntax)</td></tr>
<tr>
<td>fish</td><td>Friendly Interactive Shell (user-friendly design)</td></tr>
</tbody>
</table>
</div><p><strong>Advantages of Using Shell Scripting</strong><br />Shell scripting is used for the following:</p>
<ul>
<li><p>Automate repetitive tasks (backups, updates, deployments)</p>
</li>
<li><p>Configure system settings</p>
</li>
<li><p>Run multiple commands as a single program</p>
</li>
<li><p>Schedule jobs with tools like cron</p>
</li>
<li><p>Quickly test logic or prototypes</p>
<p>  To run a shell script, you must start with Shebang, which is represented as <code>#!/bin/bash</code>.<br />  <strong>Examples:</strong><br />  <code>#!/bin/bash</code></p>
<p>  <code>read -p</code> “Enter your age: “age”</p>
<p>  <code>if</code> [ $age -ge 28 ];then (the <code>‘if’</code> command in this example states that if the age is greater than or equal to 28, then it should give the response in the first <code>‘echo’</code>)</p>
<p>  <code>echo</code> “How time flies! Should I hope to get invited to your wedding soon because you are long overdue for marriage?.”</p>
<p>  <code>else</code> (in this example, the <code>‘else’</code> command will propel the second <code>‘echo’</code> to take effect if the age stated in the <code>‘if’</code> command is lower than 28)</p>
<p>  <code>echo</code> “I’ve known you to always be a brilliant one, so you should definitely focus on your studies.”</p>
<p>  <code>fi</code></p>
<p>  We vim into the text environment using <code>vim &lt;filename&gt;.sh</code></p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750505634180/659771e7-30d3-415b-9399-e86b45df3fd7.jpeg" alt class="image--center mx-auto" /></p>
<p>  Then we save and exit using the <code>esc</code> botton, then <code>:wq</code> to go back into the terminal.<br />  To execute an actionable command within the terminal, we must change mode directly from the terminal using the command <code>sudo chmod u+x .sh</code>. Afterwards, we run the command <code>./&lt;filename&gt;.sh</code> to execute it.</p>
<p>  <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750506400368/9d470104-8e02-45af-bdd5-ca9391dba894.jpeg" alt /></p>
</li>
</ul>
<ol start="13">
<li><p><strong>How to Create a Group</strong><br />Basically, the command <code>sudo addgroup &lt;group name&gt;</code> is used to create groups in the Linux distro. However, we can also use <code>sudo groupadd &lt;group name&gt;</code> to create a group. These two have slight differences in their functionalities.<br />The first command, which is <code>sudo addgroup &lt;group name&gt;</code> is the higher than the second command because this command is used to create an interactive group, unlike the second command, <code>sudo groupadd &lt;group name&gt;</code> that is used to create a group that is just meant to follow commands and duties assigned to various users within that group.<br /><strong>Example:</strong></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750508249783/6b4d2d74-919a-421b-8817-98762d777623.jpeg" alt class="image--center mx-auto" /></p>
<ol start="16">
<li><p><strong>How to Add Users to a Group</strong><br />The command <code>sudo usermod -aG &lt;group name&gt; &lt;username&gt;</code> is used to add a user to a group.<br /><strong>Example</strong><br />So we will run the command <code>sudo usermod -aG cloud-develops rex</code> to add an already existing user with the username <mark>‘rex’</mark> to the group that was created earlier.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750510070267/aebceac9-8b51-4fc5-af51-0c798198eaac.jpeg" alt class="image--center mx-auto" /></p>
<p>Furthermore, to list all the groups in a system, we use the command <code>getent group</code>, or <code>cat /etc/group</code>, to fetch details about a group, we use the command <code>getent group &lt;group name&gt;</code>, to see groups that a user belong to, we use the comand <code>groups &lt;username&gt;</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750511268434/4c1aafba-24a3-4052-98e6-07d2712603e2.jpeg" alt class="image--center mx-auto" /></p>
</li>
</ol>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1750511289351/ee97a3af-d68d-4e21-a14e-48c9ad8eb62e.jpeg" alt class="image--center mx-auto" /></p>
<p><strong>Conclusion</strong><br />Mastering the Linux command line isn’t just about memorizing every single instruction rather, it cuts across building confidence through consistent practice, hence enabling the user to dot his ‘i’s and slash his ‘T’s. The simple commands we just explored are the building blocks of something much greater, which includes: control, customization, and creativity in your computing experience. Like learning a new language, fluency and mastery come from hands-on use. The terminal is more than just a black screen; it’s my canvas.</p>
]]></content:encoded></item></channel></rss>