<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Morodolu Oluwafikunayomi</title>
    <description>The latest articles on DEV Community by Morodolu Oluwafikunayomi (@fikalz).</description>
    <link>https://dev.to/fikalz</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3231089%2Ff85b9080-1525-414b-8d59-1a4ce0b2c8f0.png</url>
      <title>DEV Community: Morodolu Oluwafikunayomi</title>
      <link>https://dev.to/fikalz</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fikalz"/>
    <language>en</language>
    <item>
      <title>I recently completed a hands-on project with Veeam Backup &amp; Replication, taking it from initial installation and configuration to automated, monitored backups.
I'd appreciate any feedback from fellow SysAdmins, Infrastructure Engineers, and DevOps</title>
      <dc:creator>Morodolu Oluwafikunayomi</dc:creator>
      <pubDate>Tue, 15 Sep 2026 11:41:32 +0000</pubDate>
      <link>https://dev.to/fikalz/i-recently-completed-a-hands-on-project-with-veeam-backup-replication-taking-it-from-initial-3fhp</link>
      <guid>https://dev.to/fikalz/i-recently-completed-a-hands-on-project-with-veeam-backup-replication-taking-it-from-initial-3fhp</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/fikalz/my-veeam-backup-replication-project-from-trial-download-to-monitored-backups-and-an-esxi-17ln" class="crayons-story__hidden-navigation-link"&gt;My Veeam Backup &amp;amp; Replication Project — From Trial Download to Monitored Backups (and an ESXi Bonus Round)&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/fikalz" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3231089%2Ff85b9080-1525-414b-8d59-1a4ce0b2c8f0.png" alt="fikalz profile" class="crayons-avatar__image" width="420" height="420"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/fikalz" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Morodolu Oluwafikunayomi
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Morodolu Oluwafikunayomi
                
                
              
              &lt;div id="story-author-preview-content-4608564" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/fikalz" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3231089%2Ff85b9080-1525-414b-8d59-1a4ce0b2c8f0.png" class="crayons-avatar__image" alt="" width="420" height="420"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Morodolu Oluwafikunayomi&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/fikalz/my-veeam-backup-replication-project-from-trial-download-to-monitored-backups-and-an-esxi-17ln" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Sep 8&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/fikalz/my-veeam-backup-replication-project-from-trial-download-to-monitored-backups-and-an-esxi-17ln" id="article-link-4608564"&gt;
          My Veeam Backup &amp;amp; Replication Project — From Trial Download to Monitored Backups (and an ESXi Bonus Round)
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/veeam"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;veeam&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/backup"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;backup&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/sysadmin"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;sysadmin&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/infrastructure"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;infrastructure&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
            &lt;a href="https://dev.to/fikalz/my-veeam-backup-replication-project-from-trial-download-to-monitored-backups-and-an-esxi-17ln#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            20 min read
          &lt;/small&gt;
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>automation</category>
      <category>devops</category>
      <category>infrastructure</category>
      <category>monitoring</category>
    </item>
    <item>
      <title>My Veeam Backup &amp; Replication Project — From Trial Download to Monitored Backups (and an ESXi Bonus Round)</title>
      <dc:creator>Morodolu Oluwafikunayomi</dc:creator>
      <pubDate>Tue, 08 Sep 2026 18:01:44 +0000</pubDate>
      <link>https://dev.to/fikalz/my-veeam-backup-replication-project-from-trial-download-to-monitored-backups-and-an-esxi-17ln</link>
      <guid>https://dev.to/fikalz/my-veeam-backup-replication-project-from-trial-download-to-monitored-backups-and-an-esxi-17ln</guid>
      <description>&lt;p&gt;A beginner-friendly, hands-on walkthrough of standing up Veeam Backup &amp;amp; Replication end to end on a single lab server — concepts, trial setup, agent vs agentless, protection groups, the LVM snapshot error that broke my first job, firewall gotchas, restore testing, Veeam ONE monitoring and alarms, and a bonus ESXi VM-backup phase.&lt;/p&gt;

&lt;h1&gt;
  
  
  My Veeam Backup &amp;amp; Replication Project — From Trial Download to Monitored Backups
&lt;/h1&gt;

&lt;p&gt;As part of my infrastructure showcase , I was given a fairly open-ended task: &lt;strong&gt;stand up Veeam Backup &amp;amp; Replication (VBR) from scratch and get a working, monitored backup environment running.&lt;/strong&gt; No prior Veeam experience, no existing lab — just a blank slate and the trial edition.&lt;/p&gt;

&lt;p&gt;The lab ended up looking like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;1 Windows Server&lt;/strong&gt; doing triple duty as the Veeam Backup Server, the Backup Repository, &lt;em&gt;and&lt;/em&gt; the Veeam ONE monitoring host — all on one ~700GB box&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;4 Linux clients&lt;/strong&gt; (RHEL/Rocky/AlmaLinux) backed up with the Veeam Agent for Linux&lt;/li&gt;
&lt;li&gt;Later, a &lt;strong&gt;VMware ESXi host&lt;/strong&gt; added on top, to get hands-on with agentless VM-level backup too&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This post documents the whole journey: what backup actually means and why it matters, how I got Veeam onto a test box, the agent vs. agentless decision, setting up protection groups (including the firewall issue that broke it), the LVM snapshot error that forced a change of backup mode, restore testing, reporting, Veeam ONE monitoring with alarms, and finally a bonus phase connecting a licensed ESXi host for VM backup and restore.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why backup even matters
&lt;/h2&gt;

&lt;p&gt;Before touching any software, it's worth being clear on &lt;em&gt;why&lt;/em&gt; this whole exercise exists.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;backup&lt;/strong&gt; is simply a copy of your data (and sometimes your entire system) stored somewhere separate from the original, so that if something goes wrong — hardware failure, accidental deletion, ransomware, a bad update, a full server dying — you can restore and keep operating instead of losing everything.&lt;/p&gt;

&lt;p&gt;The classic argument for backup boils down to a few failure scenarios that happen to &lt;em&gt;everyone&lt;/em&gt; eventually:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hardware failure&lt;/strong&gt; — disks die, servers crash, and RAID isn't a backup strategy on its own.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Human error&lt;/strong&gt; — someone deletes the wrong folder, overwrites the wrong file, or fat-fingers a config change.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ransomware/malware&lt;/strong&gt; — increasingly the #1 reason organizations lose data they can't get back, especially if backups themselves aren't protected.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Software or update failures&lt;/strong&gt; — a bad patch or corrupted database that isn't caught immediately.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without backups, any one of these can mean permanent data loss. With backups — and, just as importantly, &lt;em&gt;tested&lt;/em&gt; backups — the same event becomes a recovery task measured in minutes or hours instead of a catastrophe.&lt;/p&gt;

&lt;p&gt;Veeam is one of the major players in this space, offering both backup and replication (keeping a warm standby copy of a VM ready to fail over to) for physical machines, virtual machines, and cloud workloads.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Veeam: creating an account and downloading the trial
&lt;/h2&gt;

&lt;p&gt;Veeam doesn't let you just grab an installer anonymously — you need an account first:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Head to veeam.com and register for a free account (this doubles as your Veeam ID, used for licensing and support).&lt;/li&gt;
&lt;li&gt;Once registered, I could access the download center and grab the &lt;strong&gt;Veeam Backup &amp;amp; Replication&lt;/strong&gt; installer. Community Edition is free and fine for a basic/proof-of-concept setup — it supports up to 10 workloads free — but registering also auto-activates a &lt;strong&gt;30-day trial license&lt;/strong&gt;, which unlocks the full enterprise feature set so you can evaluate everything before deciding what to license.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8ahqh5giwm5sqlowao5g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8ahqh5giwm5sqlowao5g.png" alt=" " width="800" height="358"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This trial license is also why, near the end of this project, I started seeing expiry warnings pop up in the console — more on that later.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prerequisites checklist (worth confirming before you start)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Local administrator credentials on the Windows server; root or a sudo-capable account (with SSH access) on the Linux clients&lt;/li&gt;
&lt;li&gt;.NET Framework and Windows updates current on the server (both the VBR and Veeam ONE installers will flag anything missing)&lt;/li&gt;
&lt;li&gt;The Windows server should comfortably clear Veeam ONE's minimums &lt;strong&gt;on top of&lt;/strong&gt; running VBR: 4 CPU cores, 8GB RAM, 5GB free disk, in addition to whatever VBR itself needs&lt;/li&gt;
&lt;li&gt;Enough free disk space confirmed on the storage volume (leave some headroom, don't plan to fill it to 100%)&lt;/li&gt;
&lt;li&gt;SSH enabled and reachable on each Linux client — VBR connects to Linux machines over SSH, not WinRM&lt;/li&gt;
&lt;li&gt;Each client's OS major version checked ahead of time (&lt;code&gt;cat /etc/os-release&lt;/code&gt;) — the offline install package is version-specific (el7/el8/el9/el10)&lt;/li&gt;
&lt;li&gt;A machine with internet access to download the &lt;code&gt;veeam-libs&lt;/code&gt; and &lt;code&gt;veeam-nosnap&lt;/code&gt; offline install packages, since the clients themselves have no direct internet access&lt;/li&gt;
&lt;li&gt;Network connectivity confirmed between the server and each client&lt;/li&gt;
&lt;li&gt;Veeam ONE installer downloaded, matching the VBR version&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A resource constraint worth mentioning: no separate storage
&lt;/h2&gt;

&lt;p&gt;In a "proper" production Veeam deployment, you'd typically keep the &lt;strong&gt;backup server&lt;/strong&gt; (the brains — job scheduling, configuration database, console) separate from the &lt;strong&gt;backup repository&lt;/strong&gt; (the actual storage where backup files live), and often separate again from &lt;strong&gt;backup proxies&lt;/strong&gt; that handle the data movement, and from the &lt;strong&gt;monitoring host&lt;/strong&gt;. This separation is best practice because it avoids a single point of failure — if your backup server dies, your backup &lt;em&gt;data&lt;/em&gt; is still intact elsewhere.&lt;/p&gt;

&lt;p&gt;I didn't have that luxury for this project. With limited lab resources, I installed &lt;strong&gt;VBR, the backup repository, and Veeam ONE all on the same box&lt;/strong&gt;. It's a deliberate single-point-of-failure design: if that Windows server goes down, backups &lt;em&gt;and&lt;/em&gt; monitoring both stop at the same time. It's not how you'd want to run this in production, but it was enough to prove out the workflow — and it's worth flagging clearly here rather than glossing over it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Agent-based vs. agentless backup
&lt;/h2&gt;

&lt;p&gt;One of the first real decisions in Veeam is &lt;em&gt;how&lt;/em&gt; it's going to reach into a machine to actually back it up. There are two fundamentally different approaches:&lt;/p&gt;

&lt;h3&gt;
  
  
  Agentless backup
&lt;/h3&gt;

&lt;p&gt;Veeam talks directly to the &lt;strong&gt;hypervisor&lt;/strong&gt; (VMware vSphere, Microsoft Hyper-V, Nutanix AHV, etc.) and uses its snapshot APIs to capture a consistent image of the VM — no software needs to be installed inside the guest OS at all. This is generally the preferred approach for virtualized workloads because it's less invasive, easier to manage at scale, and doesn't add any agent overhead inside the VM.&lt;/p&gt;

&lt;h3&gt;
  
  
  Agent-based backup
&lt;/h3&gt;

&lt;p&gt;Veeam installs a small &lt;strong&gt;backup agent&lt;/strong&gt; directly inside the machine's operating system (Windows or Linux). The agent talks to the guest OS at the file-system/volume level to do the backup. This is the only real option for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Physical (bare-metal) servers and workstations&lt;/strong&gt; that aren't virtualized at all&lt;/li&gt;
&lt;li&gt;Machines running on &lt;strong&gt;hypervisors Veeam doesn't have agentless integration with&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Machines that are &lt;strong&gt;often offline or unreachable&lt;/strong&gt; (laptops, remote/branch office servers) — agent-based jobs are typically managed as policies that run locally rather than being triggered by a central server&lt;/li&gt;
&lt;li&gt;Cases where you need &lt;strong&gt;guest-level granularity&lt;/strong&gt; the hypervisor snapshot alone can't give you&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For my project, I started with the agent-based side — 4 Linux servers — and later added a licensed &lt;strong&gt;VMware ESXi host&lt;/strong&gt; to get hands-on with agentless, hypervisor-level backup too.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/PLACEHOLDER-agent-vs-agentless.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/PLACEHOLDER-agent-vs-agentless.png" alt="Diagram/screenshot contrasting agentless (hypervisor-based) vs agent-based backup" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1 — Install Veeam Backup &amp;amp; Replication on the server
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Log into the server with a local administrator account.&lt;/li&gt;
&lt;li&gt;Run the VBR installer.&lt;/li&gt;
&lt;li&gt;When prompted for the configuration database, accept the default — the installer sets up a local PostgreSQL instance automatically. You don't need a separate SQL Server for a basic setup like this.&lt;/li&gt;
&lt;li&gt;Let the installer also set up the local components it installs by default: the Backup Server service, the local Data Mover, and the console.&lt;/li&gt;
&lt;li&gt;Once installation finishes, open the &lt;strong&gt;Veeam Backup &amp;amp; Replication Console&lt;/strong&gt; and confirm it connects without errors. This is your central control point for everything from here on.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 2 — Add the local storage as a Backup Repository
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;In the console, go to &lt;strong&gt;Backup Infrastructure&lt;/strong&gt; → &lt;strong&gt;Repositories&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Right-click → &lt;strong&gt;Add Repository&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Choose &lt;strong&gt;Direct attached storage&lt;/strong&gt; → &lt;strong&gt;Microsoft Windows server&lt;/strong&gt; (since the repository is the same local server).&lt;/li&gt;
&lt;li&gt;Select the server itself as the location, and point it to the volume/folder where backup files should be stored.&lt;/li&gt;
&lt;li&gt;Finish the wizard, and confirm the repository shows up with its available capacity matching what you expect.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 3 — Install Veeam Agent for Linux (offline/nosnap method) on each client
&lt;/h2&gt;

&lt;p&gt;The clients don't have direct internet access, so this uses Veeam's &lt;strong&gt;offline (nosnap) install&lt;/strong&gt; — download the packages on a machine that does have internet, copy them over via SCP, then install locally. Since the clients are RHEL/Rocky/AlmaLinux, this uses &lt;code&gt;.rpm&lt;/code&gt; packages, and there are two of them — order matters: &lt;code&gt;veeam-libs&lt;/code&gt; (shared dependencies) has to go in before &lt;code&gt;veeam-nosnap&lt;/code&gt; (the actual agent).&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Check each client's OS version first&lt;/strong&gt;, since the package is version-specific (&lt;code&gt;el7&lt;/code&gt;/&lt;code&gt;el8&lt;/code&gt;/&lt;code&gt;el9&lt;/code&gt;/&lt;code&gt;el10&lt;/code&gt;):
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;cat&lt;/span&gt; /etc/os-release
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the version for each client — they may not all match.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;On a machine with internet access&lt;/strong&gt;, download both files for the matching version from Veeam's software repository. For version 9 clients, for example:

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;veeam-libs-13.1.0.252-1.x86_64.rpm&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;veeam-nosnap-13.1.0.252-1.el9.x86_64.rpm&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;(the &lt;code&gt;el9&lt;/code&gt;/&lt;code&gt;el8&lt;/code&gt;/&lt;code&gt;el7&lt;/code&gt;/&lt;code&gt;el10&lt;/code&gt; in the filename must match each client's actual version — using the wrong one is the most common failure here)&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Copy both files onto each client using SCP&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   scp &lt;span class="s2"&gt;"&amp;lt;local-file-path&amp;gt;"&lt;/span&gt; &amp;lt;username&amp;gt;@&amp;lt;client-ip&amp;gt;:&amp;lt;destination-folder&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note the colon after the IP — it tells SCP where on the remote machine to put the file. You'll be prompted to accept the SSH fingerprint the first time (&lt;code&gt;yes&lt;/code&gt;), then enter the account password. Repeat for each client, swapping the IP.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;On each client, install the libs package first, then the agent package&lt;/strong&gt;, matching the version confirmed in step 1:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;rpm &lt;span class="nt"&gt;-i&lt;/span&gt; /tmp/veeam-libs-13.1.0.252-1.x86_64.rpm
   &lt;span class="nb"&gt;sudo &lt;/span&gt;rpm &lt;span class="nt"&gt;-i&lt;/span&gt; /tmp/veeam-nosnap-13.1.0.252-1.el9.x86_64.rpm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Confirm the agent installed and is running:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status veeamservice
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No local job needs to be configured on the client itself — like the Windows flow, this gets added and managed centrally from the backup server in the next step, as long as it's set up in "managed by backup server" mode.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a Protection Group, and why do you need one?
&lt;/h2&gt;

&lt;p&gt;For the agent-based side of things, Veeam organizes target machines using &lt;strong&gt;Protection Groups&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;A protection group is essentially a &lt;strong&gt;dynamic (or static) list of computers&lt;/strong&gt; that should be protected with agent-based backups. Instead of manually adding machines to a backup job one by one — and having to remember to add every new server that shows up — a protection group defines the &lt;em&gt;scope&lt;/em&gt; (individual computers, an Active Directory OU, a CSV import, cloud instances, etc.) and Veeam periodically rescans that scope to catch new or removed machines automatically.&lt;/p&gt;

&lt;p&gt;The real value shows up at scale: if you're managing dozens or hundreds of Linux/Windows machines, you don't want backup coverage to depend on someone remembering to manually register every new server. A protection group can also handle &lt;strong&gt;agent deployment&lt;/strong&gt; for you — though since I'd already installed the agents manually in Step 3, I made sure to leave that option unchecked (more below).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmng8g0b7qmnyuy7olim8.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmng8g0b7qmnyuy7olim8.jpeg" alt=" " width="800" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Veeam gives you several ways to populate a group:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fileyjhyv3pij43y0gkvt.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fileyjhyv3pij43y0gkvt.jpeg" alt=" " width="799" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Since I was working with a small, fixed set of Linux servers with no Active Directory in the mix, I used &lt;strong&gt;Individual computers&lt;/strong&gt; — right-click &lt;strong&gt;Physical &amp;amp; Cloud Infrastructure&lt;/strong&gt; → &lt;strong&gt;Create protection group&lt;/strong&gt;, choose &lt;strong&gt;Individual computers&lt;/strong&gt;, name it (e.g. &lt;code&gt;Linux-Backup-Clients&lt;/code&gt;), and add each client's hostname or IP one at a time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On the Options screen&lt;/strong&gt; of the wizard (deployment settings), since the agents were already installed manually:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/assets%2F05-protection-group-options.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/assets%2F05-protection-group-options.jpeg" alt="Protection Group Options screen — discovery schedule and agent deployment settings" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Install backup agent&lt;/strong&gt; — leave unchecked (already done manually; checking it risks a conflicting reinstall)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Install nosnap agent (Linux only)&lt;/strong&gt; — leave unchecked, same reason&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Install application plug-ins&lt;/strong&gt; — leave unchecked, not needed for a basic setup&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Install CDP agent (enables replication)&lt;/strong&gt; — checked by default, &lt;strong&gt;uncheck it&lt;/strong&gt; — continuous replication is out of scope here&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enable auto-update for installed components&lt;/strong&gt; — leave unchecked, so nothing changes unexpectedly mid-setup&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Perform reboot automatically if required&lt;/strong&gt; — leave unchecked, don't let a client reboot itself unattended&lt;/li&gt;
&lt;li&gt;The default daily rescan schedule is fine to leave as-is — it only controls how often Veeam re-checks for new/changed machines, not the actual backup schedule&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Setting up credentials
&lt;/h2&gt;

&lt;p&gt;For Veeam to reach the Linux boxes, it needs credentials it can use to SSH in and elevate privileges. I set this up with a non-root account, using automatic privilege elevation via &lt;code&gt;sudo&lt;/code&gt; (with a fallback to &lt;code&gt;su&lt;/code&gt; if sudo isn't available).&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing connectivity — and the firewall gotcha
&lt;/h2&gt;

&lt;p&gt;Before trusting the deployment to actually run, Veeam lets you test the connection to every target first. My first attempt showed the hosts mid-test:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjfu4qiz5ulv44nreccqg.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fjfu4qiz5ulv44nreccqg.jpeg" alt=" " width="799" height="256"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Known issue hit during this deployment:&lt;/strong&gt; all four clients failed the Test Connection step with a generic "Failed" status and no detail beyond "Credentials test has been completed." The root cause was &lt;code&gt;firewalld&lt;/code&gt; blocking port 22 (SSH) on the clients — despite SSH itself running fine. Fix, run on &lt;strong&gt;each&lt;/strong&gt; client:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;firewall-cmd &lt;span class="nt"&gt;--permanent&lt;/span&gt; &lt;span class="nt"&gt;--add-service&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ssh
&lt;span class="nb"&gt;sudo &lt;/span&gt;firewall-cmd &lt;span class="nt"&gt;--reload&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Confirm with &lt;code&gt;sudo firewall-cmd --list-all&lt;/code&gt; — you should see &lt;code&gt;ssh&lt;/code&gt; listed under &lt;code&gt;services:&lt;/code&gt;. Since this was a default &lt;code&gt;firewalld&lt;/code&gt; config issue, it hit all four clients identically, so it was worth applying to all of them at once rather than fixing and retesting one at a time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frliperbuhlw43gpn3iua.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frliperbuhlw43gpn3iua.png" alt=" " width="600" height="334"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once that was sorted, all four hosts came back green:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkxe786yu4l5y1e9mkm65.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkxe786yu4l5y1e9mkm65.png" alt=" " width="799" height="256"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once applied, Veeam ran through discovery, package installation, and database record creation automatically:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If a client fails to add:&lt;/strong&gt; the most common causes are SSH not running or blocked by a firewall on the client, or the account lacking sudo rights — check both before troubleshooting further.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building the Agent Backup Job
&lt;/h2&gt;

&lt;p&gt;With the protection group live, it was time to create the actual backup job. Veeam gives you three backup modes to choose from:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Entire computer&lt;/strong&gt; — full image-level backup, best for fast, any-level recovery&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Volume level backup&lt;/strong&gt; — back up specific volumes only, reducing backup size&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File level backup&lt;/strong&gt; — slower, but only backs up selected files/folders instead of a full image&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flnnixr6k1qy2nmlffjcz.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flnnixr6k1qy2nmlffjcz.jpeg" alt=" " width="600" height="204"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I pointed the job at the protection group I'd just created, and set &lt;strong&gt;Mode: Managed by backup server&lt;/strong&gt; (not "Managed by agent"/standalone) — this keeps scheduling, jobs, and monitoring centralized in the VBR console rather than each client managing its own local job.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft6vs5ohkg0uow7rb49mk.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ft6vs5ohkg0uow7rb49mk.jpeg" alt=" " width="600" height="191"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The LVM snapshot error — and why I switched to file-level
&lt;/h3&gt;

&lt;p&gt;My first instinct was &lt;strong&gt;Entire computer&lt;/strong&gt; mode. All four clients promptly failed with:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;"Insufficient free space for a snapshot in a volume group"&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Entire machine and Volume level backup both rely on LVM snapshots to run, and in this deployment none of the clients' volume groups had free/unallocated space for LVM to create one in. The fix: switch to &lt;strong&gt;File level backup&lt;/strong&gt;, and check &lt;strong&gt;"Backup directly from live file system"&lt;/strong&gt; (the snapshot-less option, only available in file-level mode). This skips the snapshot mechanism entirely and reads files straight off the live filesystem instead. The trade-off is no point-in-time consistency guarantee if a file changes mid-backup — a non-issue for a basic setup backing up static test data.&lt;/p&gt;

&lt;p&gt;For file-level backups, you scope the job down to specific objects/folders instead of the whole filesystem:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /veeam-test-data
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"test file for backup verification"&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /veeam-test-data/testfile.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhu56o5f3zupnwin0xgv7.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhu56o5f3zupnwin0xgv7.jpeg" alt=" " width="600" height="224"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Deliberately using a small, known test folder (rather than &lt;code&gt;/&lt;/code&gt;, which would drag in &lt;code&gt;/proc&lt;/code&gt;, &lt;code&gt;/sys&lt;/code&gt;, &lt;code&gt;/dev&lt;/code&gt; and other virtual filesystems) also makes the restore test later completely unambiguous — you know exactly what should come back.&lt;/p&gt;

&lt;h2&gt;
  
  
  Storage and retention
&lt;/h2&gt;

&lt;p&gt;Next up was picking a backup repository and setting a retention policy — in my case, keeping 14 days of restore points. Because the repository lived on the same machine as VBR itself (see the resource constraint above), this step was also a reminder of why production environments separate the two.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy29k73evzm7biaii3amw.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy29k73evzm7biaii3amw.jpeg" alt=" " width="600" height="237"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting a basic schedule
&lt;/h2&gt;

&lt;p&gt;Under the job's &lt;strong&gt;Schedule&lt;/strong&gt; properties, I set it to run daily at a time when the clients are least busy (e.g. overnight), and saved.&lt;/p&gt;

&lt;h2&gt;
  
  
  Watching the job run
&lt;/h2&gt;

&lt;p&gt;Once the job kicked off, I could watch it process each host in real time from the Home → Jobs view — including throughput, processing rate, and per-object status.&lt;/p&gt;

&lt;p&gt;Right-click the job → &lt;strong&gt;Start&lt;/strong&gt; triggers it manually rather than waiting for the schedule. All four clients should finish with a green "Success" status — yellow ("Warning") is worth reading into, red ("Failed") needs troubleshooting before moving on. Checking the repository's used space afterward confirms data actually landed there.&lt;/p&gt;

&lt;h2&gt;
  
  
  Testing a restore (don't skip this)
&lt;/h2&gt;

&lt;p&gt;A backup that has never been restored isn't a verified backup. Since the job used file-level backup, I went to &lt;strong&gt;Home → Backups&lt;/strong&gt;, right-clicked the job, and chose the &lt;strong&gt;File level&lt;/strong&gt; (a.k.a. &lt;strong&gt;Guest OS files&lt;/strong&gt;) restore option:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Pick the client and the most recent successful restore point.&lt;/li&gt;
&lt;li&gt;This opens a file browser showing the backed-up filesystem as it looked at that point in time — navigate to &lt;code&gt;/veeam-test-data&lt;/code&gt; and confirm &lt;code&gt;testfile.txt&lt;/code&gt; actually shows up.&lt;/li&gt;
&lt;li&gt;Right-click &lt;code&gt;testfile.txt&lt;/code&gt; → &lt;strong&gt;Restore&lt;/strong&gt; → &lt;strong&gt;"Restore to the following location"&lt;/strong&gt; (rather than overwriting the original) → point it at a temporary folder like &lt;code&gt;/tmp/restore-test/&lt;/code&gt;. Restoring somewhere new lets you compare the two side by side rather than just trusting the process worked.&lt;/li&gt;
&lt;li&gt;On the client, confirm the file landed:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; /tmp/restore-test/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Open it and confirm the content matches exactly:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;cat&lt;/span&gt; /tmp/restore-test/testfile.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It should print exactly &lt;code&gt;test file for backup verification&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Matching content — not just a file existing — is what actually proves the setup works end to end, not just that a backup file exists in the repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting reports on the backups
&lt;/h2&gt;

&lt;p&gt;A backup job that runs is only useful if you can actually verify it worked — so part of this project was pulling &lt;strong&gt;reports&lt;/strong&gt; out of Veeam to confirm job success/failure history, data transferred, and job duration over time, rather than just eyeballing the console. This is also what you'd hand to a manager or auditor as proof backups are actually happening on schedule.&lt;/p&gt;

&lt;h2&gt;
  
  
  Connecting Veeam ONE for monitoring
&lt;/h2&gt;

&lt;p&gt;Backups are only half the story — you also want ongoing visibility into whether they're staying healthy over time, not just at the moment a job finishes. That's where &lt;strong&gt;Veeam ONE&lt;/strong&gt; comes in: it's Veeam's monitoring, reporting, and capacity-planning layer that sits on top of VBR.&lt;/p&gt;

&lt;p&gt;Only do this once the backup job above is working and verified — Veeam ONE monitors an existing, functioning backup setup, it isn't part of getting backups running in the first place.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Confirm the server still has enough free CPU/RAM/disk headroom on top of what VBR is already using — Veeam ONE's minimums (4 CPU cores, 8GB RAM, 5GB free disk) apply on top of, not instead of, VBR's requirements.&lt;/li&gt;
&lt;li&gt;Run the Veeam ONE installer, matching the version to the installed VBR version, and accept the default local configuration database — it uses its own separate database instance from VBR's, even though both run on the same machine.&lt;/li&gt;
&lt;li&gt;Let the installer set up its three components: the &lt;strong&gt;Veeam ONE Server&lt;/strong&gt; (core monitoring engine), &lt;strong&gt;Veeam ONE Reporter&lt;/strong&gt; (web-based reporting), and the &lt;strong&gt;Veeam ONE Client&lt;/strong&gt; (console for real-time monitoring).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confirm the account you'll use has the right permissions.&lt;/strong&gt; Veeam ONE needs a Windows account that's a member of the local &lt;strong&gt;Performance Monitor Users&lt;/strong&gt; and &lt;strong&gt;Event Log Readers&lt;/strong&gt; security groups, plus general access to VBR itself.&lt;/li&gt;
&lt;li&gt;Open the &lt;strong&gt;Veeam ONE Client&lt;/strong&gt;, expand the &lt;strong&gt;Veeam Backup &amp;amp; Replication&lt;/strong&gt; view in the left inventory pane, right-click the top-level node → &lt;strong&gt;Add Server&lt;/strong&gt; (or &lt;strong&gt;Ctrl+I&lt;/strong&gt;):&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwhez985rlxado98qrhlh.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwhez985rlxado98qrhlh.jpeg" alt=" " width="600" height="243"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Choose server type &lt;strong&gt;Veeam Backup &amp;amp; Replication server&lt;/strong&gt;, enter the server's hostname/IP (more reliable than &lt;code&gt;localhost&lt;/code&gt;, since some components resolve names rather than loopback addresses), and enter the credentials confirmed above — this is a standard Windows login, not a Veeam-specific account.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I added the VBR server as a data source, reusing the same service account credentials:&lt;/p&gt;

&lt;p&gt;The Data Collection Overview page, before the server was registered:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8gzhnwfg30xav1imom74.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8gzhnwfg30xav1imom74.jpeg" alt=" " width="600" height="291"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Rounding out the wizard, the deployment reuses the same credentials for connection, analytics service deployment, and backup monitoring:&lt;/p&gt;

&lt;p&gt;And here's the summary screen before finishing setup:&lt;/p&gt;

&lt;p&gt;The first sync can take a few minutes, since it pulls in everything VBR already knows: the repository, the backup job, the protection group, and all the clients within it — without you manually entering any of it into Veeam ONE.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up and testing alarms
&lt;/h2&gt;

&lt;p&gt;Configuration alone doesn't prove monitoring works — you have to actually trigger a failure and watch it get caught.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In the Veeam ONE Web Client, open &lt;strong&gt;Alarm Management&lt;/strong&gt; (configuration) — different from &lt;strong&gt;Alarms Overview&lt;/strong&gt; (where triggered alarms actually show up).&lt;/li&gt;
&lt;li&gt;Expand the &lt;strong&gt;Veeam Backup &amp;amp; Replication&lt;/strong&gt; branch, and find the &lt;strong&gt;job failure/warning alarm&lt;/strong&gt;. Predefined alarms ship enabled by default, so this is mainly a confirmation check.&lt;/li&gt;
&lt;li&gt;Find the &lt;strong&gt;repository free-space alarm&lt;/strong&gt; (default threshold is often 90–95%). With a tight storage budget across several clients, it's worth lowering that to around 80% so there's room to react before the repository actually fills.&lt;/li&gt;
&lt;li&gt;Confirm both alarms are scoped to include the VBR server — predefined alarms usually auto-apply to all connected data sources, but it's worth a quick visual check.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trigger a real test failure.&lt;/strong&gt; On one Linux client, stop the Veeam Agent service so its next backup attempt fails cleanly:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl stop veeamservice
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Back in the VBR console, right-click the job → &lt;strong&gt;Start&lt;/strong&gt;. With one client's agent stopped, that client should fail while the others succeed — a partial failure, closer to a real-world scenario than a total outage.&lt;/li&gt;
&lt;li&gt;Go to &lt;strong&gt;Alarms Overview&lt;/strong&gt; in Veeam ONE. Within a few minutes, a new triggered alarm should appear showing the affected job/client, severity, and timestamp. This — not the configuration steps above — is the actual proof the monitoring layer is watching your environment, not just installed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clean up:&lt;/strong&gt; restart the agent (&lt;code&gt;sudo systemctl start veeamservice&lt;/code&gt;), re-run the job, confirm it now succeeds cleanly, and mark the alarm resolved/acknowledged.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Veeam ONE dashboard
&lt;/h2&gt;

&lt;p&gt;Once data started flowing in, the Veeam Backup and Replication dashboard in Veeam ONE gave a much richer overview than the VBR console alone — backup infrastructure inventory, backup window trends, job status history, protected workload percentage, job duration, and repository usage, all in one place.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxdh3ub3x1bt1c2vnpkfb.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fxdh3ub3x1bt1c2vnpkfb.jpeg" alt=" " width="800" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Checking the Threat Center
&lt;/h2&gt;

&lt;p&gt;Veeam also ships a &lt;strong&gt;Threat Center&lt;/strong&gt; that scores your environment's overall data protection posture and flags any malware detected in restore points. My lab environment scored 59.7% ("Vulnerable Zone") — mostly because things like immutability and MFA weren't fully configured, which is a good reminder that a working backup job isn't the same as a &lt;em&gt;secure&lt;/em&gt; backup setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus phase: adding a licensed ESXi host for VM backup
&lt;/h2&gt;

&lt;p&gt;Once the Linux-agent side was solid, the project added a second phase: connecting a &lt;strong&gt;VMware ESXi host&lt;/strong&gt; to get hands-on with agentless, hypervisor-level backup too — dropping one Linux client from scope to make room.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Licensing note confirmed for this phase:&lt;/strong&gt; the fully free VMware ESXi hypervisor lacks the vStorage APIs Veeam needs for VM backup and is &lt;strong&gt;not&lt;/strong&gt; supported, regardless of VBR edition. A &lt;strong&gt;licensed&lt;/strong&gt; ESXi host (Essentials tier or higher) is fully supported for direct VM backup with VBR Community Edition, with no vCenter required.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Remove one Linux client&lt;/strong&gt; from the existing job and protection group (which one doesn't matter functionally — just document the choice).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add the ESXi host as a new infrastructure connection.&lt;/strong&gt; In the VBR console: &lt;strong&gt;Inventory → Virtual Infrastructure&lt;/strong&gt; (a separate section from &lt;strong&gt;Physical &amp;amp; Cloud Infrastructure&lt;/strong&gt;, where the Linux clients live) → right-click → &lt;strong&gt;Add Server → VMware vSphere&lt;/strong&gt; → choose &lt;strong&gt;ESXi host&lt;/strong&gt; specifically (not vCenter Server, since this connects directly to a single licensed host).&lt;/li&gt;
&lt;li&gt;Enter the ESXi host's IP and its root/admin credentials — a different credential type from the Windows or SSH accounts used elsewhere. VBR connects over the vSphere API, typically port 443.&lt;/li&gt;
&lt;li&gt;Finish the wizard — VBR discovers the host's VMs, datastores, and networks. Confirm the host appears under Virtual Infrastructure with its VMs listed underneath.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Backing up a VM from the ESXi host
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Home → Backup Job → Virtual machine&lt;/strong&gt; (a different job type from the Linux Computer job — this is hypervisor-level, not agent-based).&lt;/li&gt;
&lt;li&gt;Name it clearly (e.g. &lt;code&gt;ESXi-VM-Backup&lt;/code&gt;), add the specific VM as the source, and set the destination to the same repository used throughout.&lt;/li&gt;
&lt;li&gt;Leave retention at defaults, same approach as the rest of the basic setup.&lt;/li&gt;
&lt;li&gt;Right-click the job → &lt;strong&gt;Start&lt;/strong&gt;, and confirm it completes successfully. This uses a native VMware snapshot mechanism rather than the LVM-based one that caused the earlier Linux client failure, so that specific issue shouldn't recur here.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Restoring the VM and verifying it
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Once the backup completes: &lt;strong&gt;Home → Restore&lt;/strong&gt; → choose a VM-level restore option (&lt;strong&gt;Entire VM restore&lt;/strong&gt; or &lt;strong&gt;Instant VM Recovery&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt;Select the VM and the restore point just created.&lt;/li&gt;
&lt;li&gt;Choose restore location — original location (overwrite) or a new location on the same host. Overwriting is more disruptive if the VM is actually in use, so this is worth confirming with a supervisor before doing it live.&lt;/li&gt;
&lt;li&gt;Confirm the VM is present and boots/runs correctly on the ESXi host — the same principle as the file-content check used for the Linux client restore: proof the restore produced a working result, not just that the wizard finished without error.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Quick troubleshooting checklist
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Symptom&lt;/th&gt;
&lt;th&gt;Likely cause&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Client won't add to inventory&lt;/td&gt;
&lt;td&gt;SSH not running/blocked by &lt;code&gt;ufw&lt;/code&gt;/&lt;code&gt;firewalld&lt;/code&gt; on the client, or the account lacks sudo rights&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Job fails immediately&lt;/td&gt;
&lt;td&gt;Repository out of space, or client agent (&lt;code&gt;veeamservice&lt;/code&gt;) not running — check with &lt;code&gt;systemctl status veeamservice&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Job fails with "Insufficient free space for a snapshot in a volume group"&lt;/td&gt;
&lt;td&gt;LVM has no free space to create a snapshot. Fix: switch to File level backup mode and check "Backup directly from live file system"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test Connection fails with no detail beyond "Credentials test has been completed"&lt;/td&gt;
&lt;td&gt;Likely &lt;code&gt;firewalld&lt;/code&gt; blocking port 22, even though SSH itself is running. Run &lt;code&gt;sudo firewall-cmd --permanent --add-service=ssh &amp;amp;&amp;amp; sudo firewall-cmd --reload&lt;/code&gt; and retest&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;rpm -i&lt;/code&gt; install fails on a client&lt;/td&gt;
&lt;td&gt;Wrong version package used (el7/el8/el9/el10 mismatch), or &lt;code&gt;veeam-libs&lt;/code&gt; wasn't installed first&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SCP command fails or hangs&lt;/td&gt;
&lt;td&gt;Missing colon before the destination path, wrong username/IP, or SSH not reachable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Job is very slow&lt;/td&gt;
&lt;td&gt;Network throughput between client and server, or too much data selected in "Entire computer" mode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Restore fails&lt;/td&gt;
&lt;td&gt;Backup file corrupted/incomplete — check the original job's log for warnings&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Veeam ONE can't add VBR as a source&lt;/td&gt;
&lt;td&gt;Credentials lack access to VBR server, or version mismatch between Veeam ONE and VBR&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Veeam ONE shows no alarms firing&lt;/td&gt;
&lt;td&gt;Confirm the VBR data source connection is active, not just added&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  What's intentionally left out of this basic pass
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Retention policy tuning&lt;/li&gt;
&lt;li&gt;Offsite/second-copy design (currently a single point of failure by design — one server carries backup, storage, and monitoring together)&lt;/li&gt;
&lt;li&gt;Advanced Veeam ONE reporting/dashboards beyond basic failure and free-space alarms&lt;/li&gt;
&lt;li&gt;Immutability / ransomware protection&lt;/li&gt;
&lt;li&gt;Application-aware processing for anything running databases&lt;/li&gt;
&lt;li&gt;Replication or Continuous Data Protection (CDP) for the ESXi VM — this phase covers standard backup/restore only, not near-continuous replication&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;By the end of this project, I had:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Registered for a Veeam account and installed the 30-day trial edition&lt;/li&gt;
&lt;li&gt;Understood the trade-offs between agentless (hypervisor-based) and agent-based backup, and used both&lt;/li&gt;
&lt;li&gt;Built a protection group and deployed backup agents to a set of Linux servers, working through a firewalld connectivity issue along the way&lt;/li&gt;
&lt;li&gt;Hit and fixed an LVM snapshot error by switching to file-level, snapshot-less backup&lt;/li&gt;
&lt;li&gt;Created an agent-based backup job with a defined retention policy, and actually restored a file to verify it worked&lt;/li&gt;
&lt;li&gt;Pulled reports to verify backup success over time&lt;/li&gt;
&lt;li&gt;Wired up Veeam ONE for ongoing monitoring, dashboards, and alarms — and proved the alarms actually fire on a real failure&lt;/li&gt;
&lt;li&gt;Gotten a first look at the Threat Center and what a "healthy" score actually requires&lt;/li&gt;
&lt;li&gt;Connected a licensed ESXi host and backed up/restored a VM agentlessly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A few things worth calling out for anyone doing this for the first time:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Separate your backup server, repository, and monitoring host if you can.&lt;/strong&gt; I couldn't, due to lab constraints, but it's a real single-point-of-failure risk worth understanding, not just a nice-to-have.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent vs. agentless isn't a style choice — it's dictated by your environment.&lt;/strong&gt; Physical servers, offline machines, and unsupported hypervisors need agents; supported virtualization platforms are almost always better served agentlessly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Firewall rules are easy to forget&lt;/strong&gt; and will silently break agent deployment or job connectivity — always the first thing to check when something won't connect.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LVM snapshot space isn't guaranteed&lt;/strong&gt; — if entire-computer or volume-level backup fails with a snapshot error, file-level with "backup directly from live file system" is the pragmatic fallback.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A "Success" backup job doesn't mean a "secure" environment.&lt;/strong&gt; The Threat Center score was a good wake-up call that immutability and repository hardening are a separate step from just getting jobs to run.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A backup that's never been restored isn't verified&lt;/strong&gt; — and reports matter as much as the jobs themselves, since a backup nobody checks on is a backup you can't fully trust.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And, right on schedule, the trial reminded me it wasn't going to stick around forever:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/assets%2F21-trial-license-warning.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/assets%2F21-trial-license-warning.jpeg" alt="Veeam Backup and Replication trial license expiration warning with job status list in the background" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>veeam</category>
      <category>backup</category>
      <category>sysadmin</category>
      <category>infrastructure</category>
    </item>
    <item>
      <title>Zabbix Triggers, Dashboards, Graphs, Notifications, and Alerting.</title>
      <dc:creator>Morodolu Oluwafikunayomi</dc:creator>
      <pubDate>Mon, 13 Jul 2026 18:53:05 +0000</pubDate>
      <link>https://dev.to/fikalz/zabbix-triggers-dashboards-graphs-notifications-and-alerting-29ab</link>
      <guid>https://dev.to/fikalz/zabbix-triggers-dashboards-graphs-notifications-and-alerting-29ab</guid>
      <description>&lt;p&gt;Part 3 will focus on turning Zabbix from a monitoring dashboard into an active alerting system.&lt;br&gt;
So far, we have successfully connected our monitored server to Zabbix. The Zabbix server can now collect metrics from our agent, such as CPU usage, memory utilization, disk space, and system information.&lt;/p&gt;

&lt;p&gt;However, monitoring data alone is not enough.&lt;/p&gt;

&lt;p&gt;Imagine a production server running out of disk space. Zabbix can collect the disk usage percentage every minute, but unless someone checks the dashboard manually, nobody knows there is a problem.&lt;/p&gt;

&lt;p&gt;This is where triggers, alerts, and notifications come in.&lt;br&gt;
A complete monitoring workflow looks like this:&lt;br&gt;
&lt;code&gt;Metric Collection&lt;br&gt;
       |&lt;br&gt;
       |&lt;br&gt;
       v&lt;br&gt;
   Zabbix Items&lt;br&gt;
       |&lt;br&gt;
       |&lt;br&gt;
       v&lt;br&gt;
    Triggers&lt;br&gt;
       |&lt;br&gt;
       |&lt;br&gt;
       v&lt;br&gt;
 Problem Detection&lt;br&gt;
       |&lt;br&gt;
       |&lt;br&gt;
       v&lt;br&gt;
 Notifications&lt;br&gt;
       |&lt;br&gt;
       |&lt;br&gt;
       v&lt;br&gt;
 Administrator Action&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Understanding Zabbix Items&lt;/p&gt;

&lt;p&gt;Before creating triggers, we need to understand items.&lt;/p&gt;

&lt;p&gt;An item is a metric that Zabbix collects from a monitored host.&lt;/p&gt;

&lt;p&gt;Examples:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Item&lt;/strong&gt;  &lt;strong&gt;------&amp;gt;&lt;/strong&gt;                          &lt;strong&gt;Purpose&lt;/strong&gt;&lt;br&gt;
CPU utilization------&amp;gt;           Monitor processor usage&lt;br&gt;
Memory utilization-----&amp;gt;     Monitor RAM usage&lt;br&gt;
Disk space-----&amp;gt;             Monitor storage capacity&lt;br&gt;
Network traffic -----&amp;gt;   Monitor bandwidth&lt;br&gt;
System uptime------&amp;gt;             Monitor availability&lt;br&gt;
example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Host:
rhcsa

Item:
CPU utilization

Value:
35%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Creating a Trigger&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A trigger defines when a normal metric becomes a problem.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Think of it like this:

Item:

CPU usage = 95%

Trigger:

If CPU usage is above 90% for 5 minutes,
create a problem.

The trigger is the logic that converts data into an event.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;*&lt;em&gt;Create a CPU Trigger&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
Go to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Monitoring
    |
  Host
   |
specific Hosts(rhcsa)
   |
 Triggers
   |
   Create trigger
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsxbz0yhpm9s2d10nprqk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fsxbz0yhpm9s2d10nprqk.png" alt=" " width="499" height="562"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fill in:&lt;/p&gt;

&lt;p&gt;Name:&lt;/p&gt;

&lt;p&gt;High CPU Usage on {HOST.NAME} in this case ours is {rhcsa}&lt;/p&gt;

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

&lt;p&gt;Warning&lt;/p&gt;

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

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

&lt;p&gt;Add&lt;/p&gt;

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

&lt;p&gt;Item:&lt;br&gt;
CPU utilization&lt;/p&gt;

&lt;p&gt;Condition:&lt;/p&gt;

&lt;p&gt;Last value &amp;gt; 20&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example expression:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;last(/rhcsa/system.cpu.util)&amp;gt;90&lt;/p&gt;

&lt;p&gt;Click:&lt;/p&gt;

&lt;p&gt;Add&lt;/p&gt;

&lt;p&gt;Now Zabbix will monitor CPU usage.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmc3j9i7k0qrvakhhhjfh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmc3j9i7k0qrvakhhhjfh.png" alt=" " width="800" height="396"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fho3nypqpea4vh73svabc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fho3nypqpea4vh73svabc.png" alt=" " width="800" height="398"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;last(/rhcsa/system.cpu.util,#20)&amp;gt;20 isnt the same last(/rhcsa/system.cpu.util)&amp;gt;20 do take note as the latter&lt;br&gt;
Take the most recent value of system.cpu.util and check if it is greater than 20.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;on the rhcsa where the agent is we would trigger a high cpu usage using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;yes&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or in the zabbix server :&lt;br&gt;
 zabbix_get -s 192.168.120.130(ip of the agent) -k system.cpu.util&lt;br&gt;
43.189230&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc0h5bfzahu6tcini9ow5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc0h5bfzahu6tcini9ow5.png" alt=" " width="798" height="142"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating Dashboards&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dashboards provide a visual overview of your infrastructure.&lt;br&gt;
zabbix 7.0 already provides a nice visual dashboard all we need to do is edit as we see fit, such as  editing and showing us which host/server/system is using the most cpu and adding more host to view&lt;br&gt;
and change the parameters we see as well&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fncqm6gpvvaq75emr359y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fncqm6gpvvaq75emr359y.png" alt=" " width="800" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa6w3vcnx9mog53z27k1z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fa6w3vcnx9mog53z27k1z.png" alt=" " width="702" height="504"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F31h7m05w7fhdvzacyv6a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F31h7m05w7fhdvzacyv6a.png" alt=" " width="710" height="510"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I had edited what i wish to see which is all the host/system/server, their cpu usage, memory not in use and how many user are logged in, feel free to play around as long it not a live or a production server. :D&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmkkriyoqv0zpmdahz7ia.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmkkriyoqv0zpmdahz7ia.png" alt=" " width="417" height="348"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Configuring Notifications&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A trigger detects a problem.&lt;/p&gt;

&lt;p&gt;A notification tells someone about it.&lt;/p&gt;

&lt;p&gt;The flow:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Trigger&lt;br&gt;
   |&lt;br&gt;
   |&lt;br&gt;
   v&lt;br&gt;
Action&lt;br&gt;
   |&lt;br&gt;
   |&lt;br&gt;
   v&lt;br&gt;
Media Type&lt;br&gt;
   |&lt;br&gt;
   |&lt;br&gt;
   v&lt;br&gt;
Email / Slack / Teams / SMS&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;in order to achieve this we must create a user or users that will be assigned to receive such triggers:&lt;br&gt;
Go to:&lt;br&gt;
alert--&amp;gt;media&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpextcjfqyjvqq1x3pdm1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpextcjfqyjvqq1x3pdm1.png" alt=" " width="800" height="359"&gt;&lt;/a&gt;&lt;br&gt;
Select your user.&lt;/p&gt;

&lt;p&gt;`Go to:&lt;/p&gt;

&lt;p&gt;Media&lt;/p&gt;

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

&lt;p&gt;Type:&lt;/p&gt;

&lt;p&gt;Email&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;&lt;a href="mailto:admin@example.com"&gt;admin@example.com&lt;/a&gt;`&lt;/p&gt;
&lt;h1&gt;
  
  
  Configure Zabbix Email Alert Notifications (Complete Step-by-Step Guide)
&lt;/h1&gt;

&lt;p&gt;After creating triggers in Zabbix, the next step is to configure &lt;strong&gt;alert actions&lt;/strong&gt; so that Zabbix can automatically notify administrators when a problem occurs.&lt;/p&gt;

&lt;p&gt;In this guide, we will configure Zabbix to send an email notification when CPU usage becomes high.&lt;/p&gt;

&lt;p&gt;The process involves:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Creating the trigger&lt;/li&gt;
&lt;li&gt;Creating an email media type&lt;/li&gt;
&lt;li&gt;Configuring Gmail SMTP&lt;/li&gt;
&lt;li&gt;Creating a Google App Password&lt;/li&gt;
&lt;li&gt;Assigning the media to a Zabbix user&lt;/li&gt;
&lt;li&gt;Creating an alert action&lt;/li&gt;
&lt;li&gt;Testing the notification&lt;/li&gt;
&lt;/ol&gt;


&lt;h1&gt;
  
  
  Step 1: Create an Email Media Type
&lt;/h1&gt;

&lt;p&gt;First, we need to tell Zabbix how it should send emails.&lt;/p&gt;

&lt;p&gt;Navigate to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Alerts
   |
Media types
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create media type
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configure the following:&lt;/p&gt;

&lt;h3&gt;
  
  
  Name
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;trigger or problem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Type
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Email
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Email provider
&lt;/h3&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Generic SMTP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configure the SMTP settings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SMTP server:
smtp.gmail.com

SMTP server port:
465
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For Gmail, use SSL/TLS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Connection security:
SSL/TLS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not use port 587 with STARTTLS if your network blocks it.&lt;/p&gt;




&lt;h1&gt;
  
  
  Step 2: Configure Gmail Authentication
&lt;/h1&gt;

&lt;p&gt;At first, we tried sending email without authentication, but Gmail rejected the request.&lt;/p&gt;

&lt;p&gt;The error received was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;530 Authentication required
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Gmail does not allow applications to send email using only the email address.&lt;/p&gt;

&lt;p&gt;You must use a Google App Password.&lt;/p&gt;




&lt;h1&gt;
  
  
  Step 3: Create a Google App Password
&lt;/h1&gt;

&lt;p&gt;Open your Google Account:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://myaccount.google.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Security
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2-Step Verification
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After enabling it, go back to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Security
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;App passwords
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a new app password.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Other (Custom name)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Zabbix
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Google will generate a 16-character password.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;xxxx xxxx xxxx xxxx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy this password.&lt;/p&gt;

&lt;p&gt;Important:&lt;/p&gt;

&lt;p&gt;Do not use your normal Gmail password.&lt;/p&gt;

&lt;p&gt;The Google App Password is the password Zabbix uses to authenticate with Gmail SMTP.&lt;/p&gt;




&lt;h1&gt;
  
  
  Step 4: Complete the Zabbix Email Configuration
&lt;/h1&gt;

&lt;p&gt;Return to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Alerts
   |
Media types
   |
trigger or problem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configure:&lt;/p&gt;

&lt;h3&gt;
  
  
  Email
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;morodoluoluwafikunayomo@gmail.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Authentication
&lt;/h3&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;None
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Username and password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enter:&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;morodoluoluwafikunayomo@gmail.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Google App Password generated earlier
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Step 5: Add Message Templates
&lt;/h1&gt;

&lt;p&gt;Without a message template, Zabbix will create the alert but fail to send it.&lt;/p&gt;

&lt;p&gt;The error will look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;No message defined for media type
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Alerts
   |
Media types
   |
trigger or problem
   |
Message templates
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Add
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a Problem template.&lt;/p&gt;

&lt;p&gt;Message type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Problem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Problem started at {EVENT.TIME} on {EVENT.DATE}

Problem name:
{EVENT.NAME}

Host:
{HOST.NAME}

Severity:
{EVENT.SEVERITY}

Operational data:
{EVENT.OPDATA}

Event ID:
{EVENT.ID}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save.&lt;/p&gt;




&lt;h1&gt;
  
  
  Step 6: Assign the Media Type to the Admin User
&lt;/h1&gt;

&lt;p&gt;Creating a media type is not enough.&lt;/p&gt;

&lt;p&gt;Zabbix users need to have a notification method assigned.&lt;/p&gt;

&lt;p&gt;If this step is skipped, you will get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;No media defined for user
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Go to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Users
   |
Admin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open the:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Media
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;tab.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Add
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configure:&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;trigger or problem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Send to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;morodoluoluwafikunayomo@gmail.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When active:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1-7,00:00-24:00
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Select severities:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Warning
Average
High
Disaster
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save the user.&lt;/p&gt;




&lt;h1&gt;
  
  
  Step 7: Create the Alert Action
&lt;/h1&gt;

&lt;p&gt;Now we tell Zabbix what to do when a problem occurs.&lt;/p&gt;

&lt;p&gt;Navigate to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Alerts
   |
Actions
   |
Trigger actions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create action
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Action Name
&lt;/h2&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Send CPU Alerts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Conditions
&lt;/h2&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Add condition
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Trigger severity
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;is greater than or equals
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;High
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The condition becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Trigger severity &amp;gt;= High
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means only High and Disaster problems will send notifications.&lt;/p&gt;




&lt;h2&gt;
  
  
  Operations
&lt;/h2&gt;

&lt;p&gt;Go to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Operations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Add
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Send message
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Send to users
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Admin (Zabbix Administrator)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Select media type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;trigger or problem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save the action.&lt;/p&gt;

&lt;p&gt;Make sure the action status is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Enabled
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h1&gt;
  
  
  Step 8: Test the Alert
&lt;/h1&gt;

&lt;p&gt;Generate a CPU problem on the monitored host:&lt;/p&gt;

&lt;p&gt;Install stress if needed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install stress
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;stress --cpu 4 --timeout 300
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wait for the trigger to fire.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Alerts
   |
Action log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A successful notification should show:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Status:
Sent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The email should arrive in your Gmail inbox.&lt;/p&gt;




&lt;h1&gt;
  
  
  Common Problems and Fixes
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Problem 1: Host availability is red
&lt;/h2&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Get value from agent failed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent configuration
Network connectivity
Port 10050
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Problem 2: No media defined for user
&lt;/h2&gt;

&lt;p&gt;Cause:&lt;/p&gt;

&lt;p&gt;The media type exists but is not attached to the user.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Users
 |
Admin
 |
Media
 |
Add
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Problem 3: No message defined for media type
&lt;/h2&gt;

&lt;p&gt;Cause:&lt;/p&gt;

&lt;p&gt;The media type has no message template.&lt;/p&gt;

&lt;p&gt;Fix:&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Problem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;message template.&lt;/p&gt;




&lt;h2&gt;
  
  
  Problem 4: SMTP timeout
&lt;/h2&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Failed to connect to smtp.gmail.com port 587
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cause:&lt;/p&gt;

&lt;p&gt;Network blocking SMTP port 587.&lt;/p&gt;

&lt;p&gt;Fix:&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Port:
465

Security:
SSL/TLS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Problem 5: Gmail authentication error
&lt;/h2&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;530 Authentication required
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cause:&lt;/p&gt;

&lt;p&gt;Using Gmail password instead of App Password.&lt;/p&gt;

&lt;p&gt;Fix:&lt;/p&gt;

&lt;p&gt;Create a Google App Password and use it in Zabbix.&lt;/p&gt;




&lt;p&gt;After completing these steps, Zabbix can automatically detect problems and send email notifications without requiring manual checking.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8iemy912i3kufi2h54ss.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8iemy912i3kufi2h54ss.png" alt=" " width="710" height="494"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fze4qra2ffk9yk4hz3vg5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fze4qra2ffk9yk4hz3vg5.png" alt=" " width="799" height="116"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flpy25tcr0k5qqntqcvht.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Flpy25tcr0k5qqntqcvht.png" alt=" " width="800" height="323"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fosltaf4ep3fqkhx7ittw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fosltaf4ep3fqkhx7ittw.png" alt=" " width="800" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fol98ccpy50puntgtfpka.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fol98ccpy50puntgtfpka.png" alt=" " width="800" height="254"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fb0yzcfk3rf1ftrz86ofj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fb0yzcfk3rf1ftrz86ofj.png" alt=" " width="599" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff6winiprpzvcqnx7j5fg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Ff6winiprpzvcqnx7j5fg.png" alt=" " width="800" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1qgizt0qxwwhae523urn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1qgizt0qxwwhae523urn.png" alt=" " width="620" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Monitoring Ubuntu, Windows, and RHEL Servers with Zabbix (Part 2)</title>
      <dc:creator>Morodolu Oluwafikunayomi</dc:creator>
      <pubDate>Fri, 10 Jul 2026 15:21:13 +0000</pubDate>
      <link>https://dev.to/fikalz/monitoring-ubuntu-windows-and-rhel-servers-with-zabbix-part-2-11nk</link>
      <guid>https://dev.to/fikalz/monitoring-ubuntu-windows-and-rhel-servers-with-zabbix-part-2-11nk</guid>
      <description>&lt;p&gt;In Part 1, we installed the Zabbix Server on Ubuntu 22.04, configured the MySQL database, and started the required services.&lt;/p&gt;

&lt;p&gt;At this point, the server is running, but it isn't monitoring anything yet.&lt;/p&gt;

&lt;p&gt;In this article, we'll:&lt;/p&gt;

&lt;p&gt;Complete the Zabbix web setup wizard&lt;br&gt;
Install the Zabbix Agent on Windows Server&lt;br&gt;
Install the Zabbix Agent on RHEL 10&lt;br&gt;
Add both systems to Zabbix&lt;br&gt;
Verify that data is being collected&lt;/p&gt;

&lt;p&gt;By the end of this guide, you'll have a centralized monitoring platform collecting metrics from multiple operating systems.&lt;br&gt;
Understanding Zabbix Agents&lt;/p&gt;

&lt;p&gt;The Zabbix Server collects information from monitored systems using agents.&lt;/p&gt;

&lt;p&gt;These agents gather metrics such as:&lt;/p&gt;

&lt;p&gt;CPU utilization&lt;br&gt;
Memory consumption&lt;br&gt;
Disk usage&lt;br&gt;
Network traffic&lt;br&gt;
Running services&lt;br&gt;
System uptime&lt;/p&gt;

&lt;p&gt;The collected data is then displayed on the Zabbix dashboard and can be used to generate alerts.&lt;/p&gt;

&lt;p&gt;For this lab, we'll install agents on:&lt;/p&gt;

&lt;p&gt;Windows Server&lt;br&gt;
Red Hat Enterprise Linux 10&lt;br&gt;
&lt;strong&gt;Installing the Zabbix Agent on Windows Server&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Download Zabbix Agent 2 from the official Zabbix website.&lt;/p&gt;

&lt;p&gt;After launching the installer, provide:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Server=&lt;br&gt;
Hostname=&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6kcwber7avxo0oh3fgbj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6kcwber7avxo0oh3fgbj.png" alt=" " width="800" height="259"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc5skiqh9dmdzv3e7mocx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc5skiqh9dmdzv3e7mocx.png" alt=" " width="569" height="464"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Configuring the Windows Firewall&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Zabbix Server communicates with the agent using TCP port 10050.&lt;/p&gt;

&lt;p&gt;Open PowerShell as Administrator and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;netsh advfirewall firewall add rule name="Allow TCP 10050" dir=in action=allow protocol=TCP localport=10050
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the Zabbix service is running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Get-Service "Zabbix Agent 2"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Status   Name
------   ----
Running  Zabbix Agent 2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiwzi8g1kywsnbs09tzhb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fiwzi8g1kywsnbs09tzhb.png" alt=" " width="799" height="545"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installing the Zabbix Agent on RHEL 10&lt;/strong&gt;&lt;br&gt;
Next, let's onboard our Red Hat server.&lt;/p&gt;

&lt;p&gt;Add the Zabbix repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo rpm -Uvh https://repo.zabbix.com/zabbix/7.0/rhel/10/x86_64/zabbix-release-latest-7.0.el10.noarch.rpm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fylm604622e8cwixj6p1l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fylm604622e8cwixj6p1l.png" alt=" " width="799" height="317"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Install the agent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo dnf install zabbix-agent2 -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Configuring the Agent&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Edit the configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo nano /etc/zabbix/zabbix_agent2.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update the following parameters:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Server=192.168.1.100&lt;br&gt;
ServerActive=192.168.1.100&lt;br&gt;
Hostname=RHEL10-SRV01&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feskp1dy7p76z1v64dt0q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Feskp1dy7p76z1v64dt0q.png" alt=" " width="626" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Where:&lt;/p&gt;

&lt;p&gt;Server = Zabbix Server IP&lt;br&gt;
ServerActive = Zabbix Server IP&lt;br&gt;
Hostname = Host name displayed inside Zabbix&lt;/p&gt;

&lt;p&gt;Save the file.&lt;br&gt;
&lt;strong&gt;Starting the Agent Service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Enable and start the service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl enable --now zabbix-agent2

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl status zabbix-agent2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see:&lt;/p&gt;

&lt;p&gt;active (running)&lt;br&gt;
&lt;strong&gt;Configuring the Firewall&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Allow inbound traffic on TCP port 10050:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
sudo firewall-cmd --permanent --add-port=10050/tcp
sudo firewall-cmd --reload
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the port is listening:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
ss -tlnp | grep 10050
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Adding Windows Server to Zabbix&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Navigate to:&lt;/p&gt;

&lt;p&gt;Data Collection → Hosts&lt;/p&gt;

&lt;p&gt;Click:&lt;/p&gt;

&lt;p&gt;Create Host&lt;/p&gt;

&lt;p&gt;Enter:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Host Name: &lt;br&gt;
Visible Name: Windows Server&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0yue7nzumqk0y8ti13gk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F0yue7nzumqk0y8ti13gk.png" alt=" " width="799" height="314"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add the Agent interface:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;IP Address: &lt;br&gt;
Port: 10050&lt;br&gt;
Under Templates, select:&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Windows by Zabbix agent&lt;/p&gt;

&lt;p&gt;Save the host.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhyzchie01oifmdevfmcb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhyzchie01oifmdevfmcb.png" alt=" " width="800" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5g2m2i7tgve3n733vtdt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5g2m2i7tgve3n733vtdt.png" alt=" " width="799" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Adding RHEL 10 to Zabbix&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Repeat the same process.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgdqvccjvgq1vcpfxeed0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fgdqvccjvgq1vcpfxeed0.png" alt=" " width="800" height="121"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At this stage, we now have a fully functional monitoring environment.&lt;/p&gt;

&lt;p&gt;Our Ubuntu server is running Zabbix, while both Windows Server and RHEL 10 are sending performance metrics back to a centralized dashboard.&lt;/p&gt;

&lt;p&gt;The ability to monitor different operating systems from a single platform is one of the reasons Zabbix remains a popular choice in enterprise environments.&lt;/p&gt;

&lt;p&gt;In Part 3, we'll explore triggers, dashboards, graphs, notifications, and alerting so that Zabbix can automatically notify us when something goes wrong instead of waiting for users to report issues.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Monitoring Hybrid Infrastructure with Zabbix: Ubuntu, Windows, and Red Hat</title>
      <dc:creator>Morodolu Oluwafikunayomi</dc:creator>
      <pubDate>Fri, 10 Jul 2026 10:40:14 +0000</pubDate>
      <link>https://dev.to/fikalz/monitoring-hybrid-infrastructure-with-zabbix-ubuntu-windows-and-red-hat-2mdo</link>
      <guid>https://dev.to/fikalz/monitoring-hybrid-infrastructure-with-zabbix-ubuntu-windows-and-red-hat-2mdo</guid>
      <description>&lt;p&gt;&lt;em&gt;It's been a while since I last wrote a technical article. Recently, one of my routine tasks at work involved onboarding servers into our monitoring platform, and it got me thinking: why not document the process?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This article is the first part of a three-part series where I'll walk through setting up a complete Zabbix monitoring environment from scratch. We'll install the Zabbix server, configure its database, and prepare it to monitor both Windows and Linux systems.&lt;/p&gt;

&lt;p&gt;A basic understanding of Linux commands will be helpful, but I'll explain the important steps along the way.&lt;/p&gt;

&lt;p&gt;Why Monitoring Matters&lt;/p&gt;

&lt;p&gt;As infrastructure grows, so does the challenge of keeping track of system health.&lt;/p&gt;

&lt;p&gt;Whether you're managing physical servers, virtual machines, cloud workloads, or a mixture of all three, you need visibility into what's happening behind the scenes. Without monitoring, you often discover problems only after users start complaining.&lt;/p&gt;

&lt;p&gt;This is where Zabbix comes in.&lt;/p&gt;

&lt;p&gt;What is Zabbix?&lt;/p&gt;

&lt;p&gt;Zabbix is an open-source enterprise monitoring platform that helps administrators monitor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Servers&lt;/li&gt;
&lt;li&gt;Applications&lt;/li&gt;
&lt;li&gt;Databases&lt;/li&gt;
&lt;li&gt;Network devices&lt;/li&gt;
&lt;li&gt;Virtual machines&lt;/li&gt;
&lt;li&gt;Cloud resources&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It collects performance metrics, generates alerts when thresholds are exceeded, and provides dashboards that make it easier to understand the health of your infrastructure.&lt;/p&gt;

&lt;p&gt;A typical Zabbix deployment consists of four major components:&lt;/p&gt;

&lt;p&gt;Zabbix Server – The central monitoring engine&lt;br&gt;
Database – Stores collected metrics and historical data&lt;br&gt;
Web Frontend – The web interface used for administration and reporting&lt;br&gt;
Zabbix Agent – Installed on monitored systems to collect metrics&lt;br&gt;
Lab Environment&lt;/p&gt;

&lt;p&gt;To demonstrate that Zabbix is not tied to a single operating system, I built a small lab consisting of:&lt;/p&gt;

&lt;p&gt;System  Purpose&lt;br&gt;
Ubuntu 22.04    Zabbix Server&lt;br&gt;
Windows Server  Monitored Host&lt;br&gt;
RHEL 10 Monitored Host&lt;/p&gt;

&lt;p&gt;This setup reflects what many organizations use today: a mixture of Windows and Linux servers performing different business functions.&lt;/p&gt;

&lt;p&gt;The architecture looks like this:&lt;/p&gt;

&lt;p&gt;+-------------------+&lt;br&gt;
|   Zabbix Server   |&lt;br&gt;
|   Ubuntu 22.04    |&lt;br&gt;
+---------+---------+&lt;br&gt;
          |&lt;/p&gt;



&lt;p&gt;|               |&lt;br&gt;
   |               |&lt;br&gt;
+------+      +---------+&lt;br&gt;
| RHEL |      | Windows |&lt;br&gt;
|  10  |      | Server  |&lt;br&gt;
+------+      +---------+&lt;/p&gt;

&lt;p&gt;The Zabbix server will collect performance data from both systems and display it through a centralized dashboard.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Installing the Zabbix Server on Ubuntu 22.04&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The first step is to add the official Zabbix repository.&lt;/p&gt;

&lt;p&gt;Download the repository package from the Zabbix website and install it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;dpkg &lt;span class="nt"&gt;-i&lt;/span&gt; zabbix-release_latest_7.0+ubuntu22.04_all.deb
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frr9amq38c5y9wucr06q3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Frr9amq38c5y9wucr06q3.png" alt=" " width="800" height="29"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmybjvrc8wd6vrh6les7y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmybjvrc8wd6vrh6les7y.png" alt=" " width="800" height="35"&gt;&lt;/a&gt;&lt;br&gt;
Once the repository has been added, install the required Zabbix packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;zabbix-server-mysql &lt;span class="se"&gt;\&lt;/span&gt;
zabbix-frontend-php &lt;span class="se"&gt;\&lt;/span&gt;
zabbix-apache-conf &lt;span class="se"&gt;\&lt;/span&gt;
zabbix-sql-scripts &lt;span class="se"&gt;\&lt;/span&gt;
zabbix-agent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbpsrvof0ijcvym2ur1ko.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fbpsrvof0ijcvym2ur1ko.png" alt=" " width="799" height="273"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;These packages provide:&lt;br&gt;
*&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Zabbix Server&lt;/li&gt;
&lt;li&gt;PHP frontend components&lt;/li&gt;
&lt;li&gt;Apache configuration&lt;/li&gt;
&lt;li&gt;Database schema files&lt;/li&gt;
&lt;li&gt;A local Zabbix agent&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;At this stage, the software is installed but Zabbix still needs a database to store monitoring information.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Configuring MySQL for Zabbix&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Zabbix stores all collected metrics inside a database. Without one, the server cannot start.&lt;/p&gt;

&lt;p&gt;For this lab, I used MySQL.&lt;/p&gt;

&lt;p&gt;Access the MySQL shell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;mysql
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a dedicated database and user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;DATABASE&lt;/span&gt; &lt;span class="n"&gt;zabbix&lt;/span&gt; &lt;span class="nb"&gt;CHARACTER&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;utf8mb4&lt;/span&gt; &lt;span class="k"&gt;COLLATE&lt;/span&gt; &lt;span class="n"&gt;utf8mb4_bin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;USER&lt;/span&gt; &lt;span class="s1"&gt;'zabbix'&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;'localhost'&lt;/span&gt; &lt;span class="n"&gt;IDENTIFIED&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="s1"&gt;'StrongPassword'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;GRANT&lt;/span&gt; &lt;span class="k"&gt;ALL&lt;/span&gt; &lt;span class="k"&gt;PRIVILEGES&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;zabbix&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="s1"&gt;'zabbix'&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;'localhost'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="n"&gt;FLUSH&lt;/span&gt; &lt;span class="k"&gt;PRIVILEGES&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, import the Zabbix database schema:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;zcat /usr/share/zabbix-sql-scripts/mysql/server.sql.gz | mysql &lt;span class="nt"&gt;-uzabbix&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; zabbix
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F46kvnx434zij1gc71g34.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F46kvnx434zij1gc71g34.png" alt=" " width="734" height="531"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;i am  receiving a message indicating that the database already exists, that's expected as I previously configured Zabbix on the system.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr0i9mt3ys1k10ll8ilu4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fr0i9mt3ys1k10ll8ilu4.png" alt=" " width="800" height="24"&gt;&lt;/a&gt;&lt;br&gt;
This command creates the tables that Zabbix requires to store monitoring data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Connecting Zabbix to MySQL&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now we need to tell the Zabbix server how to connect to the database.&lt;/p&gt;

&lt;p&gt;Open the Zabbix server configuration file:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Locate and modify the following parameters:&lt;/p&gt;

&lt;h1&gt;
  
  
  DBName
&lt;/h1&gt;

&lt;h1&gt;
  
  
  DBUser
&lt;/h1&gt;

&lt;h1&gt;
  
  
  DBPassword
&lt;/h1&gt;

&lt;p&gt;and uncomment them and modify to &lt;br&gt;
DBName=zabbix&lt;br&gt;
DBUser=zabbix&lt;br&gt;
DBPassword=StrongPassword&lt;br&gt;
or type them at the top of the config file&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx0ng9evbq50fux6xgnc2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx0ng9evbq50fux6xgnc2.png" alt=" " width="689" height="492"&gt;&lt;/a&gt;&lt;br&gt;
Save the file and exit.&lt;br&gt;
Starting the Services&lt;/p&gt;

&lt;p&gt;Once the database configuration is complete, restart the required services:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart zabbix-server zabbix-agent apache2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enable them to start automatically after reboot:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;zabbix-server zabbix-agent apache2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we installed the Zabbix Server on Ubuntu 22.04, configured the MySQL database, and started the required services.&lt;br&gt;
At this point, the server is running, but it isn't monitoring anything yet.&lt;/p&gt;

&lt;p&gt;we'll:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Complete the Zabbix web setup wizard&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Accessing the Zabbix Web Interface&lt;/p&gt;

&lt;p&gt;Open a browser and navigate to:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;http:///zabbix&lt;br&gt;
your zabbix-server-ip is the ip of the os which can be gotten with&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

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

&lt;/div&gt;



&lt;p&gt;You should be greeted with the Zabbix setup wizard.&lt;/p&gt;

&lt;p&gt;Click Next Step.&lt;br&gt;
Configuring the Database Connection&lt;/p&gt;

&lt;p&gt;Enter the database information created during the server installation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Database type: MySQL&lt;br&gt;
Database host: localhost&lt;br&gt;
Database name: zabbix&lt;br&gt;
User: zabbix&lt;br&gt;
Password: StrongPassword&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Configuring Zabbix Server Details&lt;/p&gt;

&lt;p&gt;Specify:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Host: localhost&lt;br&gt;
Port: 10051&lt;br&gt;
Name: Zabbix Monitoring Server&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The name field is optional, but it helps identify your monitoring environment.&lt;/p&gt;

&lt;p&gt;Click Next Step.&lt;/p&gt;

&lt;p&gt;Completing the Installation&lt;/p&gt;

&lt;p&gt;Review the summary page and click Finish.&lt;/p&gt;

&lt;p&gt;You should now see the Zabbix login page.&lt;/p&gt;

&lt;p&gt;Default credentials:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Username: Admin&lt;br&gt;
Password: zabbix&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For security reasons, change the default password immediately after your first login.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>systems</category>
      <category>learning</category>
      <category>tooling</category>
    </item>
    <item>
      <title>The Fastest Way to Deploy Any Website Template on CentOS (After SSH)</title>
      <dc:creator>Morodolu Oluwafikunayomi</dc:creator>
      <pubDate>Wed, 12 Nov 2025 08:53:21 +0000</pubDate>
      <link>https://dev.to/fikalz/the-fastest-way-to-deploy-any-website-template-on-centos-after-ssh-1jdn</link>
      <guid>https://dev.to/fikalz/the-fastest-way-to-deploy-any-website-template-on-centos-after-ssh-1jdn</guid>
      <description>&lt;p&gt;This is part 2 to my previous post, you know that feeling when you finally SSH into your VirtualBox or Vagrant box, and now you have to set up a whole website manually?&lt;br&gt;
Install this, unzip that, copy files, restart Apache, fix permissions… rinse and repeat.&lt;br&gt;
Yeah, we’re not doing that today.&lt;br&gt;
Instead, I’ll show you how to automate the entire process&lt;/p&gt;

&lt;p&gt;What You’ll Need&lt;/p&gt;

&lt;p&gt;Before we dive in, make sure you’ve got the basics ready:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You’ve already SSH’d into your CentOS box, for example:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; vagrant ssh

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;p&gt;You’re inside your working directory (I’ll use /home/vagrant/server for this tutorial).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Apache is installed and running. If not, quickly do:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo yum install httpd -y
 sudo systemctl enable httpd
sudo systemctl start httpd

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;That’s it let’s automate the rest.&lt;br&gt;
&lt;strong&gt;Step 1: Create the Script&lt;/strong&gt;&lt;br&gt;
Once you’re inside your SSH terminal, move into your server folder and create a script file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd ~/server
touch scripting.sh
chmod +x scripting.sh
vi scripting.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;If vi doesn’t work, you can use nano or even cat &amp;gt; scripting.sh.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: The Automation Script&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/bash

echo "Installing wget and unzip..."
sudo yum install wget unzip -y

# Ask the user for a template URL
read -p "Enter the URL of your website template (.zip): " TEMPLATE_URL

echo "Downloading your template..."
wget $TEMPLATE_URL -O website_template.zip

echo "Extracting website files..."
unzip -o website_template.zip -d ~/server/

# Automatically detect extracted folder
EXTRACTED_DIR=$(find ~/server -maxdepth 1 -type d -name "templatemo*" -o -name "html*" | head -n 1)

if [ -z "$EXTRACTED_DIR" ]; then
  echo "❌ Could not find extracted folder. Please check manually."
  exit 1
fi

echo "Deploying files to /var/www/html..."
sudo cp -r $EXTRACTED_DIR/* /var/www/html/

echo "Restarting Apache..."
sudo systemctl restart httpd
sudo systemctl enable httpd

IP=$(hostname -I | awk '{print $1}')
echo "✅ Done! Visit your site at: http://$IP/"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save and exit (in vi, that’s ESC + :wq).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Run It&lt;/strong&gt;&lt;br&gt;
Now run your shiny new automation script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./scripting.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It’ll ask you for a template URL — just paste in one of these:&lt;/p&gt;

&lt;p&gt;Example Template URLs&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Templatemo 3D Coverflow&lt;/li&gt;
&lt;li&gt;BootstrapMade Arsha Template&lt;/li&gt;
&lt;li&gt;HTML5UP Phantom Template&lt;/li&gt;
&lt;li&gt;Or grab any .zip link from your favorite site:&lt;/li&gt;
&lt;li&gt;&lt;a href="https://templatemo.com" rel="noopener noreferrer"&gt;https://templatemo.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bootstrapmade.com" rel="noopener noreferrer"&gt;https://bootstrapmade.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://html5up.net" rel="noopener noreferrer"&gt;https://html5up.net&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Once the script runs, it’ll:&lt;/li&gt;
&lt;li&gt;Install missing tools&lt;/li&gt;
&lt;li&gt;Download your zip file&lt;/li&gt;
&lt;li&gt;Unzip it into your server folder&lt;/li&gt;
&lt;li&gt;Copy everything into /var/www/html/&lt;/li&gt;
&lt;li&gt;Restart Apache&lt;/li&gt;
&lt;li&gt;And show your local IP&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short — it does all the boring stuff for you.&lt;/p&gt;

&lt;p&gt;After it finishes, you’ll see something like this:&lt;br&gt;
 Done! Visit your site at: &lt;a href="http://192.168.33.10/" rel="noopener noreferrer"&gt;http://192.168.33.10/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>devops</category>
      <category>learning</category>
      <category>beginners</category>
    </item>
    <item>
      <title>From ThemeWagon to Live Site: Hosting a Free HTML Template on Your Local Apache Server Using Vagrant + Git Bash</title>
      <dc:creator>Morodolu Oluwafikunayomi</dc:creator>
      <pubDate>Tue, 04 Nov 2025 15:16:37 +0000</pubDate>
      <link>https://dev.to/fikalz/from-themewagon-to-live-site-hosting-a-free-html-template-on-your-local-apache-server-using-272i</link>
      <guid>https://dev.to/fikalz/from-themewagon-to-live-site-hosting-a-free-html-template-on-your-local-apache-server-using-272i</guid>
      <description>&lt;p&gt;Ever downloaded a beautiful free template from ThemeWagon&lt;br&gt;
 and thought,&lt;br&gt;
“Okay... now how do I actually host this like a real website?”&lt;/p&gt;

&lt;p&gt;That’s where this guide comes in.&lt;/p&gt;

&lt;p&gt;In this post, I’ll walk you through hosting a free HTML template on your own local Apache server, running inside a Vagrant virtual machine — all from your Git Bash terminal.&lt;/p&gt;

&lt;p&gt;What You’ll Need&lt;/p&gt;

&lt;p&gt;Before we start, make sure you’ve got these installed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🧱 VirtualBox(for running the VM)&lt;/li&gt;
&lt;li&gt;📦 Vagrant&lt;/li&gt;
&lt;li&gt;💻 Git Bash(Windows users)&lt;/li&gt;
&lt;li&gt;🧾 Any HTML template (download from ThemeWagon)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No coding required &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1 — Create a Project Folder and Initialize Vagrant&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open Git Bash and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pwd(this is to know what directory you are on)
cd "directory, either downloads or documents or desktop"
mkdir ~/myserver
cd ~/myserver
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now initialize your Ubuntu box:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vagrant init ubuntu/jammy64
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but if you wish for any other OS check out:&lt;br&gt;
&lt;a href="https://portal.cloud.hashicorp.com/vagrant/discover" rel="noopener noreferrer"&gt;https://portal.cloud.hashicorp.com/vagrant/discover&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This creates a Vagrantfile in your folder. It’s basically your VM’s configuration file — where you’ll define memory, CPU, and network settings.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2 — Edit Your Vagrantfile Using Vim&lt;/strong&gt;&lt;br&gt;
Inside Git Bash, while you are in the same directory open the Vagrantfile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vim Vagrantfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;This will open the file in Vim editor.&lt;br&gt;
Press i to enter insert mode now you can start typing or editing.&lt;/em&gt;&lt;br&gt;
thereafter to Enable Private or Public Network Access, Scroll down to find these lines:&lt;/p&gt;

&lt;blockquote&gt;
&lt;h1&gt;
  
  
  config.vm.network "private_network", ip: "192.168.33.10"
&lt;/h1&gt;
&lt;h1&gt;
  
  
  config.vm.network "public_network"
&lt;/h1&gt;

&lt;p&gt;Uncomment one of them depending on what you want:&lt;br&gt;
Use private network if you just want to access your site locally:&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;config.vm.network "private_network", ip: "192.168.33.10"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;do note kindly keep the ip address here somewhere or be written down as it is useful later on, you can also change the numbers maybe like 192.168.40.15&lt;/em&gt;&lt;br&gt;
Or use forwarded port (recommended for beginners):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;config.vm.network "forwarded_port", guest: 80, host: 8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;This means anything on port 80 (inside the VM) will be visible on your local machine at &lt;a href="http://localhost:8080" rel="noopener noreferrer"&gt;http://localhost:8080&lt;/a&gt;.&lt;/em&gt;&lt;br&gt;
lastly to Allocate More RAM and CPUs&lt;br&gt;
Find and uncomment this section:&lt;/p&gt;

&lt;blockquote&gt;
&lt;h1&gt;
  
  
  config.vm.provider "virtualbox" do |vb|
&lt;/h1&gt;
&lt;h1&gt;
  
  
  vb.memory = "1024"
&lt;/h1&gt;
&lt;h1&gt;
  
  
  end
&lt;/h1&gt;

&lt;p&gt;Now edit it to give your VM more resources:&lt;br&gt;
&lt;/p&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;config.vm.provider "virtualbox" do |vb|
  vb.memory = "2048"     # 2GB RAM
  vb.cpus = 2            # 2 CPU cores
end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;unless you want graphical user interface i don't recommend uncomment the &lt;br&gt;
GUI line of syntax, and any line with double # is an actual comment.&lt;/p&gt;

&lt;p&gt;Once done, press:&lt;br&gt;
Esc&lt;br&gt;
Type &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;:wq&lt;br&gt;
Hit Enter&lt;br&gt;
That saves and exits Vim.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Step 3 — Boot Up the Virtual Machine&lt;/strong&gt;&lt;br&gt;
Now it’s time to start your virtual server:&lt;br&gt;
type in&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vagrant up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vagrant will download the Ubuntu image, set up the VM, and start it automatically.&lt;br&gt;
The first run takes a few minutes — but once complete, you’ll see your box running.&lt;br&gt;
Then, log in to it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vagrant ssh

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’re now inside your Ubuntu server as the vagrant user&lt;br&gt;
to test you can type in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;whoami
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;this should return vagrant&lt;br&gt;
&lt;strong&gt;Step 4 — Install Apache Web Server&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;while having different types os linux OS it is important to know the name of the apache server and which ubuntu supports it&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
sudo apt update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install Apache:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install apache2 -y
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start and enable it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl start apache2
sudo systemctl enable apache2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test it!&lt;br&gt;
On your browser, go to the ip address you  have in the private ip address in the vagrant file.&lt;br&gt;
You should see “Apache2 Ubuntu Default Page”.&lt;br&gt;
Congrats — your web server works&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5 — Upload and Unzip Your ThemeWagon Template&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Inside your server, make a folder to hold your website:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir ~/server
cd ~/server
Now using wget (the themewagon download link)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;_the way i usually get is by going to themewagon, inspecting the page, going to network and clicking on the template download buttonwe should see the template name, it should be :http://..... _&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkrrrtvuv7r7b6ct49o4z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkrrrtvuv7r7b6ct49o4z.png" alt=" " width="800" height="365"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;so by doing the same you should arrive where i am, copy the link&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Then unzip it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;unzip (the foldername)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;incase you have an error code about unzip not been part of the OS  package use&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt install unzip -y
unzip foldername
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 6 — Move Files to Apache’s Web Root&lt;/strong&gt;&lt;br&gt;
Copy everything from your extracted folder into Apache’s serving directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo cp -r ~/server/neural_glass/templatemo_597_neural_glass/* /var/www/html/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart Apache so changes apply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl restart apache2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 7 — Visit Your Website!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now, open your browser and head to:&lt;br&gt;
your private ip address&lt;br&gt;
incase your forgotten your ip address:&lt;br&gt;
Check your server’s IP:&lt;/p&gt;

&lt;p&gt;If you used a private network instead of port forwarding:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ip addr show
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for something like:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;inet 192.168.33.10/24&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reboot or Halt Your Server&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To stop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vagrant halt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To start again:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vagrant up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To destroy and rebuild (when experimenting):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
vagrant destroy -f &amp;amp;&amp;amp; vagrant up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If this guide helped you, drop a ❤️ on DEV.to and comment how your first hosted template went or what how i can improve on deploying faster &lt;/p&gt;

</description>
      <category>webdev</category>
      <category>devops</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Spin Up, Explore, and Destroy: A Complete Beginner’s Guide to Using Vagrant with Ubuntu (Visual Walkthrough)</title>
      <dc:creator>Morodolu Oluwafikunayomi</dc:creator>
      <pubDate>Sat, 11 Oct 2025 15:27:46 +0000</pubDate>
      <link>https://dev.to/fikalz/spin-up-explore-and-destroy-a-complete-beginners-guide-to-using-vagrant-with-ubuntu-visual-37k7</link>
      <guid>https://dev.to/fikalz/spin-up-explore-and-destroy-a-complete-beginners-guide-to-using-vagrant-with-ubuntu-visual-37k7</guid>
      <description>&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;br&gt;
Before we begin, make sure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vagrant installed → Download here&lt;/li&gt;
&lt;li&gt;VirtualBox (or any supported provider)&lt;/li&gt;
&lt;li&gt;A terminal or command prompt&lt;/li&gt;
&lt;li&gt;Basic command-line familiarity
That’s it! Let’s get started.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Create a New Vagrant Project&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;First, create a folder for your new virtual machine setup and initialize it with the Ubuntu box:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir vagrant-ubuntu
cd vagrant-ubuntu
vagrant init ubuntu/jammy64
vi vagrant #this is to edit the file, 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;once you opened the file make sure to uncomment the private network line which contains the public address of the os and the public address line&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F52aoccfw5mq78ukdc1fx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F52aoccfw5mq78ukdc1fx.png" alt=" " width="800" height="513"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This creates a file called Vagrantfile — the heart of your configuration&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Furxvxaxv4d9dxzzm5f23.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Furxvxaxv4d9dxzzm5f23.png" alt=" " width="800" height="433"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Configure the Vagrantfile&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open the Vagrantfile with your favorite editor and tweak the settings.&lt;br&gt;
You can adjust CPU, memory, and network configurations easily.&lt;/p&gt;

&lt;p&gt;Example configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/jammy64"

  # Optional: forward host port 8080 to guest port 80
  # config.vm.network "forwarded_port", guest: 80, host: 8080

  # Provider-specific settings
  config.vm.provider "virtualbox" do |vb|
    vb.memory = "2048"
    vb.cpus = 2
  end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd72uwttpdmtmbo7d21pe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd72uwttpdmtmbo7d21pe.png" alt=" " width="800" height="538"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Start the Virtual Machine&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once your configuration is ready, start the VM using:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;vagrant up&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This command downloads the Ubuntu box (if it’s your first time) and boots it up.&lt;br&gt;
You’ll see messages as Vagrant connects to VirtualBox and starts provisioning the machine.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5d5rs20toeep2etbbjdy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5d5rs20toeep2etbbjdy.png" alt=" " width="800" height="513"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Connect to Your Virtual Machine&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Once it’s running, you can log into your Ubuntu VM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vagrant ssh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2xjucdqf8qm83lmdn0ak.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2xjucdqf8qm83lmdn0ak.png" alt=" " width="800" height="681"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If everything went well, you’ll see the Ubuntu welcome message, along with system stats and login info.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Run Basic Commands Inside the VM&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now that you’re inside, you can explore and test basic commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;whoami           # should print 'vagrant'
mkdir testfile
touch textfile.txt
ls
rm textfile.txt
rmdir testfile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also install packages, configure software, or run a web app — it’s your sandboxed Linux environment!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fce22oprrlajlaxbf8zug.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fce22oprrlajlaxbf8zug.png" alt=" " width="684" height="487"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6: Stop and Destroy the VM&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you’re done experimenting, you can safely shut down or completely remove the VM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vagrant halt       # stops the virtual machine
vagrant destroy    # permanently deletes the VM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This frees up your system resources and ensures a clean slate for next time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuu874mbjiv0f1xmeozqj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuu874mbjiv0f1xmeozqj.png" alt=" " width="800" height="760"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This workflow is especially powerful for testing backend apps, DevOps scripts, or server configurations safely. Once you’re comfortable, try automating it with provisioning tools like Ansible or deploying pre-configured images.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>linux</category>
      <category>learning</category>
      <category>devops</category>
      <category>devex</category>
    </item>
    <item>
      <title>AWS Networking Fundamentals: Building a Secure Cloud Architecture</title>
      <dc:creator>Morodolu Oluwafikunayomi</dc:creator>
      <pubDate>Sun, 31 Aug 2025 18:23:59 +0000</pubDate>
      <link>https://dev.to/fikalz/aws-networking-fundamentals-building-a-secure-cloud-architecture-50jc</link>
      <guid>https://dev.to/fikalz/aws-networking-fundamentals-building-a-secure-cloud-architecture-50jc</guid>
      <description>&lt;h1&gt;
  
  
  AWS Networking Explained Like Building a Neighborhood 🏡
&lt;/h1&gt;

&lt;p&gt;If you’re new to AWS networking, it can feel like alphabet soup: &lt;strong&gt;VPCs, Subnets, IGWs, NATs, Route Tables, SGs, NACLs&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;But here’s the good news: it’s easier to understand if you think of it like &lt;strong&gt;building a secure neighborhood&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;By the end of this post, you’ll:&lt;br&gt;&lt;br&gt;
  Understand AWS networking through real-world analogies&lt;br&gt;&lt;br&gt;
  Know the difference between gateways, firewalls, and route tables&lt;br&gt;&lt;br&gt;
  Build your own &lt;strong&gt;secure cloud community&lt;/strong&gt; step by step  &lt;/p&gt;


&lt;h2&gt;
  
  
  1. VPC → Your Gated Community
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;VPC (Virtual Private Cloud)&lt;/strong&gt; is your private section of AWS.  &lt;/p&gt;

&lt;p&gt;Imagine buying land inside a gated estate. You decide how big it is, where the streets go, and who’s allowed in.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Isolated from other customers.
&lt;/li&gt;
&lt;li&gt;You choose the boundaries (IP ranges).
&lt;/li&gt;
&lt;li&gt;You control traffic in and out.
&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  2. Subnets → Streets in Your Community
&lt;/h2&gt;

&lt;p&gt;Inside your VPC, you divide land into &lt;strong&gt;subnets&lt;/strong&gt; (streets).  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Public Subnet&lt;/strong&gt; → open for visitors (shops, restaurants, web servers).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Private Subnet&lt;/strong&gt; → hidden residential area (databases, backend).
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Pro tip: Always spread them across different availability zones so your app stays online even if one zone fails.  &lt;/p&gt;

&lt;p&gt;![Insert subnet diagram here]&lt;/p&gt;


&lt;h2&gt;
  
  
  3. Internet Gateway → The Main Gate
&lt;/h2&gt;

&lt;p&gt;The &lt;strong&gt;Internet Gateway (IGW)&lt;/strong&gt; is the guarded entrance/exit of your estate.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lets outsiders visit your public servers.
&lt;/li&gt;
&lt;li&gt;Lets your public servers reach the internet.
&lt;/li&gt;
&lt;li&gt;Scales automatically (AWS manages it).
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fper5ws2rqswietzsm6jh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fper5ws2rqswietzsm6jh.png" alt=" " width="246" height="205"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  4. NAT Gateway → The Secure Mail Slot
&lt;/h2&gt;

&lt;p&gt;Private residents (databases, backend servers) need the internet too—like downloading security updates. But you don’t want strangers knocking on their doors.  &lt;/p&gt;

&lt;p&gt;That’s what the &lt;strong&gt;NAT Gateway&lt;/strong&gt; is for:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It allows private instances to send requests out.
&lt;/li&gt;
&lt;li&gt;Outsiders can’t start conversations with them.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Analogy: a one-way mail slot.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fleupl3hyz71jvz67ehdd.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fleupl3hyz71jvz67ehdd.gif" alt=" " width="800" height="691"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  5. Route Tables → The Traffic GPS
&lt;/h2&gt;

&lt;p&gt;How does data know where to go?  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Public Subnet → IGW&lt;/strong&gt; (for internet access).
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Private Subnet → NAT Gateway&lt;/strong&gt; (outbound only).
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of it like street signs and GPS guiding cars to the right road.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzjtk31m9i5q2dkbymmg9.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzjtk31m9i5q2dkbymmg9.jpg" alt=" " width="225" height="225"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  6. Elastic IP →  think of it as your  Fixed house Address
&lt;/h2&gt;

&lt;p&gt;An &lt;strong&gt;Elastic IP (EIP)&lt;/strong&gt; is a permanent public address.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Doesn’t change if you restart your server.
&lt;/li&gt;
&lt;li&gt;Useful for NAT Gateways and critical servers.
&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  7. Security Groups → Your Bodyguards
&lt;/h2&gt;

&lt;p&gt;Every house/server gets its own &lt;strong&gt;bodyguard (SG)&lt;/strong&gt;.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Deny everything by default.
&lt;/li&gt;
&lt;li&gt;Example: “Allow web visitors (port 80, 443) but only let me in via SSH.”
&lt;/li&gt;
&lt;li&gt;Stateful: Replies are automatically allowed.
&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  🚔 8. Network ACLs → The Street Patrol
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;NACL&lt;/strong&gt; is the patrol car for the whole street.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Controls traffic before it reaches houses.
&lt;/li&gt;
&lt;li&gt;Stateless: you must define both inbound &amp;amp; outbound rules.
&lt;/li&gt;
&lt;li&gt;Can allow &lt;em&gt;and&lt;/em&gt; deny traffic (SGs can only allow).
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1tnvcywuglfk8x0y4mme.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1tnvcywuglfk8x0y4mme.png" alt=" " width="306" height="165"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flx4h3bg1nbzbqkslhlte.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flx4h3bg1nbzbqkslhlte.png" alt=" " width="800" height="660"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Putting It All Together
&lt;/h2&gt;

&lt;p&gt;So when you launch a simple website with a database:  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;VPC = your gated community.
&lt;/li&gt;
&lt;li&gt;Subnets = public (web server) + private (database).
&lt;/li&gt;
&lt;li&gt;IGW = main entrance gate.
&lt;/li&gt;
&lt;li&gt;NAT Gateway = one-way mail slot.
&lt;/li&gt;
&lt;li&gt;Route Tables = GPS for data traffic.
&lt;/li&gt;
&lt;li&gt;Elastic IP = permanent address.
&lt;/li&gt;
&lt;li&gt;Security Groups = bodyguards at each house.
&lt;/li&gt;
&lt;li&gt;NACLs = patrol cars on each street.
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Result: Visitors can access your web server.&lt;br&gt;&lt;br&gt;
The web server talks to the database.&lt;br&gt;&lt;br&gt;
The database can fetch updates from the internet—but no hacker can reach it directly.  &lt;/p&gt;


&lt;h1&gt;
  
  
  Hands-On Lab: Build Your Own AWS Neighborhood
&lt;/h1&gt;

&lt;p&gt;Now that you’ve got the concepts, let’s &lt;strong&gt;build it step by step&lt;/strong&gt;.&lt;/p&gt;


&lt;h3&gt;
  
  
  🔹 Phase 1: Foundation – Setting Up Your Land
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create a VPC (Your Gated Community)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Go to: &lt;strong&gt;AWS Console → VPC → Your VPCs → Create VPC&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Name: &lt;code&gt;My-Secure-VPC&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;IPv4 CIDR: &lt;code&gt;10.0.0.0/16&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0snykanwqpmdzxan8yru.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0snykanwqpmdzxan8yru.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdz1w2gwy9662le639l64.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdz1w2gwy9662le639l64.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create Subnets (Your Streets)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Public Subnet: &lt;code&gt;public-subnet-1&lt;/code&gt; → &lt;code&gt;10.0.1.0/24&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Private Subnet: &lt;code&gt;private-subnet-1&lt;/code&gt; → &lt;code&gt;10.0.2.0/24&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj5n229xldvoz6punho7n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj5n229xldvoz6punho7n.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl81kchwq07anqpk2lhyl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl81kchwq07anqpk2lhyl.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create an Internet Gateway (Main Gate)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Name: &lt;code&gt;My-IGW&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Attach to &lt;code&gt;My-Secure-VPC&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhn783hv88r76snbmbjne.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhn783hv88r76snbmbjne.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8dxgh31o27lbhththyp8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8dxgh31o27lbhththyp8.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  Phase 2: Routing &amp;amp; Security
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Public Route Table (Signs for Public Street)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Destination: &lt;code&gt;0.0.0.0/0&lt;/code&gt; → Target: &lt;code&gt;Internet Gateway&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Associate with: &lt;code&gt;public-subnet-1&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa6abjhp5so9u5vmg3t39.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa6abjhp5so9u5vmg3t39.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9jexbz73e7hiqny6dcab.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9jexbz73e7hiqny6dcab.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgakyefd3tj9d7ssfrl76.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgakyefd3tj9d7ssfrl76.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Security Group (Web Server’s Bodyguard)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Inbound rules:

&lt;ul&gt;
&lt;li&gt;HTTP (80) → Anywhere
&lt;/li&gt;
&lt;li&gt;HTTPS (443) → Anywhere
&lt;/li&gt;
&lt;li&gt;SSH (22) → My IP only
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6q04hxnbc22nalnrh7o9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6q04hxnbc22nalnrh7o9.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3cjc0r9uhct45pyi6loe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3cjc0r9uhct45pyi6loe.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fagbrv1p0spi2xr12gfwx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fagbrv1p0spi2xr12gfwx.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1ep35vspzbxqilh1bnhx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1ep35vspzbxqilh1bnhx.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5588n3zjz6ocxgkopczz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5588n3zjz6ocxgkopczz.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  🔹 Phase 3: NAT Gateway – Secure Mail Slot
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Allocate an Elastic IP&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F89bkmeh1788hphocll3h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F89bkmeh1788hphocll3h.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F86sefwuqdcs827epbm4f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F86sefwuqdcs827epbm4f.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create NAT Gateway&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Name: &lt;code&gt;My-NAT-Gateway&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Subnet: &lt;code&gt;public-subnet-1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Elastic IP: (select the one created)
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frjn342fn2n2vxem78mb1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frjn342fn2n2vxem78mb1.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvmstdev93mh3knhfhjlr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvmstdev93mh3knhfhjlr.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7g1140ty8risquycpuhp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7g1140ty8risquycpuhp.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Remember to create a route table for private route table&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fne0ggefguged1nid9hd9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fne0ggefguged1nid9hd9.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F91rimhdvpypzchoibk4o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F91rimhdvpypzchoibk4o.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
it the same process we used for public route table&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Private Route Table (Signs for Private Street)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Destination: &lt;code&gt;0.0.0.0/0&lt;/code&gt; → Target: &lt;code&gt;My-NAT-Gateway&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Associate with: &lt;code&gt;private-subnet-1&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6mu6y1rfjooxw156becm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6mu6y1rfjooxw156becm.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h3&gt;
  
  
  🔹 Phase 4: Deploy Your Residents
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Launch Web Server (Public Street)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Name: &lt;code&gt;Web-Server&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Type: &lt;code&gt;t2.micro&lt;/code&gt; (Free Tier)
&lt;/li&gt;
&lt;li&gt;Subnet: &lt;code&gt;public-subnet-1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Public IP: ✅ Enabled
&lt;/li&gt;
&lt;li&gt;Security Group: &lt;code&gt;Web-Server-SG&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;User Data (auto install web server):
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2qqcwx2hcp2se9sae71e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2qqcwx2hcp2se9sae71e.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm6u2coqhbep7984m19cd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm6u2coqhbep7984m19cd.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1sp38ph1psr4rpf4cmza.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1sp38ph1psr4rpf4cmza.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; ```bash
 #!/bin/bash
 sudo dnf update -y
 sudo dnf install -y httpd
 sudo systemctl start httpd
 sudo systemctl enable httpd
 echo "&amp;lt;h1&amp;gt;Hello World from my $(hostname -f)&amp;lt;/h1&amp;gt;" &amp;gt; /var/www/html/index.html
 ```
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Launch Database Server (Private Street)&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Name: &lt;code&gt;DB-Server&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Type: &lt;code&gt;t2.micro&lt;/code&gt; (Free Tier)
&lt;/li&gt;
&lt;li&gt;Subnet: &lt;code&gt;private-subnet-1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Public IP: ❌ Disabled
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Phase 5: Validation – Test Your Community
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Test Web Server&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open Web Server’s public IP in a browser → should show “Hello World”.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Test Private Database Internet Access&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SSH into Web Server → then into DB Server (using private IP).
&lt;/li&gt;
&lt;li&gt;Run:
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  curl https://checkip.amazonaws.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Output should be the NAT Gateway’s Elastic IP → proving secure outbound-only internet.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp3wvemfgv6wlqv46g4sf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp3wvemfgv6wlqv46g4sf.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Result
&lt;/h2&gt;

&lt;p&gt;Web Server: Accessible publicly.&lt;br&gt;&lt;br&gt;
 Database: Hidden in private subnet, still can update.&lt;br&gt;&lt;br&gt;
 Architecture: Secure, scalable, cloud-ready.  &lt;/p&gt;

&lt;p&gt;You’ve officially built a &lt;strong&gt;secure neighborhood in the cloud&lt;/strong&gt; 🏡🌐  &lt;/p&gt;




</description>
      <category>aws</category>
      <category>beginners</category>
      <category>devops</category>
      <category>security</category>
    </item>
    <item>
      <title>Building a Django Booking Management App with a Theme Wagon Template</title>
      <dc:creator>Morodolu Oluwafikunayomi</dc:creator>
      <pubDate>Mon, 11 Aug 2025 16:00:29 +0000</pubDate>
      <link>https://dev.to/fikalz/building-a-django-booking-management-app-with-a-theme-wagon-template-mk</link>
      <guid>https://dev.to/fikalz/building-a-django-booking-management-app-with-a-theme-wagon-template-mk</guid>
      <description>&lt;p&gt;I recently built a &lt;strong&gt;booking management system&lt;/strong&gt; using Django for the backend and &lt;strong&gt;two different dashboard templates&lt;/strong&gt; for the frontend:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Kopee Dashboard&lt;/strong&gt; → Used for the booking form page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Venus Dashboard&lt;/strong&gt; → Used as inspiration for the table page that displays booking records.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This project allows users to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Submit bookings with &lt;strong&gt;Name, Email, Date, Time, Person&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Store bookings in a &lt;strong&gt;Django database&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;View, edit, and delete bookings from a clean dashboard table&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;custom HTML/CSS dashboards&lt;/strong&gt; to save frontend development time&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Purpose of the Project&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The goal was to create a professional booking management system that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lets users submit booking details easily&lt;/li&gt;
&lt;li&gt;Stores all bookings in a structured database model&lt;/li&gt;
&lt;li&gt;Displays them in a &lt;strong&gt;styled and organized table&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Uses existing dashboard themes to make the UI look polished without starting from scratch&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Frontend Templates&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Kopee Dashboard&lt;/strong&gt; (Booking Form Page)
&lt;/h3&gt;

&lt;p&gt;The booking form in my project comes directly from the &lt;strong&gt;Kopee Dashboard&lt;/strong&gt; template. I customized it slightly to match the project’s colors and form structure.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. &lt;strong&gt;Venus Dashboard Inspiration&lt;/strong&gt; (Table View Page)
&lt;/h3&gt;

&lt;p&gt;For the table that lists all bookings, I took &lt;strong&gt;inspiration&lt;/strong&gt; from the &lt;strong&gt;Venus Dashboard&lt;/strong&gt; by ThemeWagon. I kept only the &lt;strong&gt;sidebar and table layout&lt;/strong&gt;, removed other widgets, and gave the table space, borders, and a readable font.&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Project Structure&lt;/strong&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;booking_project/
│── booking_app/
│   ├── templates/
│   │   ├── index.html        # Kopee-based booking form
│   │   ├── showdb.html       # Venus-inspired booking table
│   │   ├── booking_success.html
│   │   ├── correction.html
│   │   ├── delete_confirmation.html
│   ├── models.py
│   ├── views.py
│   ├── urls.py
│── booking_project/
│   ├── settings.py
│   ├── urls.py
│── manage.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;Database Model&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;booking_app/models.py&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.db&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Booking&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;PERSON_CHOICES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;1&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Person 1&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Person 2&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Person 3&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;4&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Person 4&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;EmailField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;TimeField&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CharField&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max_length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;choices&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;PERSON_CHOICES&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;__str__&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Booking by &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; on &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; at &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;Views (Core Logic)&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;booking_app/views.py&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.shortcuts&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;get_object_or_404&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Booking&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;POST&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;Booking&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;email&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Date&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Time&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;person&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;success&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;index.html&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;booking_success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;booking_success.html&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;showdb&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;individualbooking&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Booking&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;showdb.html&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;individualbooking&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;individualbooking&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;updateInfo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_object_or_404&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Booking&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;POST&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;updateInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;updateInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;email&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;updateInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;date&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;updateInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;time&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;updateInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;POST&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;person&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;updateInfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;showdb&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;correction.html&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;updateInfo&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;updateInfo&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;delete_contact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;booking&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_object_or_404&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Booking&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;method&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;POST&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;booking&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;showdb&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;delete_confirmation.html&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;booking&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;booking&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;URLs&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;booking_app/urls.py&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;django.urls&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;.&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt;

&lt;span class="n"&gt;urlpatterns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;index&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;success/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;booking_success&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;success&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;showdb&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;showdb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;showdb&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;update/&amp;lt;int:id&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;update&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nf"&gt;path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;delete_contact/&amp;lt;int:id&amp;gt;&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;views&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;delete_contact&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;delete_contact&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;Booking Table Template&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;showdb.html&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{% raw %}
&amp;lt;tbody&amp;gt;
{% for booking in individualbooking %}
&amp;lt;tr&amp;gt;
    &amp;lt;td&amp;gt;{{ booking.name }}&amp;lt;/td&amp;gt;
    &amp;lt;td&amp;gt;{{ booking.email }}&amp;lt;/td&amp;gt;
    &amp;lt;td&amp;gt;{{ booking.date }}&amp;lt;/td&amp;gt;
    &amp;lt;td&amp;gt;{{ booking.time }}&amp;lt;/td&amp;gt;
    &amp;lt;td&amp;gt;{{ booking.person }}&amp;lt;/td&amp;gt;
    &amp;lt;td&amp;gt;
        &amp;lt;a href="{% url 'update' booking.id %}"&amp;gt;
            &amp;lt;i class="fa-regular fa-pen-to-square"&amp;gt;&amp;lt;/i&amp;gt;
        &amp;lt;/a&amp;gt;
    &amp;lt;/td&amp;gt;
    &amp;lt;td&amp;gt;
        &amp;lt;a href="{% url 'delete_contact' booking.id %}"&amp;gt;
            &amp;lt;i class="fa-regular fa-trash-can"&amp;gt;&amp;lt;/i&amp;gt;
        &amp;lt;/a&amp;gt;
    &amp;lt;/td&amp;gt;
&amp;lt;/tr&amp;gt;
{% empty %}
&amp;lt;tr&amp;gt;
    &amp;lt;td colspan="7" style="text-align:center;"&amp;gt;No bookings yet&amp;lt;/td&amp;gt;
&amp;lt;/tr&amp;gt;
{% endfor %}
{% endraw %}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  &lt;strong&gt;How to Run&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Install Django:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;django
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Create and configure your Django project and app.&lt;/li&gt;
&lt;li&gt;Run migrations:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python manage.py makemigrations
python manage.py migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Start the server:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python manage.py runserver
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Visit &lt;strong&gt;&lt;code&gt;http://127.0.0.1:8000/&lt;/code&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Final Thoughts&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;By combining the &lt;strong&gt;Kopee Dashboard&lt;/strong&gt; for the form and a &lt;strong&gt;Venus Dashboard-inspired&lt;/strong&gt; layout for the table, I built a booking management system that looks professional and works efficiently—without reinventing the wheel for UI design. Django handled the backend logic perfectly, while these templates gave the project a polished frontend.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Full Source Code&lt;/strong&gt;: &lt;em&gt;&lt;a href="https://github.com/Fikalz/A-functioning-booking-form-with-django/tree/main" rel="noopener noreferrer"&gt;https://github.com/Fikalz/A-functioning-booking-form-with-django/tree/main&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Here are some of the images of the site&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgm0zxce49z0rnmedb2mu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgm0zxce49z0rnmedb2mu.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frj5e2yb2u63atkdpl4l5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frj5e2yb2u63atkdpl4l5.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ci8avmg0a5m09n229vm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ci8avmg0a5m09n229vm.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3qs7om85tzg97aym8pxo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3qs7om85tzg97aym8pxo.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>python</category>
      <category>backenddevelopment</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Your First Django Database Write: A Step-by-Step Walkthrough</title>
      <dc:creator>Morodolu Oluwafikunayomi</dc:creator>
      <pubDate>Sun, 03 Aug 2025 11:14:48 +0000</pubDate>
      <link>https://dev.to/fikalz/your-first-django-database-write-a-step-by-step-walkthrough-4hi6</link>
      <guid>https://dev.to/fikalz/your-first-django-database-write-a-step-by-step-walkthrough-4hi6</guid>
      <description>&lt;p&gt;When learning Django, one of the most powerful things you'll discover is how effortlessly it lets you interact with databases using models. In this guide, I’ll walk you through how to write to a database in Django using real examples, no steps skipped!&lt;/p&gt;

&lt;p&gt;Whether you're just starting or you’re working on a mini project, this article will help you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set up your virtual environment&lt;/li&gt;
&lt;li&gt;Install Django&lt;/li&gt;
&lt;li&gt;Start a project and app&lt;/li&gt;
&lt;li&gt;Create and configure a model&lt;/li&gt;
&lt;li&gt;Run the server and interact with the database
&lt;strong&gt;Step 1: Set Up Your Environment:&lt;/strong&gt;
On my previous post on python i showed the walkthrough on the creation and interacting with django,  but first, create a new folder for your project, then open your terminal or command prompt inside that folder.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python -m venv venvname
cd venvname\Scripts
activate.bat
cd ../..
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcj6nl9sg9mfsd477am55.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcj6nl9sg9mfsd477am55.png" alt=" " width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;💡 Note: venvname can be any name for your virtual environment.&lt;/em&gt;&lt;br&gt;
Once activated, install Django:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python -m pip install django
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see Django and its dependencies installing without issues.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Create Your Django Project and App&lt;/strong&gt;&lt;br&gt;
Next, use the Django CLI to set up your project and an app inside it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;django-admin startproject connectdb .
django-admin startapp dbapp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz7ie40ochzamduucyey2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz7ie40ochzamduucyey2.png" alt=" " width="800" height="330"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Make sure your structure looks like this&lt;br&gt;
djangopractice/&lt;br&gt;
├── connectdb/&lt;br&gt;
├── dbapp/&lt;br&gt;
├── venvname/&lt;br&gt;
├── manage.py&lt;br&gt;
in the root folder in your file explorer&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Create Your Model&lt;/strong&gt;&lt;br&gt;
Now open dbapp/models.py and define your model class. For this example, `I created a Contacts model:&lt;br&gt;
from django.db import models&lt;/p&gt;

&lt;p&gt;class Contacts(models.Model):&lt;br&gt;
    firstname = models.CharField(max_length=100)&lt;br&gt;
    lastname = models.CharField(max_length=100)&lt;br&gt;
    age = models.IntegerField()&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def __str__(self):
    return self.firstname`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F171mj7sgqnvztuqof2yr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F171mj7sgqnvztuqof2yr.png" alt=" " width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This will let Django know you want a table in the database called Contacts, with firstname, lastname, and age fields.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Connect to the Database Using Django Shell&lt;/strong&gt;&lt;br&gt;
you can use the django shell but i use the command prompt for this, open a new command prompt and type in one line after the other.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd downloads\djangopractice\venvname\Scripts
activate.bat
cd ../..
python manage.py makemigrations
python manage.py migrate
python manage.py shell
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9bg0mljxctrw1skembt5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9bg0mljxctrw1skembt5.png" alt=" " width="800" height="468"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Write to the Database&lt;/strong&gt;&lt;br&gt;
Inside the shell, you can import your model and start creating records. Here's how:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# First, import the model
from dbapp.models import Contacts

# Then, create a new instance
contact = Contacts(firstname='John', lastname='Doe', age=28)

# Save it to the database
contact.save()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it! 🎉 You've just written to your database.&lt;br&gt;
You can verify it by retrieving all records by&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Contacts.objects.all()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb15ve3m8jgd0409myfuc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb15ve3m8jgd0409myfuc.png" alt=" " width="800" height="175"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In my next article, I’ll show you how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Register your models with the Django admin&lt;/li&gt;
&lt;li&gt;Create a superuser&lt;/li&gt;
&lt;li&gt;Use Django’s powerful built-in admin interface to manage data visually
if you have any question or contribution ask in the comment i will always respond &lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>backenddevelopment</category>
      <category>python</category>
      <category>django</category>
    </item>
    <item>
      <title>Load Balancing in AWS: Deliver High Availability with Smart Traffic Distribution</title>
      <dc:creator>Morodolu Oluwafikunayomi</dc:creator>
      <pubDate>Tue, 29 Jul 2025 07:13:55 +0000</pubDate>
      <link>https://dev.to/fikalz/load-balancing-in-aws-deliver-high-availability-with-smart-traffic-distribution-edm</link>
      <guid>https://dev.to/fikalz/load-balancing-in-aws-deliver-high-availability-with-smart-traffic-distribution-edm</guid>
      <description>&lt;p&gt;In today's cloud-native world, users expect applications to be fast, reliable, and always available. Whether it's a web app, an API, or a containerized service, your infrastructure needs to be able to handle changing traffic loads without breaking under pressure.&lt;br&gt;
That’s where load balancing comes in — and in AWS, Amazon Web Services (AWS), Elastic Load Balancing (ELB) is a fully managed service designed to automatically distribute incoming traffic across multiple targets such as EC2 instances, containers, and IP addresses.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Load Balancing?&lt;/strong&gt;&lt;br&gt;
Load balancing is the process of distributing incoming network traffic across multiple backend resources. This prevents any single resource from becoming a bottleneck, thereby improving:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Availability&lt;/li&gt;
&lt;li&gt;Scalability&lt;/li&gt;
&lt;li&gt;Fault tolerance&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Performance&lt;br&gt;
&lt;strong&gt;Types of Load Balancers in AWS&lt;/strong&gt;&lt;br&gt;
AWS offers four types of load balancers under the Elastic Load Balancing (ELB) service:&lt;br&gt;
But before that there is something called OSI model( Open Systems Interconnection model), it is a conceptual framework that standardizes how computer systems communicate over a network, it operates at a seven layer framework, which are &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;physical&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;datalink&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;network&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;transport&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;session&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;presentation&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;application&lt;br&gt;
Depending on what your app needs, AWS offers four types of load balancers. Here's a quick overview and which layer they operate at:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Application Load Balancer (ALB)&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Operates at Layer 7 (Application)(HTTP/HTTPS).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Great for routing based on content (like path or hostname).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Perfect for modern web apps and microservices.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Network Load Balancer (NLB)&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Works at Layer 4(transport)(TCP/UDP).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Designed for ultra-low latency and high throughput.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ideal for high-performance, real-time applications.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Gateway Load Balancer (GWLB)&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Best suited for integrating third-party security appliances like firewalls or intrusion detection systems.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Routes traffic transparently while scaling with demand.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Classic Load Balancer (CLB)&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Older generation, supports both Layer 4 and Layer 7.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Mostly used in legacy systems, not recommended for new projects.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;How Load Balancing Works in AWS&lt;/strong&gt;&lt;br&gt;
Here’s a simplified view of what happens when someone accesses your app through a load balancer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A user makes a request to your application (e.g., opens your website).&lt;/li&gt;
&lt;li&gt;The request is sent to your load balancer via a DNS name.&lt;/li&gt;
&lt;li&gt;The load balancer checks which backend servers (targets) are healthy.&lt;/li&gt;
&lt;li&gt;It forwards the request to one of those healthy servers based on a routing algorithm (like round-robin).&lt;/li&gt;
&lt;li&gt;The chosen server processes the request and sends the response back through the load balancer to the user.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Simple, seamless, and scalable.&lt;/p&gt;

&lt;p&gt;_in simpler terms _&lt;br&gt;
When one server is receiving too much traffic, instead of letting it get overwhelmed, the load balancer steps in and says:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Hey, this server is getting busy — let me send the next request to another server that’s less busy or idle.”&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it distributes incoming traffic across multiple servers, which:&lt;/li&gt;
&lt;li&gt;Prevents any one server from crashing or slowing down&lt;/li&gt;
&lt;li&gt;Keeps your app fast and available&lt;/li&gt;
&lt;li&gt;Helps scale your infrastructure without users even noticing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step-by-Step: Setting Up an Application Load Balancer (ALB)&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Step 1: Launch Your EC2 Instances:&lt;/strong&gt;&lt;br&gt;
Start by launching at least two EC2 instances (in different Availability Zones if possible). These will serve your application and install Apache or NGINX, app on each. &lt;em&gt;If you don't know how to create instance check out my previous post on creation of instances and installation of webserver such as apache or nginx as i will skipping a lot of steps&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzg97ijvk9c3hsdeqt3pp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzg97ijvk9c3hsdeqt3pp.png" alt=" " width="800" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fesxfypu87laav9p1ncmg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fesxfypu87laav9p1ncmg.png" alt=" " width="800" height="276"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpm5zkcy22pd9jrqdcz4r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpm5zkcy22pd9jrqdcz4r.png" alt=" " width="800" height="328"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg1npvez28kuf47jnmqer.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg1npvez28kuf47jnmqer.png" alt=" " width="799" height="169"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Create a Target Group&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to EC2 &amp;gt; Target Groups.&lt;/li&gt;
&lt;li&gt;Click Create target group, choose “Instances” as the target type.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8xw46zz5urtegrx892ku.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8xw46zz5urtegrx892ku.png" alt=" " width="800" height="254"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxzj2lseocb3mxuxdtzb5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxzj2lseocb3mxuxdtzb5.png" alt=" " width="800" height="276"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw39lwg6lz43e317jxk90.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw39lwg6lz43e317jxk90.png" alt=" " width="761" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;leave the VPC as default or if you have specific configuration&lt;br&gt;
Set the protocol and port (e.g., HTTP, port 80).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0fng58gc1yq9npvz8q04.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0fng58gc1yq9npvz8q04.png" alt=" " width="753" height="331"&gt;&lt;/a&gt;&lt;br&gt;
then click on next&lt;br&gt;
Register your EC2 instances to the target group.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc91n7il00jit5up3kwil.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc91n7il00jit5up3kwil.png" alt=" " width="800" height="338"&gt;&lt;/a&gt;&lt;br&gt;
then click on create target group&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1ssgw6b5e1foch4ibicz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1ssgw6b5e1foch4ibicz.png" alt=" " width="799" height="242"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Create the Load Balancer&lt;/strong&gt;&lt;br&gt;
Go to EC2 &amp;gt; Load Balancers, then click Create Load Balancer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgon9gse38h4tg8zb5pyh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgon9gse38h4tg8zb5pyh.png" alt=" " width="800" height="303"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Choose Application Load Balancer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyl4n01l6srr6cwekwftn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyl4n01l6srr6cwekwftn.png" alt=" " width="363" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0lip6hat5uzoi4ro27el.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0lip6hat5uzoi4ro27el.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;br&gt;
 leave the VPC as default and select the the availability zone  based on the instance you created &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgpvdofkrpujv4gg0dsju.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgpvdofkrpujv4gg0dsju.png" alt=" " width="800" height="290"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Set the name, select internet-facing or internal, and assign at least two Availability Zones for high availability.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe9rz9a5bmjss62vmkp2b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe9rz9a5bmjss62vmkp2b.png" alt=" " width="800" height="254"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;from the above picture click on default action and select the previous target group we created then click on add listener tag, then leave the remaining checks as is, then click on create load balancer.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Test Your Setup&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Grab the DNS name of your ALB from the console.&lt;/li&gt;
&lt;li&gt;Paste it in your browser — you should see one of your app instances respond.&lt;/li&gt;
&lt;li&gt;Refresh a few times to see how it balances across servers.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aws</category>
      <category>beginners</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
