<?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: Zoo Codes</title>
    <description>The latest articles on DEV Community by Zoo Codes (@ken_mwaura1).</description>
    <link>https://dev.to/ken_mwaura1</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%2F292307%2F0269edd6-31aa-4039-afb5-45b176646fd9.png</url>
      <title>DEV Community: Zoo Codes</title>
      <link>https://dev.to/ken_mwaura1</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ken_mwaura1"/>
    <language>en</language>
    <item>
      <title>[Boost]</title>
      <dc:creator>Zoo Codes</dc:creator>
      <pubDate>Wed, 05 Aug 2026 09:19:29 +0000</pubDate>
      <link>https://dev.to/ken_mwaura1/-5d22</link>
      <guid>https://dev.to/ken_mwaura1/-5d22</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/ken_mwaura1/continuous-improvement-what-we-shipped-to-jengastack-this-week-4h5m" class="crayons-story__hidden-navigation-link"&gt;Building Managed Odoo Infrastructure in Kenya: What We Shipped This Week (August 5, 2026) 🛠️🇰🇪&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="/ken_mwaura1" 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%2F292307%2F0269edd6-31aa-4039-afb5-45b176646fd9.png" alt="ken_mwaura1 profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/ken_mwaura1" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Zoo Codes
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Zoo Codes
                
              
              &lt;div id="story-author-preview-content-4320660" 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="/ken_mwaura1" 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%2F292307%2F0269edd6-31aa-4039-afb5-45b176646fd9.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Zoo Codes&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/ken_mwaura1/continuous-improvement-what-we-shipped-to-jengastack-this-week-4h5m" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Aug 5&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/ken_mwaura1/continuous-improvement-what-we-shipped-to-jengastack-this-week-4h5m" id="article-link-4320660"&gt;
          Building Managed Odoo Infrastructure in Kenya: What We Shipped This Week (August 5, 2026) 🛠️🇰🇪
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/programming"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;programming&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/django"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;django&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/devops"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;devops&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/buildinpublic"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;buildinpublic&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/ken_mwaura1/continuous-improvement-what-we-shipped-to-jengastack-this-week-4h5m" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;6&lt;span class="hidden s:inline"&gt;&amp;nbsp;reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/ken_mwaura1/continuous-improvement-what-we-shipped-to-jengastack-this-week-4h5m#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;
            3 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>Building Managed Odoo Infrastructure in Kenya: What We Shipped This Week (August 5, 2026) 🛠️🇰🇪</title>
      <dc:creator>Zoo Codes</dc:creator>
      <pubDate>Wed, 05 Aug 2026 09:18:25 +0000</pubDate>
      <link>https://dev.to/ken_mwaura1/continuous-improvement-what-we-shipped-to-jengastack-this-week-4h5m</link>
      <guid>https://dev.to/ken_mwaura1/continuous-improvement-what-we-shipped-to-jengastack-this-week-4h5m</guid>
      <description>&lt;p&gt;Building managed multi-tenant infrastructure for Odoo in Kenya comes with a unique set of engineering challenges. Beyond handling high uptime and container orchestration, local SaaS platforms must integrate reliably with regulatory APIs like the &lt;strong&gt;Kenya Revenue Authority (KRA) eTIMS&lt;/strong&gt; and local payment gateways like M-Pesa.&lt;/p&gt;

&lt;p&gt;Here is an engineering deep-dive into what we updated, refactored, and fixed under the hood across JengaStack this week.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Resolving Odoo ORM Tax Group Errors in POS &amp;amp; Zero-Downtime Migration
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Issue
&lt;/h3&gt;

&lt;p&gt;During Point of Sale (POS) checkouts, an edge-case bug occurred around &lt;code&gt;account.tax.group&lt;/code&gt; mapping for KRA eTIMS tax rates. In Odoo's financial engine, improper tax group assignments can prevent invoice payload generation or result in XML schema validation failures when submitting invoices to KRA's API.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Fix
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;ORM-Level Patching:&lt;/strong&gt; Corrected the tax group associations within custom eTIMS modules so that POS checkout flows dynamically map tax groups without dropping validation fields.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automated Tenant Patching Script (&lt;code&gt;fix_tenant_taxes.py&lt;/code&gt;):&lt;/strong&gt; Rather than requiring manual database migrations or taking down tenant instances, we deployed an automated Python migration script:

&lt;ul&gt;
&lt;li&gt;Connects via Odoo's internal environment context (&lt;code&gt;odoo.api.Environment&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Iterates across isolated tenant schema/databases.&lt;/li&gt;
&lt;li&gt;Updates &lt;code&gt;account.tax&lt;/code&gt; references transactionally and commits without requiring instance restarts.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  2. CI/CD Hardening &amp;amp; Vulnerability Patching with &lt;code&gt;uv&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Security hygiene in a multi-tenant cloud environment requires proactive dependency management.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Core Package Upgrades:&lt;/strong&gt; Upgraded key backend libraries—including &lt;code&gt;cryptography&lt;/code&gt;, &lt;code&gt;WeasyPrint&lt;/code&gt; (used for PDF report generation), and &lt;code&gt;Pygments&lt;/code&gt;—to address recently published CVEs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pipeline Audits with &lt;code&gt;uv&lt;/code&gt;:&lt;/strong&gt; Integrated &lt;code&gt;uv&lt;/code&gt; into our GitHub Actions / CI pipeline for ultra-fast dependency resolution and automated auditing (&lt;code&gt;uv pip audit&lt;/code&gt;). Any pipeline with vulnerable transitive dependencies is flagged before reaching staging or production.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. Modernizing Internal Tooling: Portainer → Dockhand + Authentik SSO
&lt;/h2&gt;

&lt;p&gt;As infrastructure scales, managing endpoints via raw IPs creates friction and expands the attack surface.&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%2Fnezf6tbaw2zwy378d90r.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%2Fnezf6tbaw2zwy378d90r.png" alt="workflow" width="629" height="245"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Domain Migration:&lt;/strong&gt; Fully transitioned all management subdomains (&lt;code&gt;app.jengastack.app&lt;/code&gt; and &lt;code&gt;auth.jengastack.app&lt;/code&gt;) to HTTPS behind reverse proxy routing with automatic Let's Encrypt renewal.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Replacing Portainer with Dockhand + Authentik:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Retired legacy Portainer instances in favor of &lt;strong&gt;Dockhand&lt;/strong&gt; paired with &lt;strong&gt;Authentik SSO&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Enforced centralized identity management (OIDC), multi-factor authentication (MFA), and role-based access control (RBAC) across all container nodes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Observability &amp;amp; Analytics Routing:&lt;/strong&gt; Resolved SSL routing bottlenecks on telemetry endpoints and refined health probe thresholds to eliminate false-positive restart triggers during peak database IOPS.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. Resilience Patterns for Third-Party APIs &amp;amp; RPC Bug Fixes
&lt;/h2&gt;

&lt;p&gt;Network volatility between cloud servers and external government endpoints is an inevitable reality.&lt;/p&gt;

&lt;h3&gt;
  
  
  Circuit Breakers for eTIMS API Drops
&lt;/h3&gt;

&lt;p&gt;When KRA eTIMS endpoints experience latency or intermittent drops, unhandled timeouts can cascade and block checkout threads in Odoo.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Extended our custom eTIMS integration with an explicit &lt;strong&gt;Circuit Breaker pattern&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Intercepts connection drop exceptions, fails gracefully without crashing POS threads, and queues fiscal requests in a background worker queue for retry upon service recovery.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Odoo RPC &amp;amp; Asset Pipeline Fixes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;OdooRPCError: cannot marshal None&lt;/code&gt;&lt;/strong&gt;: Fixed a serialization error where XML-RPC / JSON-RPC responses returned &lt;code&gt;None&lt;/code&gt; types on null-returning controller methods.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Staticfiles Manifest Handling:&lt;/strong&gt; Handled missing file manifest exceptions gracefully during asset compilation, preventing broken UI assets during rolling backend deployments.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key Takeaways
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Automate schema and data updates:&lt;/strong&gt; If you run multi-tenant software, build CLI/Python script runners that can patch live tenant databases transactionally.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build for network resilience:&lt;/strong&gt; When relying on external regulatory or payment APIs, always wrap HTTP calls in circuit breakers and resilient background queues.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Streamline internal IAM early:&lt;/strong&gt; Moving management tools behind centralized SSO (Authentik) with strict HTTPS subdomains drastically reduces ops overhead and improves platform posture.&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;&lt;em&gt;Are you building cloud platforms or running Odoo in production? Let me know in the comments how you handle zero-downtime tenant updates and third-party API resilience!&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx34yzq57g8u0yk6qjlty.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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fx34yzq57g8u0yk6qjlty.gif" alt="next-time" width="498" height="206"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>django</category>
      <category>devops</category>
      <category>buildinpublic</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Zoo Codes</dc:creator>
      <pubDate>Mon, 03 Aug 2026 07:41:21 +0000</pubDate>
      <link>https://dev.to/ken_mwaura1/-5flo</link>
      <guid>https://dev.to/ken_mwaura1/-5flo</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/ken_mwaura1/engineering-jengastack-how-we-built-managed-odoo-19-automated-kra-etims-compliance-for-kenya-53g3" class="crayons-story__hidden-navigation-link"&gt;Engineering JengaStack: How We Built Managed Odoo 19 &amp;amp; Automated KRA eTIMs Compliance for Kenya&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="/ken_mwaura1" 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%2F292307%2F0269edd6-31aa-4039-afb5-45b176646fd9.png" alt="ken_mwaura1 profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/ken_mwaura1" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Zoo Codes
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Zoo Codes
                
              
              &lt;div id="story-author-preview-content-4299760" 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="/ken_mwaura1" 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%2F292307%2F0269edd6-31aa-4039-afb5-45b176646fd9.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Zoo Codes&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/ken_mwaura1/engineering-jengastack-how-we-built-managed-odoo-19-automated-kra-etims-compliance-for-kenya-53g3" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Aug 3&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/ken_mwaura1/engineering-jengastack-how-we-built-managed-odoo-19-automated-kra-etims-compliance-for-kenya-53g3" id="article-link-4299760"&gt;
          Engineering JengaStack: How We Built Managed Odoo 19 &amp;amp; Automated KRA eTIMs Compliance for Kenya
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/automation"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;automation&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/cloud"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;cloud&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/saas"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;saas&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/startup"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;startup&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/ken_mwaura1/engineering-jengastack-how-we-built-managed-odoo-19-automated-kra-etims-compliance-for-kenya-53g3" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/multi-unicorn-b44d6f8c23cdd00964192bedc38af3e82463978aa611b4365bd33a0f1f4f3e97.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;6&lt;span class="hidden s:inline"&gt;&amp;nbsp;reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/ken_mwaura1/engineering-jengastack-how-we-built-managed-odoo-19-automated-kra-etims-compliance-for-kenya-53g3#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;
            2 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success crayons-icon c-btn__icon"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>Engineering JengaStack: How We Built Managed Odoo 19 &amp; Automated KRA eTIMs Compliance for Kenya</title>
      <dc:creator>Zoo Codes</dc:creator>
      <pubDate>Mon, 03 Aug 2026 07:41:08 +0000</pubDate>
      <link>https://dev.to/ken_mwaura1/engineering-jengastack-how-we-built-managed-odoo-19-automated-kra-etims-compliance-for-kenya-53g3</link>
      <guid>https://dev.to/ken_mwaura1/engineering-jengastack-how-we-built-managed-odoo-19-automated-kra-etims-compliance-for-kenya-53g3</guid>
      <description>&lt;p&gt;Running an ERP system for a business in Kenya often comes with significant friction: complex server management, manual KRA eTIMS tax compliance, fragmented M-Pesa payment reconciliations, and identity management headaches.&lt;/p&gt;

&lt;p&gt;At &lt;strong&gt;JengaStack&lt;/strong&gt;, our mission is to eliminate this complexity. We've built a managed SaaS platform that automates Odoo 19 hosting, localized tax compliance, payment gateways and enterprise security.&lt;/p&gt;

&lt;h2&gt;
  
  
  🎯 The Problem
&lt;/h2&gt;

&lt;p&gt;Kenyan SMEs and growing enterprises face three primary operational hurdles when adopting ERP systems:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Local Statutory Compliance:&lt;/strong&gt; Setting up KRA eTIMS tax categories, PIN validation and compliant invoice formatting in standard open-source ERPs is tedious and error-prone.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Payment Disconnect:&lt;/strong&gt; Integrating local payment gateways like M-Pesa (Daraja) usually requires custom, unmaintained modules.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure Overhead:&lt;/strong&gt; Self-hosting Odoo requires managing PostgreSQL databases, reverse proxies, SSL certificates, backup schedules, and monitoring.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  ⚙️ How JengaStack Solves It
&lt;/h2&gt;

&lt;p&gt;We engineered a multi-tenant platform powered by a &lt;strong&gt;Django + HTMX dashboard&lt;/strong&gt; orchestrating isolated &lt;strong&gt;Odoo 19&lt;/strong&gt; tenant stacks.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Automated Kenyan Statutory Provisioning
&lt;/h3&gt;

&lt;p&gt;When a new tenant signs up, JengaStack automatically provisions an isolated Odoo environment pre-configured with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Currency &amp;amp; Locale:&lt;/strong&gt; Activated KES (&lt;code&gt;KSh&lt;/code&gt;) with &lt;code&gt;Africa/Nairobi&lt;/code&gt; timezone and &lt;code&gt;DD/MM/YYYY&lt;/code&gt; formatting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kenyan Chart of Accounts:&lt;/strong&gt; Pre-loaded &lt;code&gt;l10n_ke&lt;/code&gt; package.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;KRA Tax Categories:&lt;/strong&gt; Out-of-the-box support for 16% Standard VAT (Code A), 0% Zero-Rated (Code B), Exempt (Code C), 8% Fuel Tax, Withholding Tax (WHT) and WHVAT.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Localized Layouts:&lt;/strong&gt; Pre-formatted A4 statutory invoice and quote layouts featuring KRA PIN fields.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Native M-Pesa Integration
&lt;/h3&gt;

&lt;p&gt;Through our custom &lt;code&gt;jenga_mpesa&lt;/code&gt; module, tenants accept M-Pesa STK push and C2B payments directly at checkout or via invoice payment links. Transactions automatically reconcile into Odoo’s general ledger in real time.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Enterprise Identity &amp;amp; Security (Authentik SSO)
&lt;/h3&gt;

&lt;p&gt;We integrated &lt;strong&gt;Authentik OIDC&lt;/strong&gt; using standard PKCE Authorization Code Flows (RFC 7636). Users sign in once via &lt;strong&gt;Jenga ID&lt;/strong&gt; to access their management dashboard and Odoo workspace seamlessly without handling insecure credentials.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Robust Cloud Infrastructure (Azure + Traefik + PgBouncer)
&lt;/h3&gt;

&lt;p&gt;Our multi-VPS production architecture on Azure separates controller services from tenant worker nodes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Edge Proxy:&lt;/strong&gt; Traefik dynamically routes domain requests and handles automatic TLS certificates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database Scaling:&lt;/strong&gt; PgBouncer provides connection pooling for high concurrency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Continuous Monitoring:&lt;/strong&gt; Alertmanager integrated with Telegram and Grafana ensures instant notification on infrastructure state.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Two-Lane Email Architecture:&lt;/strong&gt; System notifications leverage Brevo SMTP (&lt;code&gt;noreply@jengastack.app&lt;/code&gt;), while customer communications direct to Zoho Mail support.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Key Technical &amp;amp; Product Highlights Featured:
&lt;/h3&gt;

&lt;p&gt;• Mission: Managed Odoo Hosting &amp;amp; Automated Compliance for Kenya.&lt;br&gt;
  • Localization: KRA eTIMS (16%, 0%, Exempt, 8% Fuel, WHT, WHVAT), l10n_ke, KES (KSh), EAT&lt;br&gt;
  timezone (Africa/Nairobi).&lt;br&gt;
  • Payments: Native M-Pesa (Daraja) integration.&lt;br&gt;
  • Security: Authentik OIDC with PKCE authorization flow (RFC 7636).&lt;br&gt;
  • Stack: Django, HTMX, Odoo 19, Traefik, PgBouncer, Tailscale, Komodo, Azure.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 What's Next?
&lt;/h2&gt;

&lt;p&gt;We are rolling out early access for Kenyan businesses, accounting firms, and IT integrators who want hassle-free ERP deployment.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- 🌐 **Website:** https://jengastack.app
- 📖 **Documentation:** https://docs.jengastack.app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Have questions about our architecture or want a demo? Reach out to &lt;a href="mailto:support@jengastack.app"&gt;support@jengastack.app&lt;/a&gt; or connect with us on &lt;a href="https://www.linkedin.com/in/kennedy-mwaura/" rel="noopener noreferrer"&gt;LinkedIn!&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
                          ──────&lt;/p&gt;

</description>
      <category>automation</category>
      <category>cloud</category>
      <category>saas</category>
      <category>startup</category>
    </item>
    <item>
      <title>The Cloud Exit Strategy: Architecting for Independence</title>
      <dc:creator>Zoo Codes</dc:creator>
      <pubDate>Tue, 20 Jan 2026 11:00:59 +0000</pubDate>
      <link>https://dev.to/ken_mwaura1/the-cloud-exit-strategy-architecting-for-independence-5cbg</link>
      <guid>https://dev.to/ken_mwaura1/the-cloud-exit-strategy-architecting-for-independence-5cbg</guid>
      <description>&lt;p&gt;We have normalized a dangerous standard in modern web development: paying hundreds of dollars a month for infrastructure before acquiring a single customer. We build distributed systems for simple problems. We rent our identity, our data, and our compute from vendors who profit from our complexity.&lt;/p&gt;

&lt;p&gt;It is time to reject the complexity tax. It is time to return to the $5 VPS.&lt;/p&gt;

&lt;p&gt;Here is the architecture of independence.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Philosophy: The Modular Monolith
&lt;/h2&gt;

&lt;p&gt;The industry tells you to split your application into microservices, serverless functions, and edge computing nodes. This is excellent advice for Netflix. It is terrible advice for you.&lt;/p&gt;

&lt;p&gt;For 99% of SaaS applications, the correct architecture is a &lt;strong&gt;Modular Monolith&lt;/strong&gt; running on a Linux server you control. This approach minimizes network latency, eliminates distributed systems failures, and—most importantly—gives you infinite runway.&lt;/p&gt;

&lt;p&gt;This isn't just about saving money. It is about architectural sanity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 1: The Control Plane (Coolify / Dokploy)
&lt;/h2&gt;

&lt;p&gt;The main reason developers flock to Vercel or Heroku is the "git push" deployment experience. Setting up Linux servers, configuring Nginx reverse proxies, and managing SSL certificates manually is tedious.&lt;/p&gt;

&lt;p&gt;But we don't need to do that manually anymore. We can run our own Platform as a Service (PaaS).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Choice:&lt;/strong&gt; &lt;a href="https://coolify.io" rel="noopener noreferrer"&gt;Coolify&lt;/a&gt; or &lt;a href="https://dokploy.com" rel="noopener noreferrer"&gt;Dokploy&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Lesson:&lt;/strong&gt; These tools act as a self-hosted overlay for your VPS. You connect your GitHub repository, and they handle the Docker builds, reverse proxies, and SSL certificates automatically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why:&lt;/strong&gt; You get the Vercel experience (automated deployments, preview URLs) without the Vercel restrictions (bandwidth limits, function timeouts, vendor lock-in).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Layer 2: The Data Layer (SQLite + Litestream)
&lt;/h2&gt;

&lt;p&gt;We have been gaslit into believing we need a distributed Postgres cluster for a standard CRUD application.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SQLite&lt;/strong&gt; in WAL (Write-Ahead Logging) mode is not a toy; it is a production-grade database engine. Because it runs in-process with your application, query latency drops from 50ms (cloud roundtrip) to sub-0.1ms (memory access).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Disaster Recovery Strategy:&lt;/strong&gt;&lt;br&gt;
The fear of SQLite is, "What if the server disk dies?"&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The Solution:&lt;/strong&gt; &lt;a href="https://litestream.io" rel="noopener noreferrer"&gt;Litestream&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How it works:&lt;/strong&gt; It hooks into SQLite’s WAL file and streams changes to commodity object storage (S3, Cloudflare R2, MinIO) in real-time. You achieve essentially zero RPO (Recovery Point Objective) for pennies a month.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Migration Path: When to Eject?
&lt;/h3&gt;

&lt;p&gt;A common anxiety with this stack is scalability. "What happens when I grow?"&lt;/p&gt;

&lt;p&gt;The truth is, SQLite handles reads effortlessly (it powers billions of mobile devices). The bottleneck is strictly &lt;strong&gt;concurrent writes&lt;/strong&gt;. Because SQLite locks the database file during a write operation (even in WAL mode, though significantly optimized), you generally hit a ceiling at around 200–500 write transactions per second, depending on your hardware.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Reality Check:&lt;/strong&gt;&lt;br&gt;
If you are processing 500 writes per second, you likely have tens of thousands of concurrent users. At that point, you are no longer a "bootstrapped project"—you are a successful business with revenue.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Ejection Plan:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Vertical Scaling First:&lt;/strong&gt; Before you leave SQLite, upgrade your $5 VPS to a $40 VPS. Faster NVMe drives and more CPU cores will extend SQLite's life significantly.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;The Switch:&lt;/strong&gt; If you truly saturate the drive I/O, you switch to Postgres. Because we are using standard SQL (via an ORM or query builder), this migration is often just changing a connection string and a driver.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Reaching the limits of SQLite is a "good problem." Do not optimize for it on Day 1.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 3: Identity &amp;amp; Auth (Better-Auth / Authentik)
&lt;/h2&gt;

&lt;p&gt;Identity is the stickiest layer of the stack. If you use Auth0 or Clerk, you are renting your users. If you stop paying, you lose your customers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option A: The Library Approach (Better-Auth)&lt;/strong&gt;&lt;br&gt;
For TypeScript/Node ecosystems, libraries like &lt;strong&gt;Better-Auth&lt;/strong&gt; allow you to embed robust authentication (Social Logins, 2FA, Passkeys) directly into your monolith.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pros:&lt;/strong&gt; The user data lives in &lt;em&gt;your&lt;/em&gt; database tables. Zero external dependency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cons:&lt;/strong&gt; Tightly coupled to your codebase.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Option B: The Service Approach (Authentik)&lt;/strong&gt;&lt;br&gt;
For a language-agnostic solution (Go, Rust, Python), run &lt;strong&gt;Authentik&lt;/strong&gt; as a container in your stack.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pros:&lt;/strong&gt; Provides a full SSO portal. Decouples auth from your application logic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cons:&lt;/strong&gt; Uses more RAM than a library.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Layer 4: Observability (Prometheus + Grafana)
&lt;/h2&gt;

&lt;p&gt;When your app crashes in the cloud, you check the dashboard they provide. When you run your own VPS, you need your own dashboard. Do not pay Datadog $500/month to monitor a $5 server.&lt;/p&gt;

&lt;p&gt;We deploy a standard &lt;strong&gt;Prometheus + Grafana&lt;/strong&gt; stack via Docker Compose.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Prometheus:&lt;/strong&gt; Scrapes metrics from your app and your server (CPU, RAM, Disk I/O).&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Grafana:&lt;/strong&gt; Visualizes that data.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Loki (Optional):&lt;/strong&gt; Aggregates logs.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This gives you deep visibility into your application's performance. You will understand your system better because you built the dashboard yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Application Layer: Language Agnostic
&lt;/h2&gt;

&lt;p&gt;This architecture does not care what language you write in. The "blocks" of this stack—Docker, SQLite, Linux—are universal standards.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Go:&lt;/strong&gt; Use &lt;strong&gt;Fiber&lt;/strong&gt; or &lt;strong&gt;Echo&lt;/strong&gt; for blazing fast binaries that sip memory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rust:&lt;/strong&gt; Use &lt;strong&gt;Axum&lt;/strong&gt; for type-safe, bulletproof performance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Node/TS:&lt;/strong&gt; Use &lt;strong&gt;Hono&lt;/strong&gt; or &lt;strong&gt;FastAPI&lt;/strong&gt; for rapid iteration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Python:&lt;/strong&gt; Use &lt;strong&gt;Django&lt;/strong&gt; or &lt;strong&gt;FastAPI&lt;/strong&gt; if data science is your core.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The interface between your code and the infrastructure is a &lt;code&gt;Dockerfile&lt;/code&gt;. That is the only contract you need to fulfill.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary: The Cost of Freedom
&lt;/h2&gt;

&lt;p&gt;Here is the bill for your production stack:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Service&lt;/th&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Compute&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Hetzner / DigitalOcean&lt;/td&gt;
&lt;td&gt;$5.00 / mo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;PaaS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Coolify (Self-hosted)&lt;/td&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Database&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;SQLite&lt;/td&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Backups&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;S3 / R2 (via Litestream)&lt;/td&gt;
&lt;td&gt;~$0.02 / mo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Auth&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Better-Auth&lt;/td&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Monitoring&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Prometheus/Grafana&lt;/td&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;~$5.02 / mo&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;You don't need a venture capital budget to build scalable software. You need a Linux server and the courage to manage your own stack.&lt;/p&gt;

&lt;p&gt;When you remove the bloated layers of managed services, you aren't just saving money—you are regaining control. You can host ten failed experiments on this server without paying a cent more. You have bought yourself time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stop renting your infrastructure. Own it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you have any questions or suggestions, please feel free to comment below or reach out to me on &lt;a href="https://twitter.com/KenMwaura1" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/kennedy-mwaura/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;. You can also check out my other articles on &lt;a href="https://dev.to/ken_mwaura1"&gt;Dev.to&lt;/a&gt;. Thanks for reading!&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%2Fxweh4feca4z1a7k2d27y.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%2Fxweh4feca4z1a7k2d27y.gif" alt="Next-time" width="498" height="206"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Buy Me a &lt;a href="https://ko-fi.com/kenmwaura1" rel="noopener noreferrer"&gt;Coffee&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>devops</category>
      <category>cloud</category>
      <category>webdev</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Zoo Codes</dc:creator>
      <pubDate>Sun, 18 Jan 2026 15:11:03 +0000</pubDate>
      <link>https://dev.to/ken_mwaura1/-3bna</link>
      <guid>https://dev.to/ken_mwaura1/-3bna</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/ken_mwaura1" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&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%2Fuser%2Fprofile_image%2F292307%2F0269edd6-31aa-4039-afb5-45b176646fd9.png" alt="ken_mwaura1"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/ken_mwaura1/unleashing-devops-with-automated-vm-labs-vagrant-libvirt-ansible-2gmk" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Unleashing DevOps with Automated VM Labs: Vagrant + Libvirt + Ansible 🚀&lt;/h2&gt;
      &lt;h3&gt;Zoo Codes ・ Jan 18&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#virtualmachine&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#automation&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#linux&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#tutorial&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>virtualmachine</category>
      <category>automation</category>
      <category>linux</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Unleashing DevOps with Automated VM Labs: Vagrant + Libvirt + Ansible 🚀</title>
      <dc:creator>Zoo Codes</dc:creator>
      <pubDate>Sun, 18 Jan 2026 15:10:20 +0000</pubDate>
      <link>https://dev.to/ken_mwaura1/unleashing-devops-with-automated-vm-labs-vagrant-libvirt-ansible-2gmk</link>
      <guid>https://dev.to/ken_mwaura1/unleashing-devops-with-automated-vm-labs-vagrant-libvirt-ansible-2gmk</guid>
      <description>&lt;p&gt;Hello there! 👋&lt;/p&gt;

&lt;p&gt;In this article, I'm going to share a method I've been using to create and manage virtual machine (VM) development and testing environments. By combining Vagrant, Libvirt, and Ansible, we can eliminate the inefficiencies of manual VM setup and finally say goodbye to the "it works on my machine" problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Objectives 🎯
&lt;/h2&gt;

&lt;p&gt;In this walkthrough, we will cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Who this is for:&lt;/strong&gt; Linux users, DevOps engineers, and developers looking to streamline their local lab setup.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What we'll learn:&lt;/strong&gt; How to leverage Vagrant and Libvirt for high-performance local virtualization and Ansible for configuration management.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Goal:&lt;/strong&gt; To create complex, multi-node labs that are consistently configured, fast, and reproducible with single commands.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  I. Introduction: The Problem with Manual VM Setup
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Manual VM Drudgery:&lt;/strong&gt; Traditional VM setup involves tedious GUI installers ("Next, Next, Next").&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Works on My Machine" Syndrome:&lt;/strong&gt; Inconsistent environments lead to arguments and production issues.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Promise of Automation:&lt;/strong&gt; My goal is to create complex, multi-node labs that are consistently configured, fast, and reproducible with single commands.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Solution:&lt;/strong&gt; I'll show you how Vagrant, Libvirt, and Ansible can be the tools to achieve this automation.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  II. The Dream Team: Vagrant &amp;amp; Libvirt Explained
&lt;/h2&gt;

&lt;h3&gt;
  
  
  A. Vagrant: The VM Choreographer
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Definition:&lt;/strong&gt; An open-source abstraction layer that simplifies the building and management of VM environments.&lt;/p&gt;

&lt;h4&gt;
  
  
  Key Benefits
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Consistency:&lt;/strong&gt; Eliminates "works on my machine" issues by using a shared blueprint.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Portability:&lt;/strong&gt; Allows effortless sharing of entire development environments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Isolation:&lt;/strong&gt; Enables running multiple labs concurrently without conflicts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automation:&lt;/strong&gt; Automates environment setup.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Disposability:&lt;/strong&gt; Facilitates easy creation and destruction of labs for experimentation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Production Parity:&lt;/strong&gt; Mirrors real-world setups locally.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Core Concepts
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Vagrantfile&lt;/code&gt;: The declarative script defining the environment.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Boxes&lt;/code&gt;: Pre-built VM images.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Providers&lt;/code&gt;: Underlying virtualization software (VirtualBox, VMware, Libvirt).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Provisioners&lt;/code&gt;: Tools (like Ansible) that configure VMs after they are running.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  B. Libvirt: The Virtualization Maestro
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Definition:&lt;/strong&gt; An open-source virtualization management toolkit that provides a consistent API for interacting with various hypervisors (KVM/QEMU, Xen, VirtualBox).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Function:&lt;/strong&gt; Acts as a translator and single management interface for different virtualization technologies.&lt;/p&gt;

&lt;h4&gt;
  
  
  Key Components
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;libvirtd&lt;/code&gt;: The background daemon managing VMs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Libvirt API:&lt;/strong&gt; The interface for developers.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;virsh&lt;/code&gt;: Command-line interface for direct VM management.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;virt-manager&lt;/code&gt;: Graphical interface for VM management.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Advantages on Linux
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Native Integration:&lt;/strong&gt; Deeply integrated with the Linux operating system.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;KVM Leverage:&lt;/strong&gt; Utilizes Kernel-based Virtual Machine (KVM) for near bare-metal performance.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  C. The Unbeatable Combo: Vagrant + Libvirt
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;vagrant-libvirt&lt;/code&gt; Plugin:&lt;/strong&gt; Enables Vagrant to use Libvirt for managing KVM/QEMU VMs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why it's Important:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Superior Performance on Linux:&lt;/strong&gt; I've found KVM offers significantly better speed and efficiency compared to VirtualBox.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enhanced Control:&lt;/strong&gt; Provides greater control over complex setups.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Freedom from Vendor Lock-in:&lt;/strong&gt; Not tied to proprietary virtualization software.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Performance Differences (Reported):&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Faster startup times (10-30s vs. 15-45s for VirtualBox).&lt;/li&gt;
&lt;li&gt;Better network performance (utilizing &lt;code&gt;virtio_net&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Superior disk I/O.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  III. Back to the Future: A Brief History of Automation
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vagrant's Genesis (2010):&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Started as Mitchell Hashimoto's personal project.&lt;/li&gt;
&lt;li&gt;Reached stable 1.0 release in 2012.&lt;/li&gt;
&lt;li&gt;Became the foundation for HashiCorp.&lt;/li&gt;
&lt;li&gt;Initially focused on VirtualBox, but its plugin architecture allowed for broader provider support.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Libvirt's Legacy (2005):&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Created to manage the growing virtualization landscape.&lt;/li&gt;
&lt;li&gt;Integrated KVM in 2006, solidifying its role.&lt;/li&gt;
&lt;li&gt;Evolved with tools like &lt;code&gt;virt-manager&lt;/code&gt; and advanced networking.&lt;/li&gt;
&lt;li&gt;Reached 1.0.0 release in 2012.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Converging Power:&lt;/strong&gt; Independent development led to synergy, with Vagrant providing orchestration and Libvirt providing performance.&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  IV. The Buzz &amp;amp; The Bumps: Current Community Opinions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  A. The High Fives (Why People Love It)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Blazing Performance (on Linux):&lt;/strong&gt; Libvirt/KVM consistently outperforms VirtualBox, especially for I/O-intensive tasks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Native Linux Feel:&lt;/strong&gt; KVM's integration with the Linux kernel provides a seamless experience.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Advanced Networking:&lt;/strong&gt; Libvirt offers granular control over virtual networks, VLANs, and bridging for complex topologies.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  B. The Head Scratchers (Where It Gets Tricky)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Steeper Learning Curve:&lt;/strong&gt; Libvirt, &lt;code&gt;virsh&lt;/code&gt;, and Linux networking concepts require more effort to master than VirtualBox's GUI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Installation Quirks:&lt;/strong&gt; Configuring &lt;code&gt;vagrant-libvirt&lt;/code&gt; and its dependencies can be challenging due to missing packages or version conflicts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Box Hunting:&lt;/strong&gt; The ecosystem of pre-built Libvirt-specific boxes is smaller than for VirtualBox; conversion tools like &lt;code&gt;vagrant-mutate&lt;/code&gt; may be needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mac Users Beware:&lt;/strong&gt; KVM is not native on macOS (especially Apple Silicon), making Libvirt less ideal; many macOS users opt for QEMU directly.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  C. The Great VirtualBox Debate
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;VirtualBox offers cross-platform ease and a large box library.&lt;/li&gt;
&lt;li&gt;Its Linux performance often requires significant tweaking (NFS for shared folders, virtio NICs) to match Libvirt/KVM.&lt;/li&gt;
&lt;li&gt;VirtualBox's simplicity comes at a performance cost.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  V. Roadblocks &amp;amp; Routers: Common Limitations ("Controversies")
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The "Default Dilemma":&lt;/strong&gt; VirtualBox dominates the pre-built box market, making Libvirt box availability a challenge.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Version Tango:&lt;/strong&gt; Maintaining synchronized versions of Vagrant and the &lt;code&gt;vagrant-libvirt&lt;/code&gt; plugin can be difficult.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network Niggles:&lt;/strong&gt; Configuring private IPs, ensuring synced folders, and resolving Libvirt network access issues can be frustrating for beginners.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The &lt;code&gt;reload&lt;/code&gt; Hang-up:&lt;/strong&gt; &lt;code&gt;vagrant reload&lt;/code&gt; may not always apply Libvirt configuration changes; a full &lt;code&gt;destroy&lt;/code&gt; and &lt;code&gt;up&lt;/code&gt; cycle might be necessary.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One Provider at a Time (Mostly):&lt;/strong&gt; Vagrant typically supports only one active provider (e.g., VirtualBox or Libvirt) unless explicitly managed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IP Address Hide-and-Seek:&lt;/strong&gt; Libvirt lacks a standard IP discovery mechanism, forcing the plugin to use less reliable methods (parsing &lt;code&gt;dnsmasq&lt;/code&gt; logs, QEMU Guest Agent).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  VI. Building a 3-Node Cluster with Vagrant + Libvirt 🛠️
&lt;/h2&gt;

&lt;p&gt;This section provides a practical example of deploying multiple VMs that can communicate, managed by a single &lt;code&gt;Vagrantfile&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The &lt;code&gt;Vagrantfile&lt;/code&gt; Blueprint
&lt;/h3&gt;

&lt;p&gt;Here is a complete &lt;code&gt;Vagrantfile&lt;/code&gt; to set up a 3-node CentOS cluster with a private network.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# -*- mode: ruby -*-&lt;/span&gt;
&lt;span class="c1"&gt;# vi: set ft=ruby :&lt;/span&gt;

&lt;span class="no"&gt;Vagrant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"2"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="c1"&gt;# Global Libvirt Provider Settings&lt;/span&gt;
  &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provider&lt;/span&gt; &lt;span class="ss"&gt;:libvirt&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;libvirt&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;libvirt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;driver&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"kvm"&lt;/span&gt;
    &lt;span class="n"&gt;libvirt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;memory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;
    &lt;span class="n"&gt;libvirt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cpus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="c1"&gt;# Define 3 nodes: node1, node2, node3&lt;/span&gt;
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt; &lt;span class="s2"&gt;"node&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"generic/centos8"&lt;/span&gt;
      &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hostname&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"node&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.cluster.local"&lt;/span&gt;

      &lt;span class="c1"&gt;# Private Network (Libvirt will create a virtual bridge)&lt;/span&gt;
      &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;network&lt;/span&gt; &lt;span class="s2"&gt;"private_network"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="ss"&gt;ip: &lt;/span&gt;&lt;span class="s2"&gt;"192.168.121.1&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="ss"&gt;libvirt__network_name: &lt;/span&gt;&lt;span class="s2"&gt;"vagrant-private-net"&lt;/span&gt;

      &lt;span class="c1"&gt;# Ansible Provisioner&lt;/span&gt;
      &lt;span class="c1"&gt;# automatically installs Ansible on the host if needed (if using 'ansible_local') &lt;/span&gt;
      &lt;span class="c1"&gt;# or runs from the host machine to configure the guest.&lt;/span&gt;
      &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provision&lt;/span&gt; &lt;span class="s2"&gt;"ansible"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;ansible&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="n"&gt;ansible&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;playbook&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"playbook.yml"&lt;/span&gt;
        &lt;span class="n"&gt;ansible&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;become&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
        &lt;span class="n"&gt;ansible&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;limit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"all"&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="c1"&gt;# Simple shell provisioning to update /etc/hosts for basic DNS&lt;/span&gt;
      &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;vm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;provision&lt;/span&gt; &lt;span class="s2"&gt;"shell"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;inline: &lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class="no"&gt;SHELL&lt;/span&gt;&lt;span class="sh"&gt;
        echo "192.168.121.10 node1.cluster.local node1" &amp;gt;&amp;gt; /etc/hosts
        echo "192.168.121.11 node2.cluster.local node2" &amp;gt;&amp;gt; /etc/hosts
        echo "192.168.121.12 node3.cluster.local node3" &amp;gt;&amp;gt; /etc/hosts
&lt;/span&gt;&lt;span class="no"&gt;      SHELL&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Blueprint Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Base Box:&lt;/strong&gt; Uses &lt;code&gt;generic/centos8&lt;/code&gt;, a reliable box for Libvirt.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Provider Config:&lt;/strong&gt; Globally sets KVM driver, 1GB RAM, and 1 CPU per VM to save resources.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Loop Definition:&lt;/strong&gt; Efficiently defines 3 nodes using a Ruby loop.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Networking:&lt;/strong&gt; Assigns static IPs (&lt;code&gt;.10&lt;/code&gt;, &lt;code&gt;.11&lt;/code&gt;, &lt;code&gt;.12&lt;/code&gt;) on a private network.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shell Provisioner:&lt;/strong&gt; rudimentary DNS via &lt;code&gt;/etc/hosts&lt;/code&gt; so nodes can ping each other by name.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The Workflow
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Install Prerequisites:&lt;/strong&gt;&lt;br&gt;
You'll need &lt;code&gt;libvirt&lt;/code&gt; and &lt;code&gt;qemu-kvm&lt;/code&gt; installed on your host system.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Debian/Ubuntu:&lt;/strong&gt; &lt;code&gt;sudo apt install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Fedora/RHEL:&lt;/strong&gt; &lt;code&gt;sudo dnf install @virtualization&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Note:&lt;/em&gt; Ensure your user is in the &lt;code&gt;libvirt&lt;/code&gt; group (e.g., &lt;code&gt;sudo usermod -aG libvirt $USER&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Install the Plugin:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vagrant plugin &lt;span class="nb"&gt;install &lt;/span&gt;vagrant-libvirt
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ensure Libvirt is Active:&lt;/strong&gt; Check with &lt;code&gt;systemctl status libvirtd&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Save the &lt;code&gt;Vagrantfile&lt;/code&gt;:&lt;/strong&gt; Copy the blueprint above into a file named &lt;code&gt;Vagrantfile&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Launch the cluster:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vagrant up &lt;span class="nt"&gt;--provider&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;libvirt
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SSH into a node:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vagrant ssh node1
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Test connectivity:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ping node2.cluster.local
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  VII. Ansible: Your Automation Sidekick
&lt;/h2&gt;

&lt;p&gt;This section details how to use Ansible for idempotent configuration management across the created cluster.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Why Layer Ansible:&lt;/strong&gt; For repeatable configuration, a cornerstone of DevOps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prerequisites:&lt;/strong&gt; Ansible installed, &lt;code&gt;vagrant-libvirt&lt;/code&gt; plugin, and optionally &lt;code&gt;qemu-guest-agent&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  A. Two Paths to Provisioning
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Vagrant's Built-in Ansible Provisioner (Easiest Integration)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Add an &lt;code&gt;ansible&lt;/code&gt; block to the &lt;code&gt;Vagrantfile&lt;/code&gt;, specifying the &lt;code&gt;playbook.yml&lt;/code&gt; (as shown in the blueprint above).&lt;/li&gt;
&lt;li&gt;Set &lt;code&gt;ansible.become = true&lt;/code&gt; for root privileges.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example &lt;code&gt;playbook.yml&lt;/code&gt;:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Save this file in the same directory as your &lt;code&gt;Vagrantfile&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Configure Lab Nodes&lt;/span&gt;
  &lt;span class="na"&gt;hosts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;all&lt;/span&gt;
  &lt;span class="na"&gt;become&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Ensure pkg cache is up to date (CentOS/RHEL)&lt;/span&gt;
      &lt;span class="na"&gt;dnf&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;update_cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yes&lt;/span&gt;
      &lt;span class="na"&gt;when&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ansible_os_family == "RedHat"&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install essential tools&lt;/span&gt;
      &lt;span class="na"&gt;package&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;vim&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;curl&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;git&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;bash-completion&lt;/span&gt;
        &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;present&lt;/span&gt;

    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Add a welcome message to /etc/motd&lt;/span&gt;
      &lt;span class="na"&gt;copy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;------------------------------------------&lt;/span&gt;
          &lt;span class="s"&gt;Welcome to your Automated Vagrant Lab! 🚀&lt;/span&gt;
          &lt;span class="s"&gt;Managed by Ansible.&lt;/span&gt;
          &lt;span class="s"&gt;------------------------------------------&lt;/span&gt;
        &lt;span class="na"&gt;dest&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/etc/motd&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Run &lt;code&gt;vagrant up&lt;/code&gt; or &lt;code&gt;vagrant provision&lt;/code&gt; to apply changes.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  2. External Ansible Control (More Flexibility)
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;After &lt;code&gt;vagrant up&lt;/code&gt;, use &lt;code&gt;vagrant ssh-config&lt;/code&gt; to get VM IPs and SSH keys.&lt;/li&gt;
&lt;li&gt;Create a custom &lt;code&gt;inventory.ini&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;Add your private key to the SSH agent: &lt;code&gt;ssh-add&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run playbooks directly:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ansible-playbook &lt;span class="nt"&gt;-i&lt;/span&gt; inventory.ini your_playbook.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Dynamic Inventory:&lt;/strong&gt; For dynamic Libvirt environments, consider using &lt;code&gt;community.libvirt&lt;/code&gt; for inventory management.&lt;/p&gt;

&lt;h2&gt;
  
  
  VIII. Crystal Ball Gazing: The Future of Automated VM Labs 🔮
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vagrant's Evolution &amp;amp; The Go Rewrite:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;HashiCorp has been working on porting Vagrant to Go (&lt;code&gt;vagrant-go&lt;/code&gt;) to align better with their ecosystem (Terraform, Packer) and improve performance.&lt;/li&gt;
&lt;li&gt;While the "Vagrant 3.0" major release has been a long-term goal, the project continues to evolve with a focus on stability and maintaining the massive ecosystem of existing plugins.&lt;/li&gt;
&lt;li&gt;Expect continued bridging between local development and cloud-native workflows.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Libvirt's Ongoing Evolution:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hypervisor Enhancements:&lt;/strong&gt; Continued improvements for QEMU interactions and support for diverse architectures like ARM64 (vital for running Linux VMs on Apple Silicon, though often via QEMU directly).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network Nirvana:&lt;/strong&gt; Finer control over DNS, VLAN tagging, and high-performance networking improvements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Storage &amp;amp; Devices:&lt;/strong&gt; Better NVMe support and snapshot handling.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;The Broader Landscape of VM Orchestration:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hybrid &amp;amp; Edge:&lt;/strong&gt; Seamless management of VMs from local machines to the cloud and edge devices.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI-Powered Automation:&lt;/strong&gt; AI predicting issues, optimizing resources, and assisting with configuration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;VMs &amp;amp; Containers Integration:&lt;/strong&gt; Blurring lines for integrated management.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developer Delight:&lt;/strong&gt; Tools focused on faster, cloud-native local development environments.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IaC Everywhere:&lt;/strong&gt; Infrastructure as Code becoming standard for all resources.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  IX. Conclusion: Your Labs, Supercharged
&lt;/h2&gt;

&lt;p&gt;I hope this guide helps you supercharge your labs! Vagrant, Libvirt, and Ansible offer a powerful, performant, and reproducible method for building virtual playgrounds, eliminating manual setup inefficiencies.&lt;/p&gt;

&lt;p&gt;Embrace automation to reclaim time and innovate. Experience the magic of automated labs and share your adventures with the community!&lt;/p&gt;

&lt;p&gt;If you have any questions or suggestions, please feel free to comment below or reach out to me on &lt;a href="https://twitter.com/KenMwaura1" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/kennedy-mwaura/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;. You can also check out my other articles on &lt;a href="https://dev.to/ken_mwaura1"&gt;Dev.to&lt;/a&gt;. Thanks for reading!&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%2Fxweh4feca4z1a7k2d27y.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%2Fxweh4feca4z1a7k2d27y.gif" alt="Next-time" width="498" height="206"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Buy Me a &lt;a href="https://ko-fi.com/kenmwaura1" rel="noopener noreferrer"&gt;Coffee&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  References 📚
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.vagrantup.com/docs" rel="noopener noreferrer"&gt;Vagrant Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://libvirt.org/" rel="noopener noreferrer"&gt;Libvirt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.ansible.com/" rel="noopener noreferrer"&gt;Ansible Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>virtualmachine</category>
      <category>automation</category>
      <category>linux</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Zoo Codes</dc:creator>
      <pubDate>Sun, 11 May 2025 09:23:51 +0000</pubDate>
      <link>https://dev.to/ken_mwaura1/-301p</link>
      <guid>https://dev.to/ken_mwaura1/-301p</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/ken_mwaura1/crushing-the-command-line-how-i-used-amazon-q-to-build-a-smarter-fastapi-scaffolder-3c45" class="crayons-story__hidden-navigation-link"&gt;Crushing the Command Line: How I Used Amazon Q to Build a Smarter FastAPI Scaffolder&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="/ken_mwaura1" 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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F292307%2F0269edd6-31aa-4039-afb5-45b176646fd9.png" alt="ken_mwaura1 profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/ken_mwaura1" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Zoo Codes
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Zoo Codes
                
              
              &lt;div id="story-author-preview-content-2475441" 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="/ken_mwaura1" 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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F292307%2F0269edd6-31aa-4039-afb5-45b176646fd9.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Zoo Codes&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/ken_mwaura1/crushing-the-command-line-how-i-used-amazon-q-to-build-a-smarter-fastapi-scaffolder-3c45" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;May 10 '25&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/ken_mwaura1/crushing-the-command-line-how-i-used-amazon-q-to-build-a-smarter-fastapi-scaffolder-3c45" id="article-link-2475441"&gt;
          Crushing the Command Line: How I Used Amazon Q to Build a Smarter FastAPI Scaffolder
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/devchallenge"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;devchallenge&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/awschallenge"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;awschallenge&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/ai"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;ai&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/webdev"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;webdev&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/ken_mwaura1/crushing-the-command-line-how-i-used-amazon-q-to-build-a-smarter-fastapi-scaffolder-3c45" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/raised-hands-74b2099fd66a39f2d7eed9305ee0f4553df0eb7b4f11b01b6b1b499973048fe5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/exploding-head-daceb38d627e6ae9b730f36a1e390fca556a4289d5a41abb2c35068ad3e2c4b5.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;13&lt;span class="hidden s:inline"&gt;&amp;nbsp;reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/ken_mwaura1/crushing-the-command-line-how-i-used-amazon-q-to-build-a-smarter-fastapi-scaffolder-3c45#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;
            4 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>devchallenge</category>
      <category>awschallenge</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Crushing the Command Line: How I Used Amazon Q to Build a Smarter FastAPI Scaffolder</title>
      <dc:creator>Zoo Codes</dc:creator>
      <pubDate>Sat, 10 May 2025 15:06:15 +0000</pubDate>
      <link>https://dev.to/ken_mwaura1/crushing-the-command-line-how-i-used-amazon-q-to-build-a-smarter-fastapi-scaffolder-3c45</link>
      <guid>https://dev.to/ken_mwaura1/crushing-the-command-line-how-i-used-amazon-q-to-build-a-smarter-fastapi-scaffolder-3c45</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/aws-amazon-q-v2025-04-30"&gt;Amazon Q Developer "Quack The Code" Challenge&lt;/a&gt;: Crushing the Command Line.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I created the FastAPI Scaffolder CLI – a zero-config generator for production-ready FastAPI apps. It solves common pain points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🕒 Saves over an hour per project setup.&lt;/li&gt;
&lt;li&gt;🛡️ Bakes in best practices (async DB pools, retry logic, secure defaults).&lt;/li&gt;
&lt;li&gt;☁️ Generates Infrastructure as Code (Terraform/Docker for AWS/Local).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With one command, you get:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;fastapi-scaffold create myapp &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--db&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;postgresql &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--broker&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;redis &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--prod&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;aws
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This generates a directory with all the files you need to get started, including a Dockerfile, docker-compose.yaml, and Terraform files for AWS deployment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Benefits
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;✅ Simplifies database and configuration setup with auto-generated async SQLAlchemy/Motor integrations.&lt;/li&gt;
&lt;li&gt;✅ Production-ready: Includes Terraform, Docker Compose, and monitoring tools.&lt;/li&gt;
&lt;li&gt;✅ Flexible and fast: Designed to be less opinionated while still providing a solid foundation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Existing scaffolding tools like the official &lt;a href="https://github.com/fastapi/full-stack-fastapi-template" rel="noopener noreferrer"&gt;FastAPI template&lt;/a&gt; often lack production readiness or are too rigid. This tool is built to be both flexible and easy to use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;The scaffolder supports:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🛢️ Multiple databases: PostgreSQL, MongoDB, SQLite.&lt;/li&gt;
&lt;li&gt;💬 Message brokers: Redis, RabbitMQ.&lt;/li&gt;
&lt;li&gt;📦 Deployment options: Minimal, Full (AWS ECS), Serverless.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let me walk you through a typical workflow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Install the CLI:&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;   uv pip &lt;span class="nb"&gt;install &lt;/span&gt;scaffold-fastapi
&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%2Fd1fr3i2lf0f77f84ulrk.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%2Fd1fr3i2lf0f77f84ulrk.png" alt="Package installation" width="800" height="848"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run the scaffolder command:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   scaffold-fastapi customer-api &lt;span class="nt"&gt;--db&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;postgresql &lt;span class="nt"&gt;--broker&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;redis &lt;span class="nt"&gt;--stack&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;full
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OR just pass the name of the app to see the default options:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   scaffold-fastapi customer-api
&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%2Fhsxq5svpty6rvd00q9d2.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%2Fhsxq5svpty6rvd00q9d2.png" alt="Choosing options" width="800" height="301"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Generated files:&lt;/strong&gt;
The tool generates a complete project structure:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── app/
│   ├── api/
│   │   └── v1/
│   ├── core/
│   ├── db/
│   ├── models/
│   └── main.py
├── tasks/
│   ├── celery_app.py
│   └── sample_tasks.py
├── infra/
│   ├── docker/
│   ├── terraform/
│   └── helm/
├── Dockerfile
└── docker-compose.yml
&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%2Fx02990s9vgc1cpdg4j1z.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%2Fx02990s9vgc1cpdg4j1z.png" alt="generated files" width="800" height="927"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Run the app:&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;cd &lt;/span&gt;customer-api
   docker-compose up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Access the API:&lt;/strong&gt;
Open your browser and navigate to &lt;code&gt;http://localhost:8000/docs&lt;/code&gt; to see the auto-generated API documentation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Run the Celery worker:&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;   docker-compose run &lt;span class="nt"&gt;--rm&lt;/span&gt; worker
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Your FastAPI application is now running with:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;PostgreSQL database with async connection pool&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Redis for caching and message brokering&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Celery worker for background tasks&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Health check endpoints&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;API documentation at /api/v1/docs&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you're ready to deploy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;infra/terraform
terraform init
terraform apply
&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%2F6w8o166hvk4v5sffa82u.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%2F6w8o166hvk4v5sffa82u.gif" alt="Scaffold Showcase" width="600" height="322"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Project Structure
&lt;/h3&gt;

&lt;p&gt;The scaffolder itself is organized into modular generators:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;scaffold-fastapi/
├── scaffold_fastapi/
│   ├── generators/
│   │   ├── app.py       &lt;span class="c"&gt;# FastAPI application files&lt;/span&gt;
│   │   ├── celery.py    &lt;span class="c"&gt;# Celery task configuration&lt;/span&gt;
│   │   ├── docker.py    &lt;span class="c"&gt;# Docker and docker-compose files&lt;/span&gt;
│   │   ├── env.py       &lt;span class="c"&gt;# Environment variable files&lt;/span&gt;
│   │   └── terraform.py &lt;span class="c"&gt;# AWS deployment files&lt;/span&gt;
│   └── __init__.py
├── cli.py               &lt;span class="c"&gt;# CLI entrypoint&lt;/span&gt;
└── pyproject.toml
├── README.md
├── LICENSE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Code Repository
&lt;/h2&gt;

&lt;p&gt;The complete code is available on GitHub: &lt;a href="https://github.com/KenMwaura1/scaffold-fastapi" rel="noopener noreferrer"&gt;scaffold-fastapi&lt;/a&gt;. The repository includes detailed instructions and examples of the generated code.&lt;/p&gt;

&lt;p&gt;The package is also available on PyPI: &lt;a href="https://pypi.org/project/scaffold-fastapi/" rel="noopener noreferrer"&gt;scaffold-fastapi&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Used Amazon Q Developer
&lt;/h2&gt;

&lt;p&gt;Amazon Q Developer was the secret weapon that made this project possible. Here's how it helped:&lt;/p&gt;

&lt;h3&gt;
  
  
  Initial Concept and Planning
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Defining the scope:&lt;/strong&gt; Amazon Q helped identify the most valuable features for a FastAPI scaffolder, such as database support, message broker integration, and deployment options.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Designing the CLI interface:&lt;/strong&gt; It suggested using Typer for a clean, intuitive command-line experience.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Planning the project structure:&lt;/strong&gt; Amazon Q provided best practices for organizing FastAPI projects, including separating concerns and using async database connections.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generating code snippets:&lt;/strong&gt; It created boilerplate code for components like async database setup, Celery configuration, and Docker files.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Rapid Prototyping
&lt;/h3&gt;

&lt;p&gt;Amazon Q accelerated development by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Implementing the CLI:&lt;/strong&gt; It generated the core CLI logic with proper argument handling and validation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Creating generator modules:&lt;/strong&gt; Each component had its own generator function, producing well-structured, idiomatic code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Debugging and Refinement
&lt;/h3&gt;

&lt;p&gt;Amazon Q was invaluable for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Troubleshooting:&lt;/strong&gt; It helped resolve Docker Compose networking issues.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Code optimization:&lt;/strong&gt; Suggestions improved efficiency and maintainability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Feature expansion:&lt;/strong&gt; New features were implemented cleanly with its guidance.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Packaging and Distribution
&lt;/h3&gt;

&lt;p&gt;Amazon Q assisted in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Creating the &lt;code&gt;pyproject.toml&lt;/code&gt; file:&lt;/strong&gt; It generated a well-structured configuration for packaging and dependencies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Setting up the CLI entry point:&lt;/strong&gt; It provided the necessary boilerplate for Typer to work seamlessly with the package.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Writing documentation:&lt;/strong&gt; It helped draft the README and usage instructions, ensuring clarity for users.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Creating a license file:&lt;/strong&gt; It suggested using the MIT license, which is widely accepted and easy to understand.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Creating Github Actions CI/CD workflows:&lt;/strong&gt; It generated a basic CI/CD pipeline for testing and deploying the scaffolder.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Creating a Dockerfile:&lt;/strong&gt; It generated a Dockerfile for the CLI tool, making it easy to run in a containerized environment.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Find more about the packaging process in the packaging guide.md and packaging-and-dist.md&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Start with clear requirements:&lt;/strong&gt; The more specific your initial prompt, the better the results.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Iterative development:&lt;/strong&gt; Break complex tasks into smaller chunks and refine incrementally.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collaborative problem-solving:&lt;/strong&gt; Treat Amazon Q as a pair programming partner, not just a code generator.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Impact and Future Plans
&lt;/h2&gt;

&lt;p&gt;This scaffolder has already saved me countless hours. What used to take a full day now takes minutes. The generated code is robust and follows best practices.&lt;/p&gt;

&lt;h3&gt;
  
  
  Future Enhancements
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Support for more databases like CockroachDB and DynamoDB.&lt;/li&gt;
&lt;li&gt;Authentication templates for OAuth, JWT, and API keys.&lt;/li&gt;
&lt;li&gt;Testing frameworks with pytest fixtures and example tests.&lt;/li&gt;
&lt;li&gt;CI/CD templates for GitHub Actions and AWS CodePipeline.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Amazon Q Developer has transformed how I approach development. It's not just about writing code faster—it's about writing better code with fewer bugs and better architecture. This FastAPI scaffolder is just one example of how Amazon Q can help developers build smarter tools.&lt;/p&gt;

&lt;p&gt;If you're building CLI tools or automation scripts, I highly recommend leveraging Amazon Q Developer. Start with a clear vision, break down the problem, and let Amazon Q help you implement the solution.&lt;/p&gt;

&lt;p&gt;I hope you have enjoyed this article. If you have any questions, please feel free to reach out to me on &lt;a href="https://twitter.com/KenMwaura1" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;. or &lt;a href="https://www.linkedin.com/in/kennedy-mwaura/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;. You can also check out my other articles on &lt;a href="https://dev.to/ken_mwaura1"&gt;Dev.to&lt;/a&gt;. Thanks for reading!&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>awschallenge</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Nested Virtualization using VMware Workstation, Esxi and Windows 10 on Linux - Part 1</title>
      <dc:creator>Zoo Codes</dc:creator>
      <pubDate>Thu, 16 Jan 2025 07:31:01 +0000</pubDate>
      <link>https://dev.to/ken_mwaura1/nested-virtualization-using-vmware-workstation-esxi-and-windows-10-on-linux-part-1-3oc4</link>
      <guid>https://dev.to/ken_mwaura1/nested-virtualization-using-vmware-workstation-esxi-and-windows-10-on-linux-part-1-3oc4</guid>
      <description>&lt;p&gt;Happy new year all 🎉, It's been a while since my last post. I am currently enrolled in a full-time course hence the lack of time. However, I'll try to do better in regards to getting a schedule in place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Recently, we were tasked with setting up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Domain controller vm.&lt;/li&gt;
&lt;li&gt;Web-server vm.
both using Windows Server 2016 running on VMWare ESXi. Also:&lt;/li&gt;
&lt;li&gt;Two windows 10 clients.&lt;/li&gt;
&lt;li&gt;All of the above running on VMWare Workstation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following were additional requirements for the above project:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;All the clients enrolled into the Domain.&lt;/li&gt;
&lt;li&gt;A static site hosted on the web server vm.&lt;/li&gt;
&lt;li&gt;The static site should be accessible on all clients through a custom URL.&lt;/li&gt;
&lt;li&gt;Create 4 Organisational Units with two users each able to access the client VMS.&lt;/li&gt;
&lt;li&gt;DNS server running on the domain controller.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;For anyone looking to replicate this project, the following are required:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A laptop/desktop with  a 64-bit operating system (either Windows or Linux).&lt;/li&gt;
&lt;li&gt;Atleast 16GB of RAM.&lt;/li&gt;
&lt;li&gt;256GB of storage or more (preferrably an SSD).&lt;/li&gt;
&lt;li&gt;Atleast 4 cores with virtualization enabled(check your BIOS options).&lt;/li&gt;
&lt;li&gt;A browser.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Why not Use QEMU/KVM?
&lt;/h3&gt;

&lt;p&gt;As a fellow Linux enthuasist (I use Arch btw), I can already hear the furious keyboard typing about using  QEMU/KVM. I use it to host my Windows 11 VM with GPU Passthrough for gaming and 3D tasks. I might write about it eventually.&lt;/p&gt;

&lt;p&gt;While I agree that QEMU/KVM is a great tool, I ran into a major issue after setting up the above project. This relating to networking, I couldn't for the life of me get the  networking to work properly inside ESXi. I tried setting up a bridge, setting up a virtual network, and even  setting up a virtual switch. Nothing seemed to work. I was about to give up when I decided to use VMware workstation.&lt;/p&gt;

&lt;p&gt;Yes, its probably a skill issue on my end but I was able to get everything working with VMware workstation in a matter of hours.If you're able to replicate this setup, kindly let me know. I'd love to  know how you did it. All that side, lets get to it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Overview
&lt;/h2&gt;

&lt;p&gt;The diagram below provides an overview of the project:&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%2F3nug9pnyv9zam52gf2by.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%2F3nug9pnyv9zam52gf2by.png" alt="overview" width="800" height="356"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we're setting up a Type 2 Hypervisor (VMware Workstation) on a Linux Host then installing three Virtual Machines:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Type 1 HyperVisor(VMWare ESXi) -&amp;gt; inside we'll have 2 VMs:
a.  Domain Controller (Windows Server 2016)
b.  Web Server (Windows Server 2016)&lt;/li&gt;
&lt;li&gt;Windows 10 client 1&lt;/li&gt;
&lt;li&gt;Windows 10 client 2&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The diagram below showcases a high-level view of the Virtual Machines:&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%2Fjk8yicuyzedcmi7spq41.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%2Fjk8yicuyzedcmi7spq41.png" alt="project diagram" width="800" height="842"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up VMware Workstation on Linux
&lt;/h2&gt;

&lt;p&gt;VMware  Workstation is a Type 2 Hypervisor that allows you to run multiple virtual machines on a single host. Following the acquisition by Broadcom, there was alot  of uncertainty about the future of VMware Workstation. However, they now offer a &lt;a href="https://blogs.vmware.com/workstation/2024/05/vmware-workstation-pro-now-available-free-for-personal-use.html" rel="noopener noreferrer"&gt;free license for Personal use for Workstation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To get started, follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Download the VMware Workstation installer from the official VMware website. Check the appropriate version for Linux.&lt;/li&gt;
&lt;li&gt;Log in to the Linux host with the user account that you plan to use with VMware Workstation.&lt;/li&gt;
&lt;li&gt;Open a terminal interface. For more information, see&amp;nbsp;&lt;a href="https://kb.vmware.com/s/article/1003892" rel="noopener noreferrer"&gt;Opening a command or shell prompt (1003892)&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Change to root. For example:
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;su root&lt;/code&gt;  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The command that you use depends on your Linux distribution and configuration.  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Change directories to the directory that contains the VMware Workstation bundle installer file. The default location is the&amp;nbsp;&lt;strong&gt;Download&lt;/strong&gt;&amp;nbsp;directory.&lt;/li&gt;
&lt;li&gt;Check if you have the &lt;code&gt;/etc/init.d&lt;/code&gt; directory, if not create it before running the installer.
&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 mkdir&lt;/span&gt; /etc/init.d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Run the appropriate Workstation installer file for the host system.  &lt;/p&gt;

&lt;p&gt;For example:  &lt;/p&gt;

&lt;p&gt;&lt;code&gt;sh VMware-workstation-Full-_xxxx-xxxx_._architecture_.bundle [--_option]_&lt;/code&gt;  &lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;xxxx-xxxx&lt;/em&gt;&amp;nbsp;is the version and build numbers&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;architecture&lt;/code&gt;&amp;nbsp;is&amp;nbsp;&lt;code&gt;i386&lt;/code&gt;&amp;nbsp;or&amp;nbsp;&lt;code&gt;x86_64&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;_option_&lt;/code&gt;&amp;nbsp;is a command line option.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For further information, check the &lt;a href="https://knowledge.broadcom.com/external/article/344595/downloading-and-installing-vmware-workst.html" rel="noopener noreferrer"&gt;linux install docs&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Arch-Linux install
&lt;/h3&gt;

&lt;p&gt;VMware relies on compiling it's own kernel modules, due to the bleeding edge nature of Arch -Linux, you may need to compile your own kernel modules. Incase you run into the following error:&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%2F8eoiq60i047820w57o8v.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%2F8eoiq60i047820w57o8v.png" alt="First run" width="525" height="198"&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%2Fjpfsos76cq12f9o4t8nj.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%2Fjpfsos76cq12f9o4t8nj.png" alt="kernel error" width="489" height="330"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a well-known issue with running VMware on Linux - compiling your own kernel modules. This isn't much of a problem for seasoned users but for others it might be a deal breaker. This &lt;a href="https://github.com/mkubecek/vmware-host-modules" rel="noopener noreferrer"&gt;repo&lt;/a&gt; will save you hours of searching google.&lt;/p&gt;

&lt;p&gt;On Arch you can install VMware Workstation on Arch-Linux using the AUR or Chaotic AUR:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install yay
&lt;/li&gt;
&lt;/ul&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;pacman &lt;span class="nt"&gt;-S&lt;/span&gt; yay
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Ensure all packages are up too date by running&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yay
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install VMware  Workstation&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  yay &lt;span class="nt"&gt;-S&lt;/span&gt; vmware-workstation
&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%2Fsorzs7hj4ba7bokyiba4.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%2Fsorzs7hj4ba7bokyiba4.png" alt="yay running" width="800" height="208"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Once completed launch using your application or run the following command in the terminal:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vmware
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In-case you have an issue with the networking or get an error pop-up, start as root:&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;vmware
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Running ESXi on VMWare
&lt;/h2&gt;

&lt;p&gt;Download the ESXi iso from the &lt;a href="https://support.broadcom.com/group/ecx/productdownloads?subfamily=VMware+vSphere&amp;amp;tab=Products" rel="noopener noreferrer"&gt;Broadcom website&lt;/a&gt;, the latest version is 8. However if your hardware is not compatible with the latest version, you can download version 7 &lt;a href="https://archive.org/details/vmware-esxi-7" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Installation is similar other VMs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a New Virtual Machine.&lt;/li&gt;
&lt;li&gt;Use the Typical Configuration.&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%2Fzgtw7kxurnf0r5003t04.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%2Fzgtw7kxurnf0r5003t04.png" alt="Installer-1" width="788" height="698"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Select the ESXi iso.&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%2Femsivzo1tqm5t6nc7dl6.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%2Femsivzo1tqm5t6nc7dl6.png" alt="Installer-2" width="787" height="707"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Choose the location to save the VM files.&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%2F7avh3yfaf987cyremhmy.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%2F7avh3yfaf987cyremhmy.png" alt="Installer-3" width="784" height="700"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Enter the Maximum disk size. In my case I used 60GB (Note the recommended is 142GB).&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%2F4gubvvk9nqndqk5oira7.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%2F4gubvvk9nqndqk5oira7.png" alt="Installer-5" width="778" height="695"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Lets Customize the Hardware options:
i.  Change the allocated memory to 16GB.(Adjust according to your host specifications).
ii. Change the CPU cores to 12.
iii. Change the Network Adapter to Custom. I'm using &lt;code&gt;/dev/vmnet8&lt;/code&gt;. (This is important for connecting the client VMs)&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%2Frd4zczs3ehqw1t1yjxjq.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%2Frd4zczs3ehqw1t1yjxjq.png" alt="Installer-6" width="800" height="645"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Finish the setup and power on the VM.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Installing ESXi
&lt;/h3&gt;

&lt;p&gt;Once Esxi powers on, you'll be greeted with the following screen: &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%2Fn8dk8jkgz45dj9j53jr4.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%2Fn8dk8jkgz45dj9j53jr4.png" alt="esxi-1" width="800" height="590"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Press Enter to continue, next, you'll be prompted to accept the EULA, press F11 to accept and continue.&lt;/p&gt;

&lt;p&gt;The next screen will prompt you to select the disk to install ESXi on. Select the disk and press Enter. &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%2Fy6ulikuo2g4e5kv3lcql.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%2Fy6ulikuo2g4e5kv3lcql.png" alt="esxi-2" width="800" height="668"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You'll be prompted to enter a password for the root account. Enter the password and press Enter.&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%2Fl4bjuuuvk0wlsjnaqf6g.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%2Fl4bjuuuvk0wlsjnaqf6g.png" alt="esxi-3" width="728" height="640"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally you'll be prompted to press F11 confirm Installation of ESXi. Press F11 to install ESXi.&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%2F9nzmbiaqovdri6o7i5wd.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%2F9nzmbiaqovdri6o7i5wd.png" alt="esxi-4" width="784" height="708"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the installation is complete, you'll be prompted to remove the installation media. Press Enter to reboot 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.amazonaws.com%2Fuploads%2Farticles%2F3u21wdulix9drl8av0gz.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%2F3u21wdulix9drl8av0gz.png" alt="esxi-5" width="728" height="702"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the system reboots, you'll be greeted with the following screen once booting is complete:&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%2Fews9cgpu2222cgmvi8cp.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%2Fews9cgpu2222cgmvi8cp.png" alt="Esxi-running" width="800" height="597"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: your IP address will be displayed on the screen. You can access the ESXi web interface by entering the IP address in your browser. &lt;br&gt;
Due to SSL issues, you'll get a warning, click on advanced and proceed.&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%2F8ubcplgi4a5yftan8xz1.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%2F8ubcplgi4a5yftan8xz1.png" alt="Firefox" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The login screen will be displayed, enter the root username and password you created during installation.&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%2Fbb5jce5dfwkvph580bda.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%2Fbb5jce5dfwkvph580bda.png" alt="login" width="778" height="742"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You'll be greeted with the following screen:&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%2Fs3oofunrg31lulxgvtzq.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%2Fs3oofunrg31lulxgvtzq.png" alt="esxi-main" width="800" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuring a new datastore
&lt;/h3&gt;

&lt;p&gt;Before we can create new VMs, we need to create a new datastore in Esxi. But we need to first add a storage device to the VM in VMware Workstation.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open VMware Workstation and select the ESXi VM.&lt;/li&gt;
&lt;li&gt;Click on Edit virtual machine settings.&lt;/li&gt;
&lt;li&gt;Click on Add.&lt;/li&gt;
&lt;li&gt;Select Hard Disk and click Next.&lt;/li&gt;
&lt;li&gt;Select SATA and click Next. If you have m.2 or NVMe drives, select the appropriate option.&lt;/li&gt;
&lt;li&gt;Set the disk size to 60GB and click Next.  (Note: You can adjust the size according to your needs).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Boot the VM and login to the ESXi web interface. Click on the &lt;em&gt;storage&lt;/em&gt; tab &amp;gt; &lt;strong&gt;Adapters&lt;/strong&gt; and you'll see the new storage device.&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%2Fzk7s8oukyp2b5v3vnaoa.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%2Fzk7s8oukyp2b5v3vnaoa.png" alt="storage" width="800" height="142"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we can create a new datastore:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click on the &lt;strong&gt;Datastores&lt;/strong&gt; tab.&lt;/li&gt;
&lt;li&gt;Click on &lt;strong&gt;New Datastore&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%2F8a41k8i3ao7mou8u803f.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%2F8a41k8i3ao7mou8u803f.png" alt="datastore-1" width="800" height="499"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Select &lt;strong&gt;Create a new VMFS datastore&lt;/strong&gt; and click Next.&lt;/li&gt;
&lt;li&gt;Select the storage device and click Next.&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%2F5llm90hcw7khmbs4jhf5.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%2F5llm90hcw7khmbs4jhf5.png" alt="datastore-2" width="800" height="509"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Enter a name for the datastore and click Next.&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Use full disk&lt;/strong&gt; and click Next.&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%2Fmoaydhyfpcy05t96647b.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%2Fmoaydhyfpcy05t96647b.png" alt="datastore-3" width="800" height="506"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Confirm the settings and click Finish.&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%2Fw4p95y7y7m2jzlruheg6.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%2Fw4p95y7y7m2jzlruheg6.png" alt="datastore-4" width="800" height="508"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The new datastore will be created.&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%2F7k03uk5vos0rz45n8ysm.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%2F7k03uk5vos0rz45n8ysm.png" alt="datastore-5" width="800" height="271"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this Part 1 of the series, we've covered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Setting up VMware Workstation on Linux.&lt;/li&gt;
&lt;li&gt;Installing ESXi on VMware Workstation.&lt;/li&gt;
&lt;li&gt;Configuring a new datastore in ESXi.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the next part, we'll cover:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating a new VM in ESXi.&lt;/li&gt;
&lt;li&gt;Installing Windows Server 2016 on the new VM.&lt;/li&gt;
&lt;li&gt;Configuring the Domain Controller and Web Server VMs.&lt;/li&gt;
&lt;li&gt;Setting up the Windows 10 clients.&lt;/li&gt;
&lt;li&gt;Enrolling the clients into the Domain.&lt;/li&gt;
&lt;li&gt;Setting up the DNS server on the Domain Controller.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Stay tuned for Part 2. Feel free to ask any questions or provide feedback. I'll be happy to help. Happy learning!&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.vmware.com/en/VMware-Workstation-Pro/index.html" rel="noopener noreferrer"&gt;VMware Workstation Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.vmware.com/en/VMware-vSphere/index.html" rel="noopener noreferrer"&gt;VMware ESXi Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blogs.vmware.com/workstation/2024/05/vmware-workstation-pro-now-available-free-for-personal-use.html" rel="noopener noreferrer"&gt;VMware Workstation Free License&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://knowledge.broadcom.com/external/article/344595/downloading-and-installing-vmware-workst.html" rel="noopener noreferrer"&gt;VMware Workstation Linux Install&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>linux</category>
      <category>virtualmachine</category>
      <category>tutorial</category>
      <category>learning</category>
    </item>
    <item>
      <title>28 Common Linux 🐧Questions And Answers 🖥️</title>
      <dc:creator>Zoo Codes</dc:creator>
      <pubDate>Thu, 21 Nov 2024 20:33:41 +0000</pubDate>
      <link>https://dev.to/ken_mwaura1/linux-answers-pbb</link>
      <guid>https://dev.to/ken_mwaura1/linux-answers-pbb</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Welcome to the friendly world of Linux! If you’re curious about how this powerful operating system works, you’ve come to the right place. This article is packed with common questions and easy-to-understand answers that will help you get started with Linux. &lt;/p&gt;

&lt;p&gt;Whether you’re a complete beginner or just looking to brush up on your skills, we’ve got you covered. From the basics to everyday commands, this guide will walk you through everything you need to know to feel comfortable using Linux. Let’s embark on this exciting journey together!&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Linux Questions &amp;amp; Answers
&lt;/h2&gt;

&lt;p&gt;1.&amp;nbsp;&lt;strong&gt;What are the primary purposes and key features of an operating system, particularly Linux?&lt;/strong&gt; The primary purpose of an operating system (OS) like Linux is to manage hardware resources and provide a user interface for interaction. Key features of Linux include multitasking, multi-user capabilities, security through user permissions, and a powerful command-line interface. Additionally, Linux is open-source, which allows for customization and community-driven development.&lt;/p&gt;

&lt;p&gt;2.&amp;nbsp;&lt;strong&gt;Describe the origins and development of the Linux operating system.&lt;/strong&gt; Linux was created by Linus Torvalds in 1991 as a free and open-source alternative to UNIX. It started as a personal project but quickly gained popularity among developers and enthusiasts. Over the years, many distributions (distros) have been developed, each tailored for different needs, such as Ubuntu for ease of use and Fedora for cutting-edge features. The collaborative nature of its development has led to a robust and secure operating system.&lt;/p&gt;

&lt;p&gt;3.&amp;nbsp;&lt;strong&gt;What are the best practices for installing Fedora Linux?&lt;/strong&gt;&amp;nbsp;When installing Fedora, I've found that it's important to back up any important data, ensure that your hardware is compatible, and create a bootable USB drive with the Fedora ISO. During installation, I recommend choosing the custom partitioning option if you're familiar with disk management, and to keep the system updated regularly using the package manager to avoid security vulnerabilities.&lt;/p&gt;

&lt;p&gt;4.&amp;nbsp;&lt;strong&gt;Explain how to interact with a Linux system using a terminal and basic shell commands.&lt;/strong&gt;&amp;nbsp;Interacting with Linux through the terminal is a powerful way to perform tasks. Basic shell commands include &lt;em&gt;ls&lt;/em&gt; to list files, &lt;em&gt;cd&lt;/em&gt;&amp;nbsp;to change directories, &lt;em&gt;cp&lt;/em&gt; to copy files, and &lt;em&gt;rm&lt;/em&gt;&amp;nbsp;to remove files. Using the &lt;em&gt;man&lt;/em&gt;&amp;nbsp;command (e.g., &lt;em&gt;man ls&lt;/em&gt;) can provide detailed information about any command, which is incredibly helpful for learning.&lt;/p&gt;

&lt;p&gt;5.&amp;nbsp;&lt;strong&gt;Describe the purpose of TCP/IP protocol and how it is configured in Linux.&lt;/strong&gt; TCP/IP is the fundamental protocol suite for networking, allowing different devices to communicate over the internet. In Linux, you can configure TCP/IP settings through configuration files like &lt;code&gt;/etc/sysconfig/network-scripts/ifcfg-eth0&lt;/code&gt;&amp;nbsp;for static IP addresses or use the &lt;code&gt;nmcli&lt;/code&gt; command for managing network connections via &lt;em&gt;NetworkManager&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;6.&amp;nbsp;&lt;strong&gt;How do you configure a network interface card (NIC) in Linux?&lt;/strong&gt; To configure a NIC in Linux, I usually edit the network configuration files or use the &lt;code&gt;ip&lt;/code&gt; command. For example, I can set a static IP by editing &lt;code&gt;/etc/network/interfaces&lt;/code&gt; or using &lt;code&gt;nmcli&lt;/code&gt; for NetworkManager-managed connections. After making changes, I restart the networking service using &lt;code&gt;systemctl restart NetworkManager.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;7.&amp;nbsp;&lt;strong&gt;What are the key aspects of printer, log file, and user administration in Linux?&lt;/strong&gt;&amp;nbsp;Printer administration involves configuring printers using CUPS (Common Unix Printing System), where you can add, manage, and troubleshoot printers through a web interface. Log file management is crucial for system monitoring; log files located in &lt;code&gt;/var/log/&lt;/code&gt; provide insights into system performance and errors. User administration includes adding/removing users with commands like &lt;code&gt;useradd&lt;/code&gt; and &lt;code&gt;userdel&lt;/code&gt;, and managing permissions with &lt;code&gt;chmod&lt;/code&gt;&amp;nbsp;and &lt;code&gt;chown&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;8.&amp;nbsp;&lt;strong&gt;How do you navigate the Linux directory structure using relative and absolute pathnames?&lt;/strong&gt; Navigating the Linux directory structure can be done using both relative and absolute pathnames. An absolute pathname starts from the root directory (e.g., &lt;code&gt;/home/user/documents&lt;/code&gt;), while a relative pathname starts from the current directory (e.g., &lt;code&gt;documents&lt;/code&gt; if I’m already in &lt;code&gt;/home/user&lt;/code&gt;). Using &lt;code&gt;cd&lt;/code&gt; to change directories and &lt;code&gt;pwd&lt;/code&gt; to print the current directory helps me keep track of where I am.&lt;/p&gt;

&lt;p&gt;9.&amp;nbsp;&lt;strong&gt;Explain the use of shell wildcards in specifying filenames in Linux&lt;/strong&gt;. Shell wildcards are incredibly useful for matching filenames. For example, * matches any number of characters (e.g., &lt;code&gt;*.txt&lt;/code&gt; matches all text files), while ? matches a single character (e.g., &lt;code&gt;file?.txt&lt;/code&gt; matches file1.txt, file2.txt, etc.). Using wildcards saves time when working with multiple files.&lt;/p&gt;

&lt;p&gt;10.&amp;nbsp;&lt;strong&gt;Describe the major features of the BASH shell, including redirection and piping.&lt;/strong&gt;&amp;nbsp;Redirection allows me to send output from a command to a file using &amp;gt; (e.g., &lt;code&gt;ls &amp;gt; filelist.txt&lt;/code&gt;) or read input from a file using &amp;lt;. Piping (|) lets me chain commands together, so I can use the output of one command as the input for another (e.g., &lt;code&gt;ls | grep txt&lt;/code&gt;&amp;nbsp;to list only text files).&lt;/p&gt;

&lt;p&gt;11.&amp;nbsp;&lt;strong&gt;How do you create and execute basic shell scripts in Linux?&lt;/strong&gt; Creating a shell script is straightforward. I usually start by opening a text editor (like &lt;code&gt;nano&lt;/code&gt; or &lt;code&gt;vim&lt;/code&gt;), then I write my script starting with the shebang line &lt;code&gt;#!/bin/bash&lt;/code&gt;&amp;nbsp;to specify the interpreter. After writing the commands I want to execute, I save the file with a &lt;code&gt;.sh&lt;/code&gt;&amp;nbsp;extension. To execute the script, I need to make it executable using &lt;code&gt;chmod +x script.sh&lt;/code&gt;, and then I can run it with &lt;code&gt;./script.sh&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;12.&amp;nbsp;&lt;strong&gt;What are the types of hardware typically found in server systems and how are they configured in Linux?&lt;/strong&gt; Server systems typically include components like CPUs, RAM, storage drives (HDDs/SSDs), network interface cards (NICs), and sometimes specialized hardware like RAID controllers. In Linux, hardware configuration can be done through various commands like &lt;code&gt;lspci&lt;/code&gt; to list PCI devices, &lt;code&gt;lsblk&lt;/code&gt; to view block devices, and configuring storage through tools like &lt;code&gt;fdisk&lt;/code&gt; or &lt;code&gt;parted&lt;/code&gt;. Additionally, server settings can be managed through configuration files and system utilities.&lt;/p&gt;

&lt;p&gt;13.&amp;nbsp;&lt;strong&gt;Explain the RAID levels and their configurations in Linux.&lt;/strong&gt; RAID (Redundant Array of Independent Disks) levels include RAID 0 (striping, no redundancy), RAID 1 (mirroring, redundancy), RAID 5 (striping with parity), and RAID 10 (combination of striping and mirroring). In Linux, I can configure RAID using the mdadm tool, which allows me to create and manage software RAID arrays. For example, to create a RAID 1 array, I'd use a command like &lt;code&gt;mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sda /dev/sdb.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;14.&amp;nbsp;&lt;strong&gt;Summarize the major steps necessary to boot a Linux system.&lt;/strong&gt; Booting a Linux system generally involves several key steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;BIOS/UEFI Initialization: The system firmware initializes hardware and performs a POST (Power-On Self-Test).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bootloader Execution: The bootloader (like GRUB) is loaded from the boot sector, which then presents options for booting different kernels or operating systems.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Kernel Loading: The selected kernel is loaded into memory, and the initial RAM disk (initrd) is also loaded if necessary.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;System Initialization: The kernel initializes system hardware and mounts the root filesystem.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Init System: The init system (like systemd) is started, which then launches system services and user sessions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;15.&lt;strong&gt;How do you configure the system to start and stop daemons at certain run levels or targets?&lt;/strong&gt; In Linux, particularly with &lt;em&gt;systemd&lt;/em&gt;, services (or daemons) are managed through units. To enable a service to start at boot, I can use &lt;code&gt;systemctl enable service_name&lt;/code&gt;, and to disable it, &lt;code&gt;systemctl disable service_name&lt;/code&gt;. To start or stop a service manually, I can use&lt;code&gt;systemctl start service_name&lt;/code&gt; or &lt;code&gt;systemctl stop service_name&lt;/code&gt;. For configuring specific targets, I can use &lt;code&gt;systemctl isolate target_name&lt;/code&gt;to switch to a specific run level or target.&lt;/p&gt;

&lt;p&gt;16.&lt;strong&gt;What is the Filesystem Hierarchy Standard in Linux?&lt;/strong&gt; The Filesystem Hierarchy Standard (FHS) defines the directory structure and directory contents in Linux systems. It specifies that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ] the root directory (/) is the top-level directory.&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;/bin&lt;/code&gt; for essential binaries,&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;/etc&lt;/code&gt; for configuration files,&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;/home&lt;/code&gt; for user home directories,&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;/var&lt;/code&gt; for variable data,&lt;/li&gt;
&lt;li&gt;[ ] &lt;code&gt;/usr&lt;/code&gt; for user programs and data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This standardization helps ensure consistency across different Linux distributions.&lt;/p&gt;

&lt;p&gt;17.&lt;strong&gt;Explain how to manage file and directory permissions in Linux&lt;/strong&gt;. In Linux, file and directory permissions are managed using the &lt;code&gt;chmod&lt;/code&gt;, &lt;code&gt;chown&lt;/code&gt;, and &lt;code&gt;chgrp&lt;/code&gt; commands. Permissions are represented in three categories: owner, group, and others, with read (r), write (w), and execute (x) permissions. For example, to give the owner read and write permissions, I would use &lt;code&gt;chmod u+rw filename&lt;/code&gt;. To change the owner of a file, I would use &lt;code&gt;chown new_owner filename&lt;/code&gt;, and to change the group, &lt;code&gt;chgrp new_group filename&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;18.&lt;strong&gt;Describe the types of device files in the /dev directory&lt;/strong&gt;. In the &lt;code&gt;/dev&lt;/code&gt; directory, there are two main types of device files: character device files and block device files. Character device files represent devices that transmit data one character at a time (e.g., &lt;code&gt;/dev/tty&lt;/code&gt; for terminal devices), while block device files represent devices that read and write data in blocks (e.g., &lt;code&gt;/dev/sda&lt;/code&gt; for hard drives). These files allow applications to interact with hardware devices through standard file operations.&lt;/p&gt;

&lt;p&gt;19.&lt;strong&gt;How do you mount and unmount filesystems in Linux?&lt;/strong&gt; To mount a filesystem in Linux, I typically use the &lt;code&gt;mount&lt;/code&gt; command. For example, to mount a USB drive located at &lt;code&gt;/dev/sdb1&lt;/code&gt; to a directory called &lt;code&gt;/mnt/usb,&lt;/code&gt; I would run:&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;mount /dev/sdb1 /mnt/usb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To unmount it, I would use the&amp;nbsp;&lt;code&gt;umount&lt;/code&gt;&amp;nbsp;command:&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;umount /mnt/usb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It’s important to ensure that no processes are using the filesystem before unmounting it to avoid data loss.&lt;/p&gt;

&lt;p&gt;20.&lt;strong&gt;How do you view processes and change their priorities in Linux?&lt;/strong&gt;&amp;nbsp;To view processes in Linux, I often use the&amp;nbsp;&lt;code&gt;ps&lt;/code&gt;&amp;nbsp;command, which lists currently running processes. For a more dynamic view,&amp;nbsp;&lt;code&gt;top&lt;/code&gt;&amp;nbsp;or&amp;nbsp;&lt;code&gt;htop&lt;/code&gt;&amp;nbsp;provides real-time updates. To change a process's priority, I can use the&amp;nbsp;&lt;code&gt;nice&lt;/code&gt;&amp;nbsp;command when starting a process (e.g.,&amp;nbsp;&lt;code&gt;nice -n 10 command&lt;/code&gt;) or the&amp;nbsp;&lt;code&gt;renice&lt;/code&gt;&amp;nbsp;command to change the priority of an already running process. Lowering the priority (increasing the niceness value) can be done with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;renice 10 &lt;span class="nt"&gt;-p&lt;/span&gt; PID
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;21.&lt;strong&gt;Explain the use of&amp;nbsp;&lt;code&gt;cron&lt;/code&gt;&amp;nbsp;and&amp;nbsp;&lt;code&gt;at&lt;/code&gt;&amp;nbsp;daemons for scheduling tasks in Linux.&lt;/strong&gt;&amp;nbsp;The&amp;nbsp;&lt;code&gt;cron&lt;/code&gt;&amp;nbsp;daemon is used for scheduling recurring tasks at specified intervals. I can create a cron job by editing the crontab with&amp;nbsp;&lt;code&gt;crontab -e&lt;/code&gt;, where I specify the time and command to run. For example, to run a script every day at 5 AM, I'd add:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;1 0 5 &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; /path/to/script.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The&amp;nbsp;&lt;code&gt;at&lt;/code&gt;&amp;nbsp;command is used for scheduling one-time tasks. I can schedule a command to run at a specific time by 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;echo&lt;/span&gt; &lt;span class="s2"&gt;"command"&lt;/span&gt; | at 5 PM
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;22.&lt;strong&gt;Describe how to configure key infrastructure services like DHCP and DNS in Linux.&lt;/strong&gt;&amp;nbsp;To configure a DHCP server in Linux, I typically install the&amp;nbsp;&lt;code&gt;dhcp&lt;/code&gt;&amp;nbsp;package and edit the configuration file located at&amp;nbsp;&lt;code&gt;/etc/dhcp/dhcpd.conf&lt;/code&gt;, where I define the subnet, range of IP addresses, and other options. After configuring, I start the DHCP service using&amp;nbsp;&lt;code&gt;systemctl start dhcpd&lt;/code&gt;. For DNS, I often use BIND (Berkeley Internet Name Domain). I install BIND, configure the zone files in&amp;nbsp;&lt;code&gt;/etc/bind/&lt;/code&gt;, and set up the&amp;nbsp;&lt;code&gt;named.conf&lt;/code&gt;&amp;nbsp;file to define the zones. I then start the BIND service with&amp;nbsp;&lt;code&gt;systemctl start named&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;23.&lt;strong&gt;Explain the process of configuring the Apache Web server for web services in Linux.&lt;/strong&gt;&amp;nbsp;To configure the Apache Web server, I first install it using the package manager (e.g.,&amp;nbsp;&lt;code&gt;sudo apt install apache2&lt;/code&gt;&amp;nbsp;on Debian-based systems). After installation, I can edit the main configuration file located at&amp;nbsp;&lt;code&gt;/etc/apache2/apache2.conf&lt;/code&gt;&amp;nbsp;or create virtual host files in&amp;nbsp;&lt;code&gt;/etc/apache2/sites-available/&lt;/code&gt;. To enable a virtual host, I use the&amp;nbsp;&lt;code&gt;a2ensite&lt;/code&gt;&amp;nbsp;command, and then restart Apache with&amp;nbsp;&lt;code&gt;sudo systemctl restart apache2&lt;/code&gt;. I also ensure that the firewall allows HTTP/HTTPS traffic using&amp;nbsp;&lt;code&gt;ufw allow 'Apache Full'&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;24.&lt;strong&gt;What are the different facets of Linux security and how can you increase the security of a Linux computer?&lt;/strong&gt;&amp;nbsp;Linux security encompasses user permissions, firewall configuration, regular updates, and system auditing. To increase security, I can enforce strong password policies, use tools like&amp;nbsp;&lt;code&gt;iptables&lt;/code&gt;&amp;nbsp;or&amp;nbsp;&lt;code&gt;ufw&lt;/code&gt;&amp;nbsp;for firewall settings, regularly apply security patches, and implement SELinux or AppArmor for additional access control. Additionally, I can minimize the number of running services and use SSH keys for secure remote access instead of passwords.&lt;/p&gt;

&lt;p&gt;25.&lt;strong&gt;Describe effective troubleshooting practices for common hardware and software problems in Linux.&lt;/strong&gt;&amp;nbsp;Effective troubleshooting in Linux involves several steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Identify the Problem:&lt;/strong&gt;&amp;nbsp;Gather information about the issue, including error messages and logs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check Logs:&lt;/strong&gt;&amp;nbsp;Review system logs in&amp;nbsp;&lt;code&gt;/var/log/&lt;/code&gt;&amp;nbsp;(like&amp;nbsp;&lt;code&gt;syslog&lt;/code&gt;&amp;nbsp;or&amp;nbsp;&lt;code&gt;dmesg&lt;/code&gt;) for relevant messages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use Diagnostic Tools:&lt;/strong&gt;&amp;nbsp;Utilize commands like&amp;nbsp;&lt;code&gt;ping&lt;/code&gt;,&amp;nbsp;&lt;code&gt;traceroute&lt;/code&gt;, and&amp;nbsp;&lt;code&gt;top&lt;/code&gt;&amp;nbsp;to diagnose network issues and system performance.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Research:&lt;/strong&gt;&amp;nbsp;Look up error messages online or consult documentation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testing:&lt;/strong&gt;&amp;nbsp;Isolate the issue by testing hardware components or reverting recent changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Seek Help:&lt;/strong&gt;&amp;nbsp;If needed, reach out to forums or communities for assistance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;26.&lt;strong&gt;Explain the difference between UNIX and Linux operating systems.&lt;/strong&gt;&amp;nbsp;UNIX is a proprietary operating system developed in the 1970s, while Linux is an open-source clone of UNIX created by Linus Torvalds in the early 1990s.&lt;/p&gt;

&lt;p&gt;27.&lt;strong&gt;What is Logical Volume Management (LVM) in Linux, and what are its advantages?&lt;/strong&gt;&amp;nbsp;Logical Volume Management (LVM) is a system for managing disk storage in Linux that allows for flexible allocation of storage space. With LVM, I can create logical volumes that can be resized dynamically, which is useful for managing storage needs over time. Advantages of LVM include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dynamic Resizing:&lt;/strong&gt;&amp;nbsp;I can easily increase or decrease the size of logical volumes as needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Snapshots:&lt;/strong&gt;&amp;nbsp;LVM allows me to create snapshots of volumes, which can be useful for backups or testing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pooling of Storage:&lt;/strong&gt;&amp;nbsp;Multiple physical disks can be combined into a single logical volume, simplifying storage management.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improved Disk Utilization:&lt;/strong&gt;&amp;nbsp;LVM helps in efficiently managing disk space across multiple partitions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;28.&lt;strong&gt;Discuss the role of systemd in managing services and daemons in Linux.&lt;/strong&gt;&amp;nbsp;Systemd is a system and service manager for Linux operating systems that has become the default init system for many distributions. Its role includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Service Management:&lt;/strong&gt;&amp;nbsp;Systemd manages services (daemons) using unit files, allowing for easy starting, stopping, enabling, and disabling of services.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Parallel Startup:&lt;/strong&gt;&amp;nbsp;It can start services in parallel, which improves boot times compared to traditional init systems.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependency Management:&lt;/strong&gt;&amp;nbsp;Systemd handles service dependencies, ensuring that services start in the correct order based on their requirements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Logging:&lt;/strong&gt;&amp;nbsp;It integrates with the journal system to provide logging capabilities, allowing for easy access to logs via the&amp;nbsp;&lt;code&gt;journalctl&lt;/code&gt;&amp;nbsp;command.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Socket and Timer Activation:&lt;/strong&gt;&amp;nbsp;Systemd can start services on-demand when a socket is accessed or at scheduled times, optimizing resource usage.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Congratulations on exploring the basics of Linux! We hope this collection of common questions and answers has made your introduction to Linux a little easier and more enjoyable. Remember, every expert was once a beginner, so don’t be afraid to experiment and ask questions as you learn. With practice and curiosity, you’ll soon feel at home in the Linux environment. Keep exploring, and enjoy your journey into the world of open-source technology!&lt;/p&gt;

&lt;p&gt;I hope you have enjoyed this article. If you have any questions, please feel free to reach out to me on&amp;nbsp;&lt;a href="https://twitter.com/KenMwaura1" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;. or&amp;nbsp;&lt;a href="https://www.linkedin.com/in/kennedy-mwaura/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;. You can also check out my other articles on&amp;nbsp;&lt;a href="https://dev.to/ken_mwaura1"&gt;Dev.to&lt;/a&gt;. Thanks for reading!&lt;/p&gt;

&lt;p&gt;Support me by buying me a&amp;nbsp;&lt;a href="https://www.buymeacoffee.com/kenmwaura1" rel="noopener noreferrer"&gt;coffee&lt;/a&gt;&lt;br&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%2Fq0npiwnjdy1zij8uto6r.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%2Fq0npiwnjdy1zij8uto6r.gif" alt="next-time" width="498" height="206"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>linux</category>
      <category>learning</category>
      <category>productivity</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>My Secret to Staying Ahead of the Tech Curve: How daily.dev Has Been a Game-Changer</title>
      <dc:creator>Zoo Codes</dc:creator>
      <pubDate>Mon, 02 Sep 2024 07:18:35 +0000</pubDate>
      <link>https://dev.to/ken_mwaura1/my-secret-to-staying-ahead-of-the-tech-curve-how-dailydev-has-been-a-game-changer-1mgk</link>
      <guid>https://dev.to/ken_mwaura1/my-secret-to-staying-ahead-of-the-tech-curve-how-dailydev-has-been-a-game-changer-1mgk</guid>
      <description>&lt;p&gt;I'll be the first to admit it: as a developer, I've often felt overwhelmed by the sheer amount of tech news and trends out there. It's like trying to drink from a firehose! But about a year ago, I stumbled upon a tool that has completely transformed my daily routine: daily.dev[&lt;a href="https://dly.to/CVhHhEWGKoN" rel="noopener noreferrer"&gt;https://dly.to/CVhHhEWGKoN&lt;/a&gt;].&lt;/p&gt;

&lt;p&gt;This amazing extension has not only saved me hours of time, but it's also helped me stay informed, focused, and ahead of the curve. I'm not exaggerating when I say it's been a total game-changer for me.&lt;/p&gt;

&lt;p&gt;So, what makes &lt;a href="https://dly.to/CVhHhEWGKoN" rel="noopener noreferrer"&gt;daily.dev&lt;/a&gt; so special? For me, it's the personalized feed that's tailored to my interests and preferences. I no longer have to sift through endless lists of irrelevant articles or scroll through Twitter for hours. &lt;a href="https://dly.to/CVhHhEWGKoN" rel="noopener noreferrer"&gt;daily.dev's&lt;/a&gt; AI-powered feed gives me exactly what I need to know, when I need to know it.&lt;/p&gt;

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

&lt;p&gt;But it's not just about saving time (although, let's be real, that's a huge bonus!). &lt;a href="https://dly.to/CVhHhEWGKoN" rel="noopener noreferrer"&gt;daily.dev&lt;/a&gt; has also helped me stay curious and excited about the tech industry. I love that I can quickly scan the latest news and updates, and then dive deeper into the topics that really interest me.&lt;/p&gt;

&lt;p&gt;If you're a fellow developer looking to boost your productivity and stay up-to-date with the latest tech news, I highly recommend giving &lt;a href="https://dly.to/CVhHhEWGKoN" rel="noopener noreferrer"&gt;daily.dev&lt;/a&gt; a try. It's not just a tool – it's a community of like-minded folks who are passionate about tech and innovation.&lt;/p&gt;

&lt;p&gt;So, what's your secret to staying ahead of the tech curve? Share your favorite tools and tips in the comments below!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkqxzrk6hlavlqrhe94rr.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkqxzrk6hlavlqrhe94rr.gif" alt="Next time gif" width="498" height="206"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>developers</category>
      <category>learning</category>
      <category>tooling</category>
    </item>
  </channel>
</rss>
