<?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: Ubayed Bin Sufian</title>
    <description>The latest articles on DEV Community by Ubayed Bin Sufian (@ubayedbinsufian).</description>
    <link>https://dev.to/ubayedbinsufian</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3496590%2F41f63d8e-df22-495b-a00f-2794cc5aa34f.jpg</url>
      <title>DEV Community: Ubayed Bin Sufian</title>
      <link>https://dev.to/ubayedbinsufian</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ubayedbinsufian"/>
    <language>en</language>
    <item>
      <title>VirtualBox Networking and Multi-VM Labs for DevOps Beginners</title>
      <dc:creator>Ubayed Bin Sufian</dc:creator>
      <pubDate>Wed, 10 Jun 2026 05:07:54 +0000</pubDate>
      <link>https://dev.to/ubayedbinsufian/virtualbox-networking-and-multi-vm-labs-for-devops-beginners-6km</link>
      <guid>https://dev.to/ubayedbinsufian/virtualbox-networking-and-multi-vm-labs-for-devops-beginners-6km</guid>
      <description>&lt;h2&gt;
  
  
  VirtualBox Networking
&lt;/h2&gt;

&lt;p&gt;In this section we will discuss:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Various types of networking — NAT, Bridged, Host-Only — what they mean and when to use each&lt;/li&gt;
&lt;li&gt;How multiple VMs connect to each other&lt;/li&gt;
&lt;li&gt;How to troubleshoot issues where you can't reach the internet&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  A Computer Can Have More Than One Door to the Network
&lt;/h2&gt;

&lt;p&gt;When we think about connecting a computer to the internet, we usually imagine just one connection — maybe Wi-Fi.&lt;/p&gt;

&lt;p&gt;But a computer can actually have &lt;strong&gt;multiple network interfaces&lt;/strong&gt;, and each one acts like its own separate &lt;strong&gt;door&lt;/strong&gt; to the network.&lt;/p&gt;

&lt;p&gt;Let me show you using my own laptop.&lt;/p&gt;

&lt;p&gt;When I ran:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;I got this:&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%2Fp0cp4d71yqfpazm9i2c5.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%2Fp0cp4d71yqfpazm9i2c5.png" alt="ip addr show" width="799" height="186"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At first glance, this looks technical. But there's a simple story here.&lt;/p&gt;




&lt;h2&gt;
  
  
  Meet the Three Characters
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;code&gt;lo&lt;/code&gt; — The Computer Talking to Itself
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;loopback interface&lt;/strong&gt; (&lt;code&gt;lo&lt;/code&gt;) is special.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;inet 127.0.0.1/8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the famous &lt;strong&gt;localhost&lt;/strong&gt; address. Think of it as your laptop looking into a mirror.&lt;/p&gt;

&lt;p&gt;When an application talks to &lt;code&gt;127.0.0.1&lt;/code&gt;, it is not going out to the network — it is talking back to the same machine.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. &lt;code&gt;enp1s0&lt;/code&gt; — The Unused Ethernet Port
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;2: enp1s0
state DOWN
NO-CARRIER
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is my &lt;strong&gt;wired Ethernet adapter&lt;/strong&gt;. It exists, but no cable is plugged in.&lt;/p&gt;

&lt;p&gt;Imagine a door in your house that exists but is bolted shut — nobody can enter through it. That is why there is &lt;strong&gt;no IP address&lt;/strong&gt; assigned here.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. &lt;code&gt;wlp2s0&lt;/code&gt; — The Active Wi-Fi Connection
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;3: wlp2s0
inet 192.168.0.105/24
state UP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is my &lt;strong&gt;wireless adapter&lt;/strong&gt;. It is connected to my home Wi-Fi, so my router assigned it an IP via DHCP:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;This is the address other devices on my home network can use to reach my laptop.&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%2F8mopwrfj564c4tlphkbn.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%2F8mopwrfj564c4tlphkbn.png" alt="Summary of all networks" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  What if Both Were Connected?
&lt;/h3&gt;

&lt;p&gt;Now imagine I plug in an Ethernet cable while Wi-Fi is still on.&lt;/p&gt;

&lt;p&gt;Suddenly my laptop could look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;enp1s0  -&amp;gt; 192.168.0.110
wlp2s0  -&amp;gt; 192.168.0.105
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same laptop. Two interfaces. Two IP addresses. Two different doors into the same machine.&lt;/p&gt;

&lt;p&gt;Other devices could reach me using &lt;strong&gt;either address&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Big Lesson
&lt;/h3&gt;

&lt;p&gt;A computer is not assigned an IP address. An &lt;strong&gt;interface&lt;/strong&gt; is assigned an IP address.&lt;/p&gt;

&lt;p&gt;That is an important distinction. Your laptop may have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one Wi-Fi adapter&lt;/li&gt;
&lt;li&gt;one Ethernet adapter&lt;/li&gt;
&lt;li&gt;a VPN tunnel&lt;/li&gt;
&lt;li&gt;virtual machine adapters&lt;/li&gt;
&lt;li&gt;docker bridges&lt;/li&gt;
&lt;li&gt;loopback
Each can have its &lt;strong&gt;own IP address&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So when someone says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What is your computer's IP?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The more accurate question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Which interface are you talking about?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Glossary
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;network interface&lt;/strong&gt; is the part of a computer that allows it to communicate on a network.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;network adapter&lt;/strong&gt; is the hardware (or virtual hardware) that provides that interface.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hardware (adapter)  ---&amp;gt;  OS sees it as  ---&amp;gt;  Interface
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The Big Idea: Every VM is Just Another Machine on a Network
&lt;/h2&gt;

&lt;p&gt;Think of your laptop as a small apartment building. VirtualBox creates multiple virtual "tenants" (VMs) inside it.&lt;/p&gt;

&lt;p&gt;Each VM:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Has its own network card (adapter)&lt;/li&gt;
&lt;li&gt;Connects to a "network type" you choose&lt;/li&gt;
&lt;li&gt;Can have up to 4 network adapters (usually 1 is enough)
&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%2Ffwv195kzhhj80at32vvp.png" alt="adapters with network types" width="800" height="425"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Which network is this VM plugged into?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That choice defines everything.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Host-Only Network (Private Lab Inside Your Laptop)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Concept
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;Host-Only network&lt;/strong&gt; is like building a private hallway inside your apartment building — only the residents (your VMs) and the landlord (your host machine) can use it. No one from outside can get in.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only your host machine + VMs can talk to each other&lt;/li&gt;
&lt;li&gt;No internet access by default&lt;/li&gt;
&lt;li&gt;Completely isolated from the outside world
&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%2F300oqnffl51cu67ok7ki.png" alt="Host only network" width="800" height="533"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example Setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Host machine: 192.168.5.1
VM1:          192.168.5.2
VM2:          192.168.5.3
VM3:          192.168.5.4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All machines can ping each other and share services internally — but none can reach the internet.&lt;/p&gt;

&lt;h3&gt;
  
  
  How It Works in VirtualBox
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;File → Tools → Network Manager&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Create a new Host-Only network&lt;/li&gt;
&lt;li&gt;VirtualBox creates a virtual adapter (like &lt;code&gt;vboxnet0&lt;/code&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%2F4uhmigzmib25cvo9pax3.png" alt="vboxnet0" width="800" height="425"&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%2Fpf5ov3dubnr686br9ujg.png" alt="ip addr show" width="799" height="206"&gt;
&lt;/li&gt;
&lt;li&gt;Your host gets an IP like &lt;code&gt;192.168.5.1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Attach VMs to &lt;strong&gt;Host-Only Adapter&lt;/strong&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%2Ff6wsiyqigfr2nfqies7n.png" alt="Attach VMs" width="800" height="425"&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Use Case
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Testing microservices locally&lt;/li&gt;
&lt;li&gt;Simulating private networks&lt;/li&gt;
&lt;li&gt;Database + backend interaction in isolation&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  2. NAT Network (Private Network + Internet Access)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Concept
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;NAT Network&lt;/strong&gt; is like that same private hallway — but now there's a shared exit door that leads outside. The tenants can talk to each other &lt;em&gt;and&lt;/em&gt; get to the internet, but strangers still can't walk in uninvited.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;VMs can talk to each other&lt;/li&gt;
&lt;li&gt;VMs can access the internet&lt;/li&gt;
&lt;li&gt;External systems still cannot directly access VMs&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How It Works
&lt;/h3&gt;

&lt;p&gt;When a VM sends a request out to the internet:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;VM sends a packet with its private IP (e.g. &lt;code&gt;10.0.2.4&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;VirtualBox's NAT engine replaces it with the host's IP&lt;/li&gt;
&lt;li&gt;Request goes to the internet&lt;/li&gt;
&lt;li&gt;Response comes back to the host&lt;/li&gt;
&lt;li&gt;NAT engine forwards it back to the correct VM
This is called &lt;strong&gt;Network Address Translation (NAT)&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;VM1 → 10.0.2.4
VM2 → 10.0.2.5
VM3 → 10.0.2.6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All share internet access and can communicate internally.&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%2Frij7keer44blci7t768e.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%2Frij7keer44blci7t768e.png" alt="NAT network" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;File → Tools → Network&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Create a &lt;strong&gt;NAT Network&lt;/strong&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%2Fn4enruo4peisi250yj2f.png" alt="Create a NAT Network" width="799" height="426"&gt;
&lt;/li&gt;
&lt;li&gt;Attach VM → Network → &lt;strong&gt;NAT Network&lt;/strong&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%2Fd4c0nqgp8607o2e04ild.png" alt="Attach VM to NAT network" width="800" height="424"&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Use Case
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Running development environments with internet access&lt;/li&gt;
&lt;li&gt;Package installs (&lt;code&gt;apt&lt;/code&gt;, &lt;code&gt;npm&lt;/code&gt;, &lt;code&gt;pip&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;APIs + database testing with external services&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  3. NAT (Default VM Mode)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Concept
&lt;/h3&gt;

&lt;p&gt;This is similar to NAT Network but simpler and more isolated. Each VM gets its own mini-router — it can call out to the internet, but it cannot talk to other VMs by default.&lt;/p&gt;

&lt;p&gt;Think of each tenant having their own private exit, but no shared hallway between them.&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%2Ffwsvk4bumd5edze7khtf.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%2Ffwsvk4bumd5edze7khtf.png" alt="NAT" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Difference vs NAT Network
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;NAT&lt;/th&gt;
&lt;th&gt;NAT Network&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Internet access&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VM-to-VM communication&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Shared network&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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%2Fodzwjz6bj341g8uk3j0r.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%2Fodzwjz6bj341g8uk3j0r.png" alt="NAT diagram" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Use Case
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Single VM development&lt;/li&gt;
&lt;li&gt;Safer isolation&lt;/li&gt;
&lt;li&gt;Quick setup without networking complexity&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  4. Bridged Network (VM Becomes a Real Machine on Your LAN)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Concept
&lt;/h3&gt;

&lt;p&gt;Bridged networking is the most open mode. Your VM stops being a hidden tenant and moves out onto the street — it becomes a fully visible member of your home network, just like your phone or any other device.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The VM behaves like a real computer plugged into your router.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Router:  192.168.1.1
Laptop:  192.168.1.10
Phone:   192.168.1.20
VM:      192.168.1.30   ← your router sees this as a real device
&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%2Fdz8g75n9290js17i0qhr.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%2Fdz8g75n9290js17i0qhr.png" alt="Overview of Bridged adapter" width="800" height="533"&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%2Fpjeud0stom48gj651fcb.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%2Fpjeud0stom48gj651fcb.png" alt="Bridged adapter" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What Happens Internally
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;VM gets an IP from your router via DHCP&lt;/li&gt;
&lt;li&gt;Same subnet as your laptop&lt;/li&gt;
&lt;li&gt;Fully visible to other devices on the network&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Use Case
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Hosting services (web servers, APIs)&lt;/li&gt;
&lt;li&gt;Testing real network behavior&lt;/li&gt;
&lt;li&gt;Accessing the VM from another machine on your LAN&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Internet Connectivity Summary
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mode&lt;/th&gt;
&lt;th&gt;Internet Access&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;NAT&lt;/td&gt;
&lt;td&gt;✅ Via host as gateway&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NAT Network&lt;/td&gt;
&lt;td&gt;✅ Via host as gateway&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bridged&lt;/td&gt;
&lt;td&gt;✅ Via router directly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Host-Only&lt;/td&gt;
&lt;td&gt;❌ No internet by default&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&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%2Fvmjpz5rx0nsqxrk1inz5.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%2Fvmjpz5rx0nsqxrk1inz5.png" alt="internet connectivity" width="800" height="450"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Screenshot taken from YouTube video&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  If Host-Only Needs Internet
&lt;/h3&gt;

&lt;p&gt;You have two options:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option A:&lt;/strong&gt; Enable IP forwarding on the host — make your laptop act like a router.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option B (simpler):&lt;/strong&gt; Add a second adapter to each VM:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Adapter 1 → Host-Only (private network)&lt;/li&gt;
&lt;li&gt;Adapter 2 → NAT (internet)
This is the most common real-world setup for home labs.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  5. Port Forwarding (Access VM Services from Outside)
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Concept
&lt;/h3&gt;

&lt;p&gt;Port forwarding is like setting up a concierge at the front desk of your building. When a visitor arrives and asks for a specific service, the concierge knows exactly which apartment to send them to.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"If someone knocks on port 8080, send them to the web server in VM1."&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Example — Web Server
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Host Port 8080 → VM Port 80
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now visiting &lt;code&gt;http://localhost:8080&lt;/code&gt; forwards to the web server running inside your VM.&lt;/p&gt;
&lt;h3&gt;
  
  
  Example — SSH
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Host Port 2222 → VM Port 22
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh user@localhost &lt;span class="nt"&gt;-p&lt;/span&gt; 2222
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You can SSH into the VM without even knowing its internal IP.&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%2Fmsto1rsfylesojat84dj.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%2Fmsto1rsfylesojat84dj.png" alt="Port forwarding" width="799" height="426"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Use Case
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Accessing web apps inside a NAT VM&lt;/li&gt;
&lt;li&gt;Debugging microservices&lt;/li&gt;
&lt;li&gt;Running multiple VMs with different exposed ports&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Working with Multiple VMs: Cloning and Snapshots
&lt;/h2&gt;

&lt;p&gt;So far, we've explored the different networking modes in VirtualBox. Now let's look at how to efficiently create multiple VMs, connect them together, and use snapshots to experiment safely.&lt;/p&gt;


&lt;h2&gt;
  
  
  Creating Multiple VMs with Cloning
&lt;/h2&gt;

&lt;p&gt;When building a lab, you'll often need several VMs that are nearly identical — like printing copies of the same blueprint rather than drawing each one from scratch.&lt;/p&gt;

&lt;p&gt;The common approach:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create and configure one base VM&lt;/li&gt;
&lt;li&gt;Install required software and updates&lt;/li&gt;
&lt;li&gt;Use it as a template&lt;/li&gt;
&lt;li&gt;Clone it as many times as needed&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  How to Clone a VM
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Shut down the VM&lt;/li&gt;
&lt;li&gt;Right-click the VM in VirtualBox&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Clone&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Enter a name for the new VM&lt;/li&gt;
&lt;li&gt;Choose the clone type&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The Clone option is only available when the VM is powered off.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvr1orgh1hrnhkryalea9.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%2Fvr1orgh1hrnhkryalea9.png" alt="How to Clone a VM" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Full Clone vs Linked Clone
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Full Clone&lt;/strong&gt; — A completely independent copy. Like photocopying a document: the copy stands on its own.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Fully self-contained, easy to move between computers&lt;/li&gt;
&lt;li&gt;❌ Uses the same disk space as the original&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Linked Clone&lt;/strong&gt; — Shares the original's virtual disk and only stores changes. Like a shortcut that points back to the original.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Much smaller, faster to create&lt;/li&gt;
&lt;li&gt;❌ Depends on the parent VM; can't be moved easily&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  When to Use Each
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Recommended&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Learning labs&lt;/td&gt;
&lt;td&gt;Linked Clone&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Temporary testing&lt;/td&gt;
&lt;td&gt;Linked Clone&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Long-term VM&lt;/td&gt;
&lt;td&gt;Full Clone&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Moving VMs between computers&lt;/td&gt;
&lt;td&gt;Full Clone&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For most home labs, Linked Clones are sufficient.&lt;/p&gt;


&lt;h2&gt;
  
  
  Connecting Multiple VMs Together
&lt;/h2&gt;

&lt;p&gt;Say we've cloned our base VM and now have VM1 and VM2. We want:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;VM1 ↔ VM2 communication&lt;/li&gt;
&lt;li&gt;Internet access for both
The cleanest solution: &lt;strong&gt;two network adapters per VM&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Adapter 1: NAT
&lt;/h3&gt;

&lt;p&gt;Gives each VM internet access — for downloading packages, updates, and calling external services.&lt;/p&gt;
&lt;h3&gt;
  
  
  Adapter 2: Host-Only Network
&lt;/h3&gt;

&lt;p&gt;Creates a private channel between all VMs and the host.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Host Machine  → 192.168.57.1
VM1           → 192.168.57.3
VM2           → 192.168.57.4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Setting Up the Host-Only Network
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Open &lt;strong&gt;File → Host Network Manager&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Enable DHCP if desired&lt;/li&gt;
&lt;li&gt;Save the network
VirtualBox creates a virtual network (&lt;code&gt;vboxnet1&lt;/code&gt;) with an address range like &lt;code&gt;192.168.57.0/24&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Attaching VMs to the Host-Only Network
&lt;/h3&gt;

&lt;p&gt;For each VM:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open VM Settings → Network&lt;/li&gt;
&lt;li&gt;Enable &lt;strong&gt;Adapter 2&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Host-Only Adapter&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Choose the newly created network&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Verifying Connectivity
&lt;/h2&gt;

&lt;p&gt;Once both VMs are running:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Check IP addresses:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;You should see a second interface with an IP like &lt;code&gt;192.168.57.3&lt;/code&gt; or &lt;code&gt;192.168.57.4&lt;/code&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%2Fuws13raq7h9wlg00vi1j.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%2Fuws13raq7h9wlg00vi1j.png" alt=" " width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test VM-to-VM communication:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# From VM1&lt;/span&gt;
ping 192.168.57.4

&lt;span class="c"&gt;# From VM2&lt;/span&gt;
ping 192.168.57.3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Test internet access:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ping google.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All three should work.&lt;/p&gt;




&lt;h2&gt;
  
  
  Choosing the Right Networking Mode
&lt;/h2&gt;

&lt;p&gt;A quick reference:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Requirement&lt;/th&gt;
&lt;th&gt;Recommended Mode&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Internet only&lt;/td&gt;
&lt;td&gt;NAT&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VM-to-VM + Internet&lt;/td&gt;
&lt;td&gt;NAT Network&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VM-to-VM only&lt;/td&gt;
&lt;td&gt;Host-Only&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;VM visible on LAN&lt;/td&gt;
&lt;td&gt;Bridged&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Private network + Internet&lt;/td&gt;
&lt;td&gt;Host-Only + NAT&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Using Snapshots
&lt;/h2&gt;

&lt;p&gt;Think of snapshots as save points in a video game. Before you attempt a risky boss fight (a major system change), you save. If things go wrong, you reload and try again.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Snapshots Are Useful
&lt;/h3&gt;

&lt;p&gt;Before you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Upgrade software&lt;/li&gt;
&lt;li&gt;Install packages&lt;/li&gt;
&lt;li&gt;Modify configurations&lt;/li&gt;
&lt;li&gt;Experiment with new tools
Take a snapshot. If something breaks, restore it in seconds.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Creating a Snapshot
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Select the VM → open the &lt;strong&gt;Snapshots&lt;/strong&gt; view&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Take Snapshot&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Give it a meaningful name (e.g. &lt;code&gt;Good State&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /opt/app
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Example File"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /opt/app/example.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything works. Take a snapshot named &lt;code&gt;Good State&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now simulate an accident:&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;"corrupted data"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /opt/app/example.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Restoring a Snapshot
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Power off the VM&lt;/li&gt;
&lt;li&gt;Open Snapshots&lt;/li&gt;
&lt;li&gt;Right-click the snapshot → &lt;strong&gt;Restore&lt;/strong&gt;
After booting, the VM returns exactly to where it was. The original file is back.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Cloning from a Snapshot
&lt;/h3&gt;

&lt;p&gt;You can also clone directly from a snapshot — useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Testing multiple software versions side by side&lt;/li&gt;
&lt;li&gt;Comparing configurations&lt;/li&gt;
&lt;li&gt;Building temporary environments from a known-good state&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;&lt;strong&gt;Use clones for reusability&lt;/strong&gt; — configure one solid base VM, clone it whenever you need a fresh machine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use Linked Clones for labs&lt;/strong&gt; — they save significant disk space.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Take snapshots before major changes&lt;/strong&gt; — OS upgrades, kernel updates, database migrations, large installs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use NAT + Host-Only together&lt;/strong&gt; — this combination gives you internet access and VM-to-VM communication, which covers most lab scenarios.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;VirtualBox becomes significantly more powerful once you combine cloning, multiple network adapters, and snapshots. Together, they let you build realistic multi-machine environments on a single laptop — and experiment freely, knowing you can always recover.&lt;/p&gt;




&lt;p&gt;This is part of my DevOps Prerequisite series:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/ubayedbinsufian/devops-prerequisite-linux-basics-you-actually-need-47pe"&gt;DevOps Prerequisite #1: Linux Basics You Actually Need&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/ubayedbinsufian/build-your-own-lab-virtualization-for-devops-beginners-1fac"&gt;Build Your Own Lab: Virtualization for DevOps Beginners&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;VirtualBox Networking and Multi-VM Labs for DevOps Beginners (this post)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Why Vagrant Still Matters (and When It Doesn't) (next)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Networking for DevOps: The Only Concepts You Need&lt;/li&gt;
&lt;li&gt;YAML Explained for Future DevOps Engineers&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Disclaimer: I have used GPT 5.5 &amp;amp; Claude Sonnet 4.6 (Low) for writing the topics, GPT 5.5 &amp;amp; Gemini Nano for content and cover image generation respectively.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference:&lt;/strong&gt;&lt;br&gt;
💡 Want a visual walkthrough? This video does a great job explaining the basics covered here. Use it as a supplement — not a replacement:&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/Wvf0mBNGjXY?start=2256"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>devops</category>
      <category>virtualbox</category>
      <category>networking</category>
      <category>linux</category>
    </item>
    <item>
      <title>From Prototype to Production-Ready: Finishing an Open Source WordPress Event Management Plugin</title>
      <dc:creator>Ubayed Bin Sufian</dc:creator>
      <pubDate>Sun, 07 Jun 2026 21:06:30 +0000</pubDate>
      <link>https://dev.to/ubayedbinsufian/from-prototype-to-production-ready-finishing-an-open-source-wordpress-event-management-plugin-1g5n</link>
      <guid>https://dev.to/ubayedbinsufian/from-prototype-to-production-ready-finishing-an-open-source-wordpress-event-management-plugin-1g5n</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/github-2026-05-21"&gt;GitHub Finish-Up-A-Thon Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;Every open-source conference needs a home on the web. An open-source community runs an existing ticketing platform handles event ticketing. But there was a gap: it was doing too much. It was managing ticketing and trying to be a full event website at the same time. That's not a great separation of concerns.&lt;/p&gt;

&lt;p&gt;The idea was straightforward: build a dedicated &lt;strong&gt;WordPress Event Management Plugin&lt;/strong&gt; that handles the public-facing side of events — the landing pages, speaker grids, session listings, schedules, and code of conduct pages — while the ticketing platform stays focused on what it does best.&lt;/p&gt;

&lt;p&gt;A community contributor started this plugin. They got the foundation in place, but the code was procedural, hardcoded in places, and not following WordPress coding standards. It was a solid proof of concept, but not something you'd ship to a production site.&lt;/p&gt;

&lt;p&gt;This challenge gave me the push to finally finish it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Demo
&lt;/h2&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%2Frjgquwmsl5eo5u19tn00.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%2Frjgquwmsl5eo5u19tn00.gif" alt="Animated GIF or short screen recording of the plugin in action — switching between event pages in WordPress admin" width="560" height="287"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Animated GIF or short screen recording of the plugin in action — switching between event pages in WordPress admin&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live repository:&lt;/strong&gt; &lt;a href="https://github.com/fossasia/WPFAevent" rel="noopener noreferrer"&gt;https://github.com/fossasia/WPFAevent&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Plugin pages completed so far:&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Template&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;events-template.php&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ Complete&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;past-events-template.php&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ Complete&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;speakers-template.php&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ Complete&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;code-of-conduct-template.php&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ Complete&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;landing-template.php&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;✅ &lt;strong&gt;Finished during this challenge&lt;/strong&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;schedule-template.php&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;🔄 In progress&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  The Landing Page — Before
&lt;/h3&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%2Frf1fcgafqx5ycrq18akw.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%2Frf1fcgafqx5ycrq18akw.png" alt="The Landing Page — Before" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Landing Page — After
&lt;/h3&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%2F1f8g4zalyo44zs8mt8qr.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%2F1f8g4zalyo44zs8mt8qr.png" alt="After — the finished landing template with header navigation, featured sections" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;After — the finished landing template with header navigation, featured sections&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Comeback Story
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Where It Started
&lt;/h3&gt;

&lt;p&gt;The original prototype gave us a working skeleton. You could register the plugin, activate it, and assign pages to templates. That was genuinely useful groundwork. But when you looked under the hood:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Template files were full of &lt;strong&gt;hardcoded values&lt;/strong&gt; — event names, speaker names, and section titles were written directly into PHP strings&lt;/li&gt;
&lt;li&gt;Logic was scattered across &lt;strong&gt;procedural scripts&lt;/strong&gt; with no class structure&lt;/li&gt;
&lt;li&gt;There was no consistent use of WordPress hooks (&lt;code&gt;add_action&lt;/code&gt;, &lt;code&gt;add_filter&lt;/code&gt;), sanitization helpers (&lt;code&gt;sanitize_text_field&lt;/code&gt;, &lt;code&gt;esc_html&lt;/code&gt;), or nonce verification&lt;/li&gt;
&lt;li&gt;The landing template existed as a file but rendered almost nothing dynamically&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It wasn't broken — it just wasn't finished, and it wasn't ready for anyone to actually use on a real site.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs96xjw187ohllg2lys94.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%2Fs96xjw187ohllg2lys94.png" alt="Side-by-side of old procedural code vs. new OOP class structure in VS Code" width="799" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Side-by-side of old procedural code vs. new OOP class structure in VS Code&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Refactor
&lt;/h3&gt;

&lt;p&gt;The first big task was structural. I rewrote the plugin to follow &lt;strong&gt;WordPress Coding Standards&lt;/strong&gt; and proper &lt;strong&gt;Object-Oriented PHP&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each template is now handled by its own PHP class&lt;/li&gt;
&lt;li&gt;WordPress hooks are registered cleanly in a central bootstrap file&lt;/li&gt;
&lt;li&gt;All output is properly escaped using &lt;code&gt;esc_html()&lt;/code&gt;, &lt;code&gt;esc_url()&lt;/code&gt;, and &lt;code&gt;wp_kses_post()&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Data is pulled via &lt;strong&gt;custom post types&lt;/strong&gt; and post meta — no hardcoded values anywhere&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The three earlier templates (events, speakers, code of conduct) had already been refactored before this challenge. The landing template was the next one on the list — and the most complex.&lt;/p&gt;

&lt;h3&gt;
  
  
  Finishing the Landing Template
&lt;/h3&gt;

&lt;p&gt;The landing page is the hub for an individual event. When a visitor navigates to a specific event, this is what they see first. It needed to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Display a header with navigation links&lt;/strong&gt; — Schedule, Speakers, Register — that are relevant to that specific event&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pull in featured content sections&lt;/strong&gt; dynamically based on event metadata&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Render a Speakers grid&lt;/strong&gt; showing featured speakers for the event, sourced from the custom post type relationships — no hardcoded names or photos&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stay modular&lt;/strong&gt; — each section is its own component so future contributors can add or swap sections without touching the core template&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%2Fx6cq5hd3ys0l6zbfdhy9.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%2Fx6cq5hd3ys0l6zbfdhy9.png" alt="WordPress admin — assigning the landing-template.php to a page via the Page Attributes dropdown" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;WordPress admin — assigning the landing-template.php to a page via the Page Attributes dropdown&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmlp4nfvmfklz4476chx9.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%2Fmlp4nfvmfklz4476chx9.png" alt="Frontend output of the landing page showing the header nav, featured sections" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Frontend output of the landing page showing the header nav, featured sections&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  My Experience with GitHub Copilot
&lt;/h2&gt;

&lt;p&gt;I'll be honest — I was skeptical at first. I've used AI autocomplete tools before and found them useful for boilerplate but frustrating for anything that required understanding a project's specific conventions.&lt;/p&gt;

&lt;p&gt;GitHub Copilot surprised me.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where It Helped Most
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;WordPress-specific patterns.&lt;/strong&gt; The WordPress API has a lot of functions you need to remember — the right sanitization function for the right context, the correct way to register a custom post type, how to structure a &lt;code&gt;WP_Query&lt;/code&gt; call with the right arguments. Copilot was genuinely good at filling these in accurately, and it mostly respected the OOP structure I had already established when suggesting completions.&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%2Fok6pt2hgh5rlc1ntuosd.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%2Fok6pt2hgh5rlc1ntuosd.png" alt="Copilot suggestion in VS Code — showing it autocompleting a register_post_type() call with correct arguments" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Copilot suggestion in VS Code — showing it autocompleting a register_post_type() call with correct arguments&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repetitive structure.&lt;/strong&gt; The speakers grid component follows a pattern: query posts, loop through results, output HTML with escaped values. Once I wrote the first version, Copilot helped me apply the same pattern to featured sections quickly, and it kept the escaping consistent — which matters a lot in WordPress.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Docblock comments.&lt;/strong&gt; Writing PHPDoc comments for every method is tedious but important for an open-source plugin that other contributors will maintain. Copilot generated accurate docblocks based on the method signatures and logic, saving real time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5p5enb9lul9zz04331wp.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%2F5p5enb9lul9zz04331wp.png" alt="Copilot generating a PHPDoc comment for a class method in the landing template file" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Copilot generating a PHPDoc comment for a class method in the landing template file&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Where I Steered It
&lt;/h3&gt;

&lt;p&gt;Copilot sometimes suggested patterns that were technically valid PHP but not the WordPress way. For example, it would occasionally reach for plain &lt;code&gt;mysqli&lt;/code&gt; or &lt;code&gt;PDO&lt;/code&gt; for data queries rather than &lt;code&gt;WP_Query&lt;/code&gt; or &lt;code&gt;get_post_meta()&lt;/code&gt;. I learned to prompt it with more context — mentioning WordPress hooks or the class it was working inside — and that helped a lot.&lt;/p&gt;

&lt;p&gt;It also couldn't know our plugin's specific data model (how speakers relate to events, how featured sections are stored in post meta) without me giving it context. Once I pasted in the relevant schema or pointed it at an existing similar method, the suggestions got much more useful.&lt;/p&gt;

&lt;p&gt;The workflow that worked best: &lt;strong&gt;write the method signature and a comment describing intent → let Copilot fill in the body → review and adjust.&lt;/strong&gt; It's a genuine collaboration, not a vending machine.&lt;/p&gt;




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

&lt;p&gt;The landing template is done, but the plugin isn't finished. Sessions and schedule templates are next. The goal is to have a complete, standards-compliant plugin that any community member can drop into a WordPress site and use for their event.&lt;/p&gt;

&lt;p&gt;If you're interested in contributing, the repo is open. Issues are tagged and the architecture is documented.&lt;/p&gt;




&lt;h2&gt;
  
  
  Tooling Disclosure
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;AI tools used in this project:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Copilot&lt;/strong&gt; — used for code generation, autocompletion, and docblock writing throughout the plugin development, as described in the "My Experience with GitHub Copilot" section above&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claude Code&lt;/strong&gt; — used to assist with drafting and structuring this article&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both tools were used as assistants, not as authors. All architectural decisions, code review, and final judgement calls were made by the human contributor.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>githubchallenge</category>
      <category>ai</category>
      <category>githubcopilot</category>
    </item>
    <item>
      <title>How I Use Antigravity 2.0 to Navigate Open-Source Codebases and Make Better Technical Decisions</title>
      <dc:creator>Ubayed Bin Sufian</dc:creator>
      <pubDate>Mon, 25 May 2026 07:43:09 +0000</pubDate>
      <link>https://dev.to/ubayedbinsufian/how-i-use-antigravity-20-to-navigate-open-source-codebases-and-make-better-technical-decisions-2ic3</link>
      <guid>https://dev.to/ubayedbinsufian/how-i-use-antigravity-20-to-navigate-open-source-codebases-and-make-better-technical-decisions-2ic3</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/google-io-writing-2026-05-19"&gt;Google I/O Writing Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Hook: The Tool That Changed How I Contribute to Open Source
&lt;/h2&gt;

&lt;p&gt;I'll be honest — for the past two years, whenever someone asked me what AI coding tool to use, my answer was automatic: Claude Code or Codex, pick your poison. Google? Not even in the conversation.&lt;/p&gt;

&lt;p&gt;Then Google I/O 2026 happened.&lt;/p&gt;

&lt;p&gt;In roughly 24 hours, Google dropped over 20 tools — and one of them stopped me mid-scroll. &lt;strong&gt;Antigravity 2.0&lt;/strong&gt;: a standalone desktop agent orchestration platform, free to start, built on Gemini 3.5 Flash, and designed to spin up parallel AI sub-agents the way a senior engineer delegates work to a team.&lt;/p&gt;

&lt;p&gt;I didn't want to just read about it. I wanted to put it to work on something real. So I pointed it at a problem I run into constantly as an open-source contributor: &lt;strong&gt;walking into an unfamiliar codebase and trying to figure out what's already there before you touch anything&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Right now I'm using it to review &lt;a href="https://github.com/fossasia/WPFAevent" rel="noopener noreferrer"&gt;WPFAevent&lt;/a&gt;, a WordPress plugin by &lt;a href="https://fossasia.org" rel="noopener noreferrer"&gt;FOSSASIA&lt;/a&gt; that integrates with the Eventyay event platform. It's a real repo — 14 open issues, 17 pull requests, PHP + JavaScript + CSS — and it gave me a good surface for testing how well Antigravity handles the kind of context-gathering work that usually eats the first hour of any contribution session.&lt;/p&gt;

&lt;p&gt;This is the full walkthrough of how I use it, what genuinely impressed me, where I hit friction, and what every developer contributing to open source should know before they dive in.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Is Antigravity 2.0?
&lt;/h2&gt;

&lt;p&gt;Antigravity 2.0 is Google's new &lt;strong&gt;standalone desktop app for AI agent orchestration&lt;/strong&gt;. Less than a year ago, Google shipped the Antigravity IDE — a full code editor with an Agent Manager baked in. It was powerful but intimidating. Antigravity 2.0 strips that away entirely. What remains is a clean chat interface that anyone can open and immediately use, backed by agents that coordinate complex work automatically.&lt;/p&gt;

&lt;p&gt;The key word is &lt;em&gt;agents&lt;/em&gt; — plural, parallel, autonomous.&lt;/p&gt;

&lt;p&gt;Where a tool like Claude Code (as of this writing) requires developers to manually configure sub-agent workflows, Antigravity 2.0 is designed from the ground up around the idea that one task can, and often should, spawn multiple specialized agents working simultaneously. A code analysis agent. A research agent cross-referencing docs. A QA agent running browser tests. All at once, reporting back to you, asking for approval only when needed.&lt;/p&gt;

&lt;p&gt;At Google I/O, the team ran Antigravity 2.0 for 12 hours straight on stage — 93 sub-agents running in parallel — and produced a working operating system. That's the scale this thing is designed to operate at.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Where it fits in Google's ecosystem:&lt;/strong&gt; Antigravity connects directly to Google products via installable skills and plugins — Chrome DevTools, modern web guidance, and more — and the whole stack runs on Gemini 3.5 Flash, which is reportedly capable of generating code at close to 800 tokens per second. That raw speed changes how iteration feels in practice.&lt;/p&gt;




&lt;h2&gt;
  
  
  My Hands-On Experiment: Reviewing WPFAevent
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Environment &amp;amp; Prerequisites
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;OS:&lt;/strong&gt; Linux Mint 22.3 - Cinnamon 64-bit&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Antigravity version:&lt;/strong&gt; 2.0.6 (Manual Tarball Release)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google account:&lt;/strong&gt; Required for sign-in&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/fossasia/WPFAevent" rel="noopener noreferrer"&gt;fossasia/WPFAevent&lt;/a&gt; — cloned locally&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prior Antigravity IDE experience:&lt;/strong&gt; None needed (though existing IDE users get a smooth migration path)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 1: Installation and Onboarding
&lt;/h3&gt;

&lt;p&gt;Head to &lt;a href="https://antigravity.google" rel="noopener noreferrer"&gt;antigravity.google&lt;/a&gt; and grab the installer for your platform — Apple Silicon, Intel Mac, Windows (two installer options), or Linux.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# macOS: Drag to Applications, open from Spotlight&lt;/span&gt;
&lt;span class="c"&gt;# Windows: Run the installer directly&lt;/span&gt;
&lt;span class="c"&gt;# Linux: Build available from the site&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For Linux Mint, instead of using the standard &lt;code&gt;apt&lt;/code&gt; package manager (which still defaults to the older 1.x stable branch), you manually download the compressed package and extract it directly into the system's optional application directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Extract package to system application directory&lt;/span&gt;
&lt;span class="nb"&gt;sudo tar&lt;/span&gt; &lt;span class="nt"&gt;-xzf&lt;/span&gt; Antigravity.tar.gz &lt;span class="nt"&gt;-C&lt;/span&gt; /opt/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Troubleshooting the Linux Desktop Shortcut
&lt;/h4&gt;

&lt;p&gt;Initially, I attempted to create a standard terminal-based desktop entry using a &lt;code&gt;.desktop&lt;/code&gt; file configuration pointing to internal package assets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# NOTE: This automated script method did NOT work natively for pinning the icon/shortcut&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;' &amp;gt; ~/.local/share/applications/antigravity-ide.desktop
[Desktop Entry]
Name=Antigravity IDE
Comment=Antigravity IDE v2.0 - Experience liftoff
GenericName=IDE
Exec=/opt/Antigravity/antigravity %F
Icon=/opt/Antigravity/resources/app/resources/icon.png
Type=Application
Categories=Development;IDE;
Terminal=false
StartupWMClass=antigravity
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;update-desktop-database ~/.local/share/applications
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because the build structure handles asset routing differently (resulting in a generic gear icon or the shortcut missing from the Mint menu entirely), I verified the core application manually by calling the binary file directly from the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/opt/Antigravity/antigravity
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Final Visual Icon Solution
&lt;/h4&gt;

&lt;p&gt;To successfully map the IDE to the Linux Mint application menu with its real branding, I bypass text configurations entirely and configured it manually using the Cinnamon Desktop environment tools:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Download the official brand logo directly from the &lt;a href="https://antigravity.google/press" rel="noopener noreferrer"&gt;Antigravity Press Asset Kit&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Right-click the Linux Mint Menu button (bottom-left corner) -&amp;gt; Click &lt;strong&gt;Configure&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Navigate to the Menu tab and click Open the menu editor.&lt;/li&gt;
&lt;li&gt;Locate the Antigravity IDE entry under your designated development categories, click it, and open Properties.&lt;/li&gt;
&lt;li&gt;Click on the icon tile on the left side of the properties window, browse to your downloaded press asset image, and hit Save.&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%2Fif9e7crw0fx1k2gm4qkq.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%2Fif9e7crw0fx1k2gm4qkq.png" alt="screenshot of the Linux Mint Menu Editor properties" width="800" height="427"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A screenshot of the Linux Mint Menu Editor properties dialog box showing the Antigravity desktop entry, with the custom branded press-asset icon selected and successfully mapped.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Open the app, sign in with your Google account, and you'll land in a short onboarding flow.&lt;/p&gt;

&lt;p&gt;During onboarding, you hit the &lt;strong&gt;"Build with Google"&lt;/strong&gt; page. This is where you install &lt;strong&gt;skills and plugins&lt;/strong&gt; — essentially integrations that give your agents context about specific tools.&lt;/p&gt;

&lt;p&gt;I installed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Modern Web Guidance&lt;/strong&gt; — helps the agent reason about web development patterns and best practices&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Chrome DevTools&lt;/strong&gt; — gives the agent the ability to interact with and inspect the browser&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're migrating from the Antigravity IDE, keep the "Keep Antigravity IDE" checkbox selected — your old setup carries over cleanly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Creating a Project
&lt;/h3&gt;

&lt;p&gt;Antigravity 2.0 is &lt;strong&gt;project-centric&lt;/strong&gt;. A project is simply a folder on your local machine that the AI reads from and writes to directly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Click the + icon next to Projects
→ New Project
→ Select your cloned repo folder
→ All agent context and output is scoped to this folder
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I pointed it at my local clone of WPFAevent. From this point forward, every question I ask is answered with reference to the actual source files in that directory — not generic knowledge about WordPress plugins, but this specific codebase.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Orienting to the Codebase
&lt;/h3&gt;

&lt;p&gt;Before jumping to any specific issue, I sent an orientation prompt to get a high-level map of the project:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Give me an overview of this codebase. What does it do, how is it structured, and what are the main entry points I should know about?"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fedksooc56cm75k55nbs8.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%2Fedksooc56cm75k55nbs8.png" alt="Screenshot of codebase comparison" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Antigravity compares the actual plugin structure (&lt;code&gt;includes/cpt/&lt;/code&gt;, &lt;code&gt;includes/cache/&lt;/code&gt;) with the outdated README and correctly uses the live codebase as the source of truth.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is where the first surprise hit. The project's &lt;code&gt;README.md&lt;/code&gt; outlined a file structure containing API shortcodes like &lt;code&gt;class-event-api.php&lt;/code&gt; and &lt;code&gt;class-event-speakers.php&lt;/code&gt;. But the agent read through the directory, ignored the outdated documentation, and mapped the &lt;strong&gt;actual&lt;/strong&gt; codebase structure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;wpfaevent.php&lt;/code&gt; — Core plugin bootstrap file, registering CLI commands and calling &lt;code&gt;run_wpfaevent()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;includes/class-wpfaevent.php&lt;/code&gt; — The main orchestrator that registers Custom Post Types, taxonomies, metadata, and admin/public hooks.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;includes/cpt/&lt;/code&gt; — Declares custom post types &lt;code&gt;wpfa_event&lt;/code&gt; and &lt;code&gt;wpfa_speaker&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;includes/meta/&lt;/code&gt; &amp;amp; &lt;code&gt;includes/taxonomies/&lt;/code&gt; — Defines fields like start/end dates, locations, speaker bio details, and categories.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;includes/cache/class-wpfaevent-cache.php&lt;/code&gt; — Implements transient-like caching for page lookups (specifically the Code of Conduct page ID).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;public/templates/&lt;/code&gt; — Contains custom WordPress page templates (&lt;code&gt;page-speakers.php&lt;/code&gt;, &lt;code&gt;page-schedule.php&lt;/code&gt;, &lt;code&gt;page-past-events.php&lt;/code&gt;) which are dynamically loaded by &lt;code&gt;class-wpfaevent-landing.php&lt;/code&gt; on activation.
What would have taken me 15 minutes of head-scratching over why files mentioned in the README didn't exist took the agent 15 seconds to clarify. It immediately pointed out: &lt;em&gt;"The codebase is currently a robust skeleton relying on Custom Post Types and page templates rather than active external API endpoints."&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 4: Digging Into Real Codebase Quirks
&lt;/h3&gt;

&lt;p&gt;With the true architecture in hand, I opened up some of the file templates and started pressure-testing how Antigravity handles logical constraints.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Issue 1: Transients and Page Caching&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Because the setting page is a skeletal placeholder (&lt;code&gt;admin/class-wpfaevent-admin.php&lt;/code&gt; literally outputs a &lt;em&gt;"Plugin Skeleton Active"&lt;/em&gt; warning notice), there isn't a remote JSON API transient cache yet. However, the plugin implements a custom caching class for page routing. I prompted:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Walk me through how `class-wpfaevent-cache.php` handles transients. 
Are there any risks of stale pages serving incorrect data to users?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent analyzed &lt;code&gt;get_coc_page_id()&lt;/code&gt; and pointed out that it uses the WordPress Object Cache (&lt;code&gt;wp_cache_get&lt;/code&gt; and &lt;code&gt;wp_cache_set&lt;/code&gt; under the &lt;code&gt;wpfaevent&lt;/code&gt; group) for 1 hour. It then highlighted &lt;code&gt;clear_page_cache()&lt;/code&gt;, noting that it hooks into &lt;code&gt;save_post&lt;/code&gt; and &lt;code&gt;delete_post&lt;/code&gt; to actively invalidate the cache if a page is updated—meaning there is no risk of stale routing, though it noted that as more templates are implemented, we will need to extend this invalidation wrapper.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Issue 2: Enqueuing Styles for New Templates&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Instead of standard shortcodes, the plugin enqueues styles conditionally based on active templates to keep the footprint light. I asked:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;If I want to add a custom template for event sponsors, what is the pattern for enqueuing stylesheet assets to make sure we don't load unnecessary CSS on other pages?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent navigated to &lt;code&gt;public/class-wpfaevent-public.php&lt;/code&gt; and mapped the exact modular extension pattern:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create &lt;code&gt;public/css/templates/sponsors.css&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Add a conditional block using &lt;code&gt;is_page_template('page-sponsors.php')&lt;/code&gt; inside &lt;code&gt;enqueue_styles()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Chain the base stylesheet (&lt;code&gt;$this-&amp;gt;plugin_name&lt;/code&gt;) and navigation stylesheet as dependencies in the array parameter of &lt;code&gt;wp_enqueue_style()&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Issue 3: Multi-Day Events Sorting in page-schedule.php&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;public/templates/page-schedule.php&lt;/code&gt;, events are chronologically sorted and grouped by date. I asked:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;How does `page-schedule.php` sort events, and what happens 
if an event has a missing or invalid start date?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent walked through the &lt;code&gt;DateTimeImmutable::createFromFormat check&lt;/code&gt;, showing how it loops through expected date formats, converts them to a Unix timestamp &lt;code&gt;sort_key&lt;/code&gt;, and defaults invalid or missing dates to &lt;code&gt;PHP_INT_MAX&lt;/code&gt; (grouping them under a localized &lt;code&gt;"TBD"&lt;/code&gt; header at the very end of the schedule). &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%2Fxfhqzggm88j7bq36dx0y.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%2Fxfhqzggm88j7bq36dx0y.png" alt="Multi-Day Events Sorting in page-schedule.php" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The explanation also made the current behavior easy to reason about: events are grouped entirely by their parsed start date, while invalid or missing dates fall back to a &lt;code&gt;PHP_INT_MAX&lt;/code&gt; sort key and appear under a localized "TBD" section at the end of the schedule. This gave me enough context to evaluate edge cases and potential future improvements without manually tracing the entire sorting workflow.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Inline Comments on Artifacts
&lt;/h3&gt;

&lt;p&gt;One feature that surprised me was how naturally Antigravity handles &lt;strong&gt;iterative refinement&lt;/strong&gt;. When the agent produces an analysis artifact — say, a breakdown of what changes are needed for a fix — I can leave comments directly on that artifact, the same way you'd annotate a Google Doc.&lt;/p&gt;

&lt;p&gt;I used this to push back on one of its suggestions:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;[Comment on artifact]: "This approach modifies the API response parsing — but can we keep the change isolated to the display layer instead? I don't want to touch class-event-api.php for this."&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The agent re-read the constraint, updated its recommendation, and produced a revised approach scoped entirely to the template file. No need to rephrase the whole context in a new message.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 6: Parallel Agents for Broader Analysis
&lt;/h3&gt;

&lt;p&gt;When I had several open issues I wanted to evaluate at once, I used &lt;strong&gt;parallel conversations with work trees&lt;/strong&gt; — Antigravity's mechanism for running multiple agent threads against separate copies of the codebase simultaneously.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Work Tree&lt;/strong&gt; = a new folder containing a copy of the project, so agents can explore different issues or approaches in parallel without interfering with each other.&lt;/p&gt;

&lt;p&gt;I kicked off three parallel threads:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Thread 1 — Dependency audit:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;Check&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;composer.json&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;and&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;includes/&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;directory.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Are&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;there&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;any&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;outdated&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;dependencies&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;or&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;missing&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;requirements&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;relative&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;to&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;WordPress&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mf"&gt;5.8&lt;/span&gt;&lt;span class="err"&gt;+&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;target&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;stated&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;in&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;the&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;README?&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;→&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;New&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Work&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Tree&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Thread 2 — i18n coverage:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Review the codebase for any user-facing strings that are
not wrapped in __() or _e(). List them by file.
→ New Work Tree
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Thread 3 (main thread) — PR review:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;There are 17 open pull requests. Based on the current codebase,
which open issues do you think represent the highest-impact
and lowest-risk changes for a new contributor to start with?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;All three running simultaneously. While I reviewed the PR analysis coming back on the main thread, the dependency audit and i18n coverage checks were still running. The i18n thread came back with a list of specific files and line numbers — exactly the kind of output that's tedious to produce manually but trivial to act on.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 7: Scheduled Tasks for Ongoing Contribution
&lt;/h3&gt;

&lt;p&gt;The final feature I explored was &lt;strong&gt;Scheduled Tasks&lt;/strong&gt; — brand new to Antigravity 2.0.&lt;/p&gt;

&lt;p&gt;Scheduled tasks let you run any prompt on a recurring schedule, with the app running silently in the background even when all windows are closed. A menu bar icon shows how many agents are active.&lt;/p&gt;

&lt;p&gt;For ongoing open-source contribution, this opens up a genuinely useful workflow. I set up a task called &lt;strong&gt;"WPFAevent Issue Digest"&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Name: WPFAevent Issue Digest
Schedule: Every Monday, 8:00 AM

Prompt:
Review the current state of the WPFAevent codebase in this project folder.
Check if there are any new patterns or inconsistencies introduced since last week.
Summarize which open issues now have enough context in the codebase to act on,
and flag anything that looks like it might conflict with work already in progress.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every Monday morning, a brief lands in the app summarising where things stand — without me having to re-orient from scratch each time I come back to the project. For anyone juggling multiple open-source repos alongside their main work, this kind of ambient awareness is genuinely valuable.&lt;/p&gt;

&lt;p&gt;The same pattern applies beyond open source: PR status checks, dependency monitoring, documentation drift alerts — any recurring check you'd otherwise do manually.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Worked Well
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Speed changes the cost of asking questions.&lt;/strong&gt; Gemini 3.5 Flash at close to 800 tokens/second means there's no friction to firing off a quick question about a file you're not sure about. The low latency makes exploratory questioning feel natural rather than effortful.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Parallel agents change the math on codebase analysis.&lt;/strong&gt; Running a dependency audit, an i18n coverage check, and a PR review simultaneously — each scoped to its own work tree — compressed what would have been a multi-hour orientation into a single focused session.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inline artifact comments are intuitive.&lt;/strong&gt; Instead of rephrasing context in a new message, I could annotate the agent's analysis directly, redirect its approach, and get an updated response — exactly like commenting on a Google Doc. This interaction model clicked immediately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Voice input is underrated.&lt;/strong&gt; For longer, more nuanced questions about a codebase, speaking is faster and more natural than typing. The agent handled complex multi-part prompts accurately.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Command approval flow builds trust.&lt;/strong&gt; Knowing exactly what terminal commands the agent wants to run — and having the ability to approve, reject, or whitelist them — means you never feel like you've lost control of your machine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Self-testing via &lt;code&gt;/browser&lt;/code&gt; is a big deal.&lt;/strong&gt; For issues that involve frontend behavior, being able to ask the agent to verify its own proposed fix in a real browser — and watch it catch its own mistakes — is meaningfully more reliable than code review alone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Free model access is exceptional value.&lt;/strong&gt; Gemini 3.5 Flash, Claude Sonnet, Claude Opus, and GPT models are all accessible from the model picker in the free tier. Limited usage, but the breadth is remarkable for zero cost.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Was Challenging
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Model switching restrictions are a regression.&lt;/strong&gt; In the original Antigravity IDE, you could mix and match — Claude for one task, Codex for another, choosing the best model for the specific job. That flexibility is currently gone. You work with what Google gives you out of the box. For developers who've built workflows around model-specific strengths, this is a real limitation worth acknowledging upfront.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Early rate limits were brutal — though largely fixed.&lt;/strong&gt; In the first few days post-launch, users were hitting weekly caps after just a couple of work sessions. The backlash was significant. Google responded by tripling rate limits across paid plans, resetting quotas, and then tripling again. Paid users now have roughly 9x the original launch runway. If you tried it early and walked away frustrated, it's worth revisiting. Free tier limits remain tighter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Browser setup requires a manual step.&lt;/strong&gt; Connecting the &lt;code&gt;/browser&lt;/code&gt; agent to Chrome requires enabling Remote Debugging in Chrome — it's a two-click process, but it's not automatic. First-timers will need to follow the setup prompt before browser testing works.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sub-agent oversight can feel like a second job at scale.&lt;/strong&gt; When you have 5–10 sub-agents running simultaneously, monitoring the overview panel and approving occasional blocked actions requires attention. The UI handles this reasonably well, but it's worth being mentally prepared for — this isn't a "fire and forget" tool for complex tasks.&lt;/p&gt;




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

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Antigravity 2.0 is genuinely designed for agents&lt;/strong&gt;, not retrofitted for them. The parallel sub-agent architecture, work trees, and &lt;code&gt;/browser&lt;/code&gt; command make this feel purpose-built in a way that competing tools don't.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Codebase orientation is a first-class use case.&lt;/strong&gt; Dropping a repo into a project and asking targeted questions about architecture, issue context, and implementation gaps is one of the most practical things you can do with the tool — and one of the least talked about.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scheduled tasks turn it into an autonomous employee.&lt;/strong&gt; The ability to set recurring prompts that run in the background — even with the window closed — opens a class of use cases most AI coding tools don't address.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The free tier is a genuine on-ramp.&lt;/strong&gt; There's enough free usage to complete a real contribution session, evaluate the tool properly, and decide whether a paid plan makes sense. You don't need a credit card to form a real opinion.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Speed changes behavior.&lt;/strong&gt; When a tool responds this fast, you ask questions you'd have otherwise skipped. You explore tangents. You pressure-test assumptions before committing to an approach. The raw throughput of Gemini 3.5 Flash has real downstream effects on how you think through a problem.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Who should try it:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open-source contributors who need to understand existing codebases before diving into issues&lt;/li&gt;
&lt;li&gt;Developers onboarding onto new projects at work who want to compress the orientation phase&lt;/li&gt;
&lt;li&gt;Developers who want faster iteration cycles on complex multi-part features&lt;/li&gt;
&lt;li&gt;Developers running background research, audit, or monitoring workflows&lt;/li&gt;
&lt;li&gt;Anyone who has been waiting for a free, capable alternative to Claude Code or Codex&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Final Verdict
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Would I recommend it?&lt;/strong&gt; Yes, with awareness of the current limitations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is it production-ready?&lt;/strong&gt; For codebase analysis, contribution workflows, and sophisticated side projects — absolutely. For mission-critical production pipelines where model flexibility and guaranteed uptime matter more than cost, the rate limits and model restrictions are worth factoring in. Google has shown it responds fast to user feedback, so this calculus may shift.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What excites me most?&lt;/strong&gt; Not any single feature — it's the direction. Antigravity 2.0 is a bet that the future of software development is &lt;em&gt;orchestration&lt;/em&gt;: you describe intent, agents coordinate execution, and you stay in the loop as a reviewer and decision-maker rather than a line-by-line author. That model of working is going to win. The question is which platform it wins on.&lt;/p&gt;

&lt;p&gt;After this session, Google has a serious claim to that platform.&lt;/p&gt;

&lt;p&gt;Check it out at &lt;a href="https://antigravity.google" rel="noopener noreferrer"&gt;antigravity.google&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Tooling note
&lt;/h2&gt;

&lt;p&gt;In the spirit of transparency, here’s how I used AI while creating this post:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Antigravity 2.0.6&lt;/strong&gt; — used directly for codebase review and issue analysis on the WPFAevent repository.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Claude Sonnet 4.6&lt;/strong&gt; — used to help structure and refine the written draft of this article.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GPT-5.5&lt;/strong&gt; — used to generate the cover image concept and visuals.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All hands-on testing, observations, and conclusions in this post are based on my own experience using Antigravity during this review workflow.&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://antigravity.google/" rel="noopener noreferrer"&gt;https://antigravity.google/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://antigravity.google/press" rel="noopener noreferrer"&gt;https://antigravity.google/press&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/live/wYSncx9zLIU?si=V0cl54qjbeIKPfIk" rel="noopener noreferrer"&gt;https://www.youtube.com/live/wYSncx9zLIU?si=V0cl54qjbeIKPfIk&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/6C0FjHoN3qE?si=is1s4sbVy_6DQYSJ" rel="noopener noreferrer"&gt;https://youtu.be/6C0FjHoN3qE?si=is1s4sbVy_6DQYSJ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://youtu.be/-dwLbaCB-_I?si=D3_TljUStE4v2NOP" rel="noopener noreferrer"&gt;https://youtu.be/-dwLbaCB-_I?si=D3_TljUStE4v2NOP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/fossasia/WPFAevent" rel="noopener noreferrer"&gt;https://github.com/fossasia/WPFAevent&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>googleio</category>
      <category>ai</category>
      <category>opensource</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Build Your Own Lab: Virtualization for DevOps Beginners</title>
      <dc:creator>Ubayed Bin Sufian</dc:creator>
      <pubDate>Sun, 10 May 2026 02:04:52 +0000</pubDate>
      <link>https://dev.to/ubayedbinsufian/build-your-own-lab-virtualization-for-devops-beginners-1fac</link>
      <guid>https://dev.to/ubayedbinsufian/build-your-own-lab-virtualization-for-devops-beginners-1fac</guid>
      <description>&lt;h3&gt;
  
  
  What We'll cover?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Setting up your lab (laptop vs cloud)&lt;/li&gt;
&lt;li&gt;Virtual Box

&lt;ul&gt;
&lt;li&gt;Deploying VMs&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;




&lt;h3&gt;
  
  
  Setting Up a Lab on Your Laptop
&lt;/h3&gt;

&lt;p&gt;There are two main options for practicing DevOps: set up a lab on your local machine, or spin up cloud VMs on AWS, Azure, or GCP.&lt;/p&gt;

&lt;p&gt;We will focus on the home lab — using a laptop or desktop you already own. It gives you full control, costs nothing extra, and you can use virtualization software like VirtualBox to create and manage virtual machines right on your hardware. &lt;/p&gt;

&lt;h4&gt;
  
  
  What Is a Home Lab, and What Can You Do in It?
&lt;/h4&gt;

&lt;p&gt;Imagine your laptop is a studio apartment. Now imagine you're trying to run a full restaurant kitchen, a woodworking shop, and a recording studio — all in that same apartment. Things are going to get messy.&lt;/p&gt;

&lt;p&gt;That's what happens when you install every DevOps tool directly on your machine: Git, Jenkins, Docker, Kubernetes, Ansible, Python, Java, Node.js, Apache, Nginx, MySQL, MongoDB, AWS CLI, Ubuntu, CentOS... they all start stepping on each other. Different versions conflict. Something breaks. You don't know what you did. You're afraid to change anything.&lt;/p&gt;

&lt;p&gt;Virtual machines are the solution. Think of each VM as a separate apartment in the same building. Same physical hardware underneath, but completely isolated from each other. If one apartment burns down (a VM breaks), the others are fine. You just rebuild that one.&lt;/p&gt;

&lt;p&gt;With VMs you can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run different OS versions (Ubuntu, CentOS, Red Hat) side by side&lt;/li&gt;
&lt;li&gt;Isolate tools and projects so they never interfere&lt;/li&gt;
&lt;li&gt;Snapshot a working state and roll back if something goes wrong&lt;/li&gt;
&lt;li&gt;Delete and recreate freely — no fear&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Virtualization software
&lt;/h3&gt;

&lt;p&gt;Virtualization software (also called a &lt;strong&gt;hypervisor&lt;/strong&gt;) sits between your physical hardware and your virtual machines, letting multiple operating systems run on the same machine simultaneously. &lt;/p&gt;

&lt;p&gt;There are two types:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Type 1 — Bare-metal Hypervisor&lt;/strong&gt;: This runs directly on the hardware, with no host OS underneath. Think of it as the hypervisor &lt;em&gt;being&lt;/em&gt; the operating system. Examples: VMware ESXi, Microsoft Hyper-V, Xen. These are used in enterprise environments where you need high performance and dozens (or hundreds) of VMs. They're powerful, but expensive and complex. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Type 2 — Hosted Hypervisor&lt;/strong&gt;: This runs on top of your regular OS (host) — like any other application you install. Examples: Oracle VirtualBox, VMware Workstation, Parallels Desktop. These are perfect for home labs and development environments. Easier to set up, free or cheap, and more than capable for learning. However, they may have performance overhead due to running on top of a host operating 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%2Fbasmsdybi69s01jm8xtg.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%2Fbasmsdybi69s01jm8xtg.png" alt="Type 1 and Type 2 hypervisor" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Reference: &lt;a href="https://www.facebook.com/photo/?fbid=122115084969253388&amp;amp;set=gm.1847442505941341&amp;amp;idorvanity=192962784722663" rel="noopener noreferrer"&gt;https://www.facebook.com/photo/?fbid=122115084969253388&amp;amp;set=gm.1847442505941341&amp;amp;idorvanity=192962784722663&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We will be using Type 2 hypervisor, specifically Oracle VirtualBox, for our home lab environment. &lt;/p&gt;

&lt;p&gt;Here's a quick comparison if you're choosing between the two popular options:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Oracle VirtualBox&lt;/th&gt;
&lt;th&gt;VMware Workstation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Cost&lt;/td&gt;
&lt;td&gt;Free and open-source&lt;/td&gt;
&lt;td&gt;Paid (free trial available)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Platform Support&lt;/td&gt;
&lt;td&gt;Windows, macOS, Linux&lt;/td&gt;
&lt;td&gt;Windows, Linux&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Performance&lt;/td&gt;
&lt;td&gt;Good for most use cases&lt;/td&gt;
&lt;td&gt;Better for resource-intensive tasks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;User Interface&lt;/td&gt;
&lt;td&gt;Simple and intuitive&lt;/td&gt;
&lt;td&gt;More advanced features&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Snapshot &amp;amp; Cloning&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Resource Management&lt;/td&gt;
&lt;td&gt;Good&lt;/td&gt;
&lt;td&gt;Advanced&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  Installing VirtualBox on Linux Mint 22.3 (Zena)
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;For Windows and macOS installation, refer to the YouTube video in the Reference section below.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I use Linux Mint, so I'll walk through that. You can check your OS details with:&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;cat&lt;/span&gt; /etc/os-release
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Linux Mint 22.3 is based on Ubuntu 24.04 LTS (&lt;code&gt;noble&lt;/code&gt;), so we use the &lt;code&gt;noble&lt;/code&gt; VirtualBox repository.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1 — Add the Oracle VirtualBox repository key:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wget &lt;span class="nt"&gt;-O-&lt;/span&gt; https://www.virtualbox.org/download/oracle_vbox_2016.asc | &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;gpg &lt;span class="nt"&gt;--yes&lt;/span&gt; &lt;span class="nt"&gt;--output&lt;/span&gt; /usr/share/keyrings/oracle-virtualbox-2016.gpg &lt;span class="nt"&gt;--dearmor&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2 — Add the repository:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"deb [arch=amd64 signed-by=/usr/share/keyrings/oracle-virtualbox-2016.gpg] https://download.virtualbox.org/virtualbox/debian noble contrib"&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nb"&gt;sudo tee&lt;/span&gt; /etc/apt/sources.list.d/virtualbox.list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3 — Install VirtualBox:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get update
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;virtualbox-7.1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4 — Verify the installation:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;For the latest version and other Linux distributions, check the official site: &lt;a href="https://www.virtualbox.org/wiki/Linux_Downloads" rel="noopener noreferrer"&gt;https://www.virtualbox.org/wiki/Linux_Downloads&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Setting Up Your First VM in VirtualBox
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Open VirtualBox from your applications menu.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Click &lt;strong&gt;New&lt;/strong&gt; to create a virtual machine.&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%2F2hyfkchaewsx0an20v6i.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%2F2hyfkchaewsx0an20v6i.png" alt="VM creation" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Follow the prompts — choose your OS, allocate memory (at least 2GB recommended for Linux, though 1GB works for lightweight setups), and set up a virtual hard disk.&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%2Fvegl4h3nzg27hud2i5fw.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%2Fvegl4h3nzg27hud2i5fw.png" alt="Base memory and CPU" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You have two options here: install the OS manually via an ISO (like inserting a CD), or use a &lt;strong&gt;pre-configured VM image&lt;/strong&gt; that already has the OS installed. I prefer the second approach — it saves time. You can find pre-built images at &lt;a href="https://www.osboxes.org/" rel="noopener noreferrer"&gt;osboxes.org&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Download the &lt;code&gt;.7z&lt;/code&gt; file from osboxes.org, extract it, and you'll get a &lt;code&gt;.vmdk&lt;/code&gt; file — that's the virtual hard disk.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When the wizard asks for a hard disk, select &lt;strong&gt;"Use an existing virtual hard disk file"&lt;/strong&gt; and point it to the &lt;code&gt;.vmdk&lt;/code&gt; file you extracted.&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%2Fdq2t89t53jqbiz3w0nxl.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%2Fdq2t89t53jqbiz3w0nxl.png" alt="Virtual Hard Disk" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Before starting the VM, right-click it → &lt;strong&gt;Settings&lt;/strong&gt; → &lt;strong&gt;Network&lt;/strong&gt; → set the adapter to &lt;strong&gt;Bridged Adapter&lt;/strong&gt;. This allows the VM to connect to the same network as your host machine and enable the VM to have its own IP address and access the internet.&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%2Fd182fghvg6dree3og6m8.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%2Fd182fghvg6dree3og6m8.png" alt="Network selection" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Once the virtual machine is created, start in Normal Start.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Log in with the default credentials from osboxes.org (username: &lt;code&gt;osboxes&lt;/code&gt;, password: &lt;code&gt;osboxes.org&lt;/code&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%2Ffwc3a2x3ujpaoktz2koh.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%2Ffwc3a2x3ujpaoktz2koh.png" alt="Boot up" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Connecting to Your VM
&lt;/h3&gt;

&lt;p&gt;Now your VM is running. But how do you actually &lt;em&gt;talk&lt;/em&gt; to it?&lt;/p&gt;

&lt;p&gt;Think of VMs like tenants in a building. Just because they share the same physical building (your laptop) doesn't mean they can walk into each other's apartments freely. They need proper addresses and open doors.&lt;/p&gt;

&lt;h4&gt;
  
  
  Three Ways to Start a VM
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Normal Start&lt;/strong&gt; — Opens a console window with the VM's UI. Closing the window shuts down the VM. Good for initial setup.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Headless Start&lt;/strong&gt; — VM runs in the background with no window. You access it only via SSH or remote desktop. This is the DevOps way. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Detachable Start&lt;/strong&gt; — Like Normal Start, but closing the console window doesn't shut down the VM. It keeps running in the background.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu6clo3t1cr1dnavpm7yq.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%2Fu6clo3t1cr1dnavpm7yq.png" alt="Normal mode" width="720" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  SSH Into a Linux VM
&lt;/h4&gt;

&lt;p&gt;For Linux guest VMs, SSH is your main tool. For Windows guests, you'd use Remote Desktop (RDP).&lt;/p&gt;

&lt;p&gt;The VM needs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;An IP address assigned&lt;/li&gt;
&lt;li&gt;SSH service running
Use the console window to do your initial configuration first — get the IP set, start SSH. After that, you can switch to your host terminal for everything else.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Even the vms are within our laptop (host) think of them as separate machines connected to the same network so whatever you need for one system to connect to another system you would need these vms configured with ip addresses and the relevant services must be configured and running on. On windows, the remote desktop service needs to be running and on linux the ssh service needs to be running so make sure ssh server is installed and is in a running state in the vm (guest system). If configured you can ssh into the vm from the host system using the terminal on the host and the ip address of the remote vm.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check SSH status on the VM&lt;/span&gt;
service sshd status

&lt;span class="c"&gt;# Start SSH if it's not running&lt;/span&gt;
service sshd start
&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%2Fc82p8j8xyd9sstk9fa8e.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%2Fc82p8j8xyd9sstk9fa8e.png" alt="start sshd" width="720" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To SSH in from your host machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh username@ip_address
&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%2Fj8zncxuwfsijxqm23qn7.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%2Fj8zncxuwfsijxqm23qn7.png" alt="ssh using ip_addr" width="800" height="426"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you can't connect, check these first:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does the VM have an IP address?&lt;/li&gt;
&lt;li&gt;Are you using the correct IP?&lt;/li&gt;
&lt;li&gt;Is the SSH service running on the VM?&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Networking: Bridged vs NAT
&lt;/h2&gt;

&lt;p&gt;This is where a lot of beginners get confused. Let's use an analogy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bridged Adapter&lt;/strong&gt; is like giving your VM its own room in the house with its own doorbell. It gets a real IP address on your network. Anyone on your local network can reach it. SSH is straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh username@vm_ip_address
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;NAT (Network Address Translation)&lt;/strong&gt; is like the VM living in a back room with no direct doorbell — it can call out (access the internet), but nobody outside can call in directly. If you have multiple NAT VMs, they're also isolated from each other (they all get the same internal IP and can't see each other).&lt;/p&gt;

&lt;p&gt;To SSH into a NAT VM, you need &lt;strong&gt;port forwarding&lt;/strong&gt; — you tell VirtualBox: "whenever someone knocks on my host machine's port 2222, forward that knock to port 22 on the VM."&lt;/p&gt;

&lt;p&gt;Set it up in VirtualBox:&lt;br&gt;
&lt;strong&gt;Settings → Network → Advanced → Port Forwarding → Add Rule&lt;/strong&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Protocol&lt;/th&gt;
&lt;th&gt;Host Port&lt;/th&gt;
&lt;th&gt;Guest Port&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ssh&lt;/td&gt;
&lt;td&gt;TCP&lt;/td&gt;
&lt;td&gt;2222&lt;/td&gt;
&lt;td&gt;22&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;(We use port 2222 on the host because port 22 is already used by the host's own SSH service.)&lt;/p&gt;

&lt;p&gt;Then SSH in using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ssh username@127.0.0.1 &lt;span class="nt"&gt;-p&lt;/span&gt; 2222
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;This is part of my DevOps Prerequisite series:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://dev.to/ubayedbinsufian/devops-prerequisite-linux-basics-you-actually-need-47pe"&gt;DevOps Prerequisite #1: Linux Basics You Actually Need&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Build Your Own Lab: Virtualization for DevOps Beginners (this post)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Why Vagrant Still Matters (and When It Doesn’t) (next)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Networking for DevOps: The Only Concepts You Need&lt;/li&gt;
&lt;li&gt;YAML Explained for Future DevOps Engineers&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Disclaimer: I have used GH copilot for writing the topics, Gemini Nano Banana for image generation, ChatGPT for the html snippet &amp;amp; other concepts and Claude for fine tuning the entire blog.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference:&lt;/strong&gt;&lt;br&gt;
💡 Want a visual walkthrough?&lt;br&gt;
This video does a great job explaining the basics covered here. Use it as a supplement—not a replacement:   &lt;iframe src="https://www.youtube.com/embed/Wvf0mBNGjXY?start=2256"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>devops</category>
      <category>linux</category>
      <category>virtualmachine</category>
      <category>networking</category>
    </item>
    <item>
      <title>Linux Services Made Simple: Create, Control, and Remove Your First systemd Service</title>
      <dc:creator>Ubayed Bin Sufian</dc:creator>
      <pubDate>Tue, 05 May 2026 18:45:21 +0000</pubDate>
      <link>https://dev.to/ubayedbinsufian/linux-services-made-simple-create-control-and-remove-your-first-systemd-service-3aa2</link>
      <guid>https://dev.to/ubayedbinsufian/linux-services-made-simple-create-control-and-remove-your-first-systemd-service-3aa2</guid>
      <description>&lt;h2&gt;
  
  
  Linux as a service (The simplest Way to Understand It)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A service is just a program that runs in the background&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;systemctl&lt;/code&gt; is the tool to control it&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;systemd&lt;/code&gt; is the system that manages services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Simple analogy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Think of a service like a car 🚗:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can start it&lt;/li&gt;
&lt;li&gt;You can stop it&lt;/li&gt;
&lt;li&gt;You can check if it’s running&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The systemd is like the engine that keeps the car running smoothly behind the scenes.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you'll learn
&lt;/h2&gt;

&lt;p&gt;By the end of this, you’ll be able to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create your own service&lt;/li&gt;
&lt;li&gt;Start / stop it using &lt;code&gt;systemctl&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Enable / disable it at boot&lt;/li&gt;
&lt;li&gt;Delete it cleanly (no leftover mess)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1: Create a simple script
&lt;/h2&gt;

&lt;p&gt;Create a file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nano ~/my_simple_service.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Paste this content:&lt;br&gt;
&lt;/p&gt;

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

&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;true
&lt;/span&gt;&lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Hello! Service is running..."&lt;/span&gt;
  &lt;span class="nb"&gt;sleep &lt;/span&gt;5
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Ctrl + O&lt;/code&gt; --&amp;gt; Enter&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Ctrl + X&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x ~/my_simple_service.sh
&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%2Fv5c3d85so4picwxmkad4.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%2Fv5c3d85so4picwxmkad4.png" alt="Create a simple script" width="800" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Create a systemd service
&lt;/h2&gt;

&lt;p&gt;Now we tell &lt;strong&gt;systemd&lt;/strong&gt; how to run our script.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Paste this:&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="o"&gt;[&lt;/span&gt;Unit]
&lt;span class="nv"&gt;Description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;My Simple Demo Service

&lt;span class="o"&gt;[&lt;/span&gt;Service]
&lt;span class="nv"&gt;ExecStart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/home/&lt;span class="nv"&gt;$USER&lt;/span&gt;/my-simple-service.sh
&lt;span class="nv"&gt;Restart&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;always

&lt;span class="o"&gt;[&lt;/span&gt;Install]
&lt;span class="nv"&gt;WantedBy&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;multi-user.target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 Replace &lt;code&gt;/home/your-username&lt;/code&gt; with your actual username&lt;br&gt;
(Don’t use &lt;code&gt;$USER&lt;/code&gt; here — systemd won’t expand it properly)&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 3: Reload systemd and start the service
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl daemon-reload
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start my-simple.service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Step 4: Check status
&lt;/h2&gt;


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

&lt;/div&gt;


&lt;p&gt;You should see the service running.&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%2Faoptcm5e6v13bz0vgisz.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%2Faoptcm5e6v13bz0vgisz.png" alt="Create a systemd service" width="800" height="329"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 5: Stop the service
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl stop my-simple.service
&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%2Fgimzjjf5jinknsnfvf43.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%2Fgimzjjf5jinknsnfvf43.png" alt="stop the service" width="800" height="196"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 6: Enable / Disable (auto-start on boot)
&lt;/h2&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;my-simple.service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl disable my-simple.service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 7: View logs (while service is running)
&lt;/h2&gt;



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

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;-f&lt;/code&gt; - follow (like &lt;code&gt;tail -f&lt;/code&gt;)&lt;/p&gt;

&lt;p&gt;You should see:&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="s2"&gt;"Hello! Service is running..."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;…repeating every 5 seconds. &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%2Fa88sts6h2i8i4zx0pghs.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%2Fa88sts6h2i8i4zx0pghs.png" alt="View logs while service is running" width="800" height="218"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stop the service&lt;/strong&gt;: &lt;code&gt;sudo systemctl stop my-simple.service&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;View logs again&lt;/strong&gt;: &lt;code&gt;sudo journalctl -u my-simple.service&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You will only see past logs (no new updates).&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%2Ff8xm9ej880ip6pg4mxcp.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%2Ff8xm9ej880ip6pg4mxcp.png" alt="view logs when service is not running" width="800" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 8: Clean up (Delete everything properly)
&lt;/h2&gt;

&lt;p&gt;[CAUTION: PLEASE BE CAREFUL WHEN DELETING THE SERVICE FILES SO WE DO NOT DELETE ANY SYSTEM FILES]&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl stop my-simple.service
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl disable my-simple.service
&lt;span class="nb"&gt;sudo rm&lt;/span&gt; /etc/systemd/system/my-simple.service
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl daemon-reload
&lt;span class="nb"&gt;sudo rm&lt;/span&gt; ~/my_simple_service.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now your system is back to a clean state—no leftover services, no hidden issues.&lt;/p&gt;

&lt;p&gt;You just created and managed your first Linux service from scratch 🎉&lt;/p&gt;

&lt;p&gt;This is a small step—but it’s exactly how real-world services (like web servers and databases) are managed in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  Flow Diagram
&lt;/h2&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%2Fobtkbuw0zoxiiytbhzxw.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%2Fobtkbuw0zoxiiytbhzxw.png" alt="How Systemd works" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclaimer: I have used GH copilot for writing the topics, Gemini Nano Banana for image generation and ChatGPT for the flow diagram and other concepts.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>linux</category>
      <category>devops</category>
      <category>systemdesign</category>
      <category>beginners</category>
    </item>
    <item>
      <title>DevOps Prerequisite: Linux Basics You Actually Need</title>
      <dc:creator>Ubayed Bin Sufian</dc:creator>
      <pubDate>Fri, 01 May 2026 01:24:51 +0000</pubDate>
      <link>https://dev.to/ubayedbinsufian/devops-prerequisite-linux-basics-you-actually-need-47pe</link>
      <guid>https://dev.to/ubayedbinsufian/devops-prerequisite-linux-basics-you-actually-need-47pe</guid>
      <description>&lt;p&gt;Most DevOps roadmaps look like a never-ending checklist—tools, technologies, and concepts thrown at you all at once.&lt;/p&gt;

&lt;p&gt;If you're from a non-IT background or just starting out, it is easy to feel stuck thinking: “Where do I even begin?”&lt;/p&gt;

&lt;p&gt;I’ve been there.&lt;/p&gt;

&lt;p&gt;That’s why I’m starting this DevOps Prerequisite series to break things down into simple, practical steps that actually matter.&lt;/p&gt;

&lt;p&gt;In this first part, we will focus on the one skill that quietly powers almost everything in DevOps: &lt;strong&gt;Linux and Vi editor&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Not everything, just the &lt;strong&gt;Linux basics&lt;/strong&gt; you actually need to get started and build confidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic Linux Commands
&lt;/h2&gt;

&lt;p&gt;According to the Stack Overflow Developer Survey 2024, Linux is the most commonly used operating system among developers, and it's also one of the most loved. Most of the industry tools and platforms are built on Linux, making it essential for DevOps professionals to have a good understanding of Linux commands and operations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Shell Types
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Bourne Shell (sh)&lt;/strong&gt;: The original Unix shell, which is still widely used for scripting.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C Shell (csh/tcsh)&lt;/strong&gt;: Known for its C-like syntax, often used in interactive use.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Z Shell (zsh)&lt;/strong&gt;: An extended version of the Bourne Shell with many improvements, popular among developers for its features and customization options.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bourne Again Shell (bash)&lt;/strong&gt;: The most widely used shell, which is an enhanced version of the Bourne Shell, offering features like command history and job control.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;echo $SHELL&lt;/code&gt; - This command will display the current shell being used.&lt;/p&gt;

&lt;h3&gt;
  
  
  Basic Commands
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;echo &amp;lt;message&amp;gt;&lt;/code&gt;: Prints the message to the terminal. Also used to display the value of environment variables. In scripts and configuration files, it can be used to print information or debug messages.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ls&lt;/code&gt;: Lists files and directories.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cd&lt;/code&gt;: Change directory.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;pwd&lt;/code&gt;: Print working directory.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mkdir&lt;/code&gt;: Create a new directory.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cd new_dir; mkdir sub_dir; pwd&lt;/code&gt;: Multiple commands in one line. &lt;em&gt;;&lt;/em&gt; is used to separate commands, allowing you to execute them sequentially.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcpsa664q5dmsj38v7nbh.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%2Fcpsa664q5dmsj38v7nbh.png" alt="Basic linux commands" width="800" height="184"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Directory Management
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;To create a dir hierarchy asia/bangladesh/dhaka:

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;mkdir asia&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mkdir asia/bangladesh&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;mkdir asia/bangladesh/dhaka&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;[To create the dir hierarchy in one line]&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;mkdir -p asia/bangladesh/dhaka&lt;/code&gt; (using &lt;em&gt;-p&lt;/em&gt; flag to create parent directories if they don't exist)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rm -r asia&lt;/code&gt;: Remove a directory and its contents recursively.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cp -r my_dir /tmp/my_dir_copy&lt;/code&gt;: Copy a directory and its contents recursively.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fan1qbf3tn9y1dnjj3rua.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%2Fan1qbf3tn9y1dnjj3rua.png" alt="Create dir hierarchy step-by-step" width="800" height="396"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fotwswlbjayqcxp3xugih.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%2Fotwswlbjayqcxp3xugih.png" alt="Create dir hierarchy in a single command and delete it" width="800" height="241"&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%2Fi1kflcuekhdexrdg9ud2.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%2Fi1kflcuekhdexrdg9ud2.png" alt="Copy dir contents recursively" width="800" height="245"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  File Management
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;touch file1.txt&lt;/code&gt;: Create an empty file or update the timestamp of an existing file.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cat &amp;gt; file2.txt&lt;/code&gt;:  After running this command, the prompt will appear and you can type the content. Hit the Enter key for a new line and press &lt;code&gt;Ctrl + D&lt;/code&gt; to save and exit.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cat file2.txt&lt;/code&gt;: Display the content of the file.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cp file2.txt dir&lt;/code&gt;: Copy a file to a new location.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mv dir/file2.txt dir/sub_dir&lt;/code&gt;: Move or rename a file. To rename a file, you can use the same command with the new name in the same directory, e.g., &lt;code&gt;mv file.txt new_file.txt&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rm my_dir.txt&lt;/code&gt;: Remove a file.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvtb336bjxxbcu64s2hxq.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%2Fvtb336bjxxbcu64s2hxq.png" alt="File management" width="800" height="218"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  User Management
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;whoami&lt;/code&gt;: Display the current user.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;id&lt;/code&gt;: Display user ID and group information.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;su username&lt;/code&gt;: Switch to another user account. You will be prompted to enter the password for the specified user. Same machine, different user.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ssh username@hostname&lt;/code&gt;: Connect to a remote server using SSH. You will be prompted to enter the password for the specified user on the remote server. Different machine, login remotely.&lt;/li&gt;
&lt;li&gt;Every linux system has a super user called the &lt;strong&gt;root user&lt;/strong&gt;. The root user has full administrative privileges and can perform any action on the system. In production or enterprise environments, acces to root user is often restricted for security reasons, and users are given specific permissions to perform their tasks. &lt;/li&gt;
&lt;li&gt;If a normal user needs to perform administrative tasks, they can use the &lt;code&gt;sudo&lt;/code&gt; command to execute commands with elevated privileges such as installing software, modifying system configurations, or managing user accounts. The root user can grant them sudo privileges by adding their username into the &lt;strong&gt;/etc/sudoers&lt;/strong&gt; file or by adding them to a group that has sudo privileges (e.g., the "sudo" group on Debian-based systems). Now, the user can run commands with &lt;code&gt;sudo&lt;/code&gt; to perform administrative tasks without needing to log in as the root user. The user needs to enter their own password to confirm the action, and the system will log the command for auditing purposes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffounvjgfyn1iu0srbli4.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%2Ffounvjgfyn1iu0srbli4.png" alt="User management" width="800" height="118"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Download files
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;curl -O https://www.digitalocean.com/robots.txt&lt;/code&gt;: Download a file from the specified URL and save it with the custom name. Without the &lt;em&gt;-o&lt;/em&gt; flag, the content will be displayed in the terminal instead of being saved to a file. &lt;code&gt;curl&lt;/code&gt;; "Client URL".&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;wget https://example.com/file.txt -O file.txt&lt;/code&gt;: Download a file from the specified URL and save it with a custom name. &lt;code&gt;wget&lt;/code&gt;; "World Wide Web get".&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmontm36pprcvghd4wh1c.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%2Fmontm36pprcvghd4wh1c.png" alt="Download files commands" width="800" height="340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Check OS version
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;ls /etc/*release*&lt;/code&gt;: This command lists the contents of the /etc directory that match the pattern &lt;em&gt;release&lt;/em&gt;, which typically includes files that contain information about the operating system version and distribution. The output may vary depending on the Linux distribution being used, but it often includes files like &lt;code&gt;os-release&lt;/code&gt;, &lt;code&gt;lsb-release&lt;/code&gt;, or &lt;code&gt;redhat-release&lt;/code&gt; that provide details about the OS version, name, and other relevant information.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cat /etc/*release*&lt;/code&gt;: This command displays the contents of the files in the /etc directory that match the pattern &lt;em&gt;release&lt;/em&gt;. These files usually contain information about the operating system version and distribution. By running this command, you can see details such as the OS name, version number, and other relevant information about the Linux distribution you are using.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fal03ltuy737843muve0e.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%2Fal03ltuy737843muve0e.png" alt="Check OS version" width="800" height="275"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Package Managers
&lt;/h3&gt;

&lt;p&gt;Package managers are tools that automate the process of installing, updating, configuring, and removing software packages on a computer. They help manage dependencies and ensure that the correct versions of software are installed. Different Linux distributions use different package managers. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Debian-based distributions (like Ubuntu) use &lt;code&gt;apt&lt;/code&gt; (Advanced Package Tool).&lt;/li&gt;
&lt;li&gt;Red Hat-based distributions (like CentOS, Fedora) use &lt;code&gt;yum&lt;/code&gt; or &lt;code&gt;dnf&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Arch Linux uses &lt;code&gt;pacman&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  apt (Advanced Package Tool)
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;apt&lt;/code&gt; is a package manager used in Debian-based Linux distributions that provides a high-level interface for managing software packages. It automatically resolves dependencies and allows you to easily install, update, and remove software packages. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;apt install package_name&lt;/code&gt;: Install a package along with its dependencies.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;apt remove package_name&lt;/code&gt;: Remove a package.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;apt update&lt;/code&gt;: Update the package index to get the latest information about available packages.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;apt upgrade&lt;/code&gt;: Upgrade all installed packages to their latest versions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwi979s1d7gtpot7zyzh8.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%2Fwi979s1d7gtpot7zyzh8.png" alt="apt" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Red Hat Package Manager (RPM)
&lt;/h4&gt;

&lt;p&gt;A software is bundled into a package file with the .rpm extension. The &lt;code&gt;rpm&lt;/code&gt; command is used to manage these packages, allowing you to install, update, remove, and query software on your system. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;rpm -i package.rpm&lt;/code&gt;: Install a package.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rpm -e package_name&lt;/code&gt;: Remove a package.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rpm -q package_name&lt;/code&gt;: Query if a package is installed. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It does not resolve dependencies automatically, so you may need to manually install any required packages before installing the main package. For example, if you try to install ansible using &lt;code&gt;rpm -i ansible.rpm&lt;/code&gt; and it has dependencies like &lt;code&gt;python3&lt;/code&gt; and &lt;code&gt;python3-pip&lt;/code&gt;, you would need to install those dependencies first before installing ansible.&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%2Fyksrtzukm3sg3obztxy4.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%2Fyksrtzukm3sg3obztxy4.png" alt="Red Hat Package Manager" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  yum (Yellowdog Updater, Modified)
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;yum&lt;/code&gt; is a high level package manager used in Red Hat-based Linux distributions that uses RPM under the hood. It automatically resolves dependencies and allows you to easily install, update, and remove software packages. It searches software repositories that act as warehouses containing rpm packages. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;yum install package_name&lt;/code&gt;: Install a package along with its dependencies.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;yum remove package_name&lt;/code&gt;: Remove a package.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;yum update package_name&lt;/code&gt;: Update a package to the latest version.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;How does yum find where a particular is located?&lt;/em&gt; It looks into the repository configuration files located in &lt;code&gt;/etc/yum.repos.d/&lt;/code&gt; directory. These files contain information about the repositories, including their URLs and the packages they contain. When you run a yum command, it checks these repositories for the requested package and its dependencies, and then downloads and installs them as needed. At times, the default set of repos may not have the software you need or may not have the latest version. So you need to configure additional repositories so yum can find those packages. Instructions to configure additional repositories are usually provided on the software vendor's website. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;yum repolist&lt;/code&gt;: List all configured repositories and their status (enabled/disabled).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ls /etc/yum.repos.d/&lt;/code&gt;: List the repository configuration files in the yum.repos.d directory. Each file corresponds to a repository and contains information about its name, base URL, and other settings. By checking these files, you can see which repositories are configured on your system and where yum will look for packages when you run installation or update commands.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cat /etc/yum.repos.d/&amp;lt;repo_file&amp;gt;.repo&lt;/code&gt;: Display the contents of a specific repository configuration file. This file contains details about the repository, such as its name, base URL, and whether it is enabled or disabled. By examining this file, you can understand where yum will look for packages when you run installation or update commands, and you can also modify the repository settings if needed.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;yum list &amp;lt;package_name&amp;gt;&lt;/code&gt;: Check if a specific package is available in the configured repositories. &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;yum --showduplicates list &amp;lt;package_name&amp;gt;&lt;/code&gt;: Check for all available versions of a specific package in the configured repositories. This command will show you all the versions of the package that are available for installation, allowing you to choose which version you want to install or update to.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F74pd9z2wj44kw9w6l515.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%2F74pd9z2wj44kw9w6l515.png" alt="yum" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Services
&lt;/h3&gt;

&lt;p&gt;Services are background processes that run on a server to provide specific functionality, such as web hosting, database management, or file sharing.&lt;/p&gt;

&lt;p&gt;Once software that runs in the background (e.g., web servers, databases) is installed, it needs to keep running reliably even after a reboot. Services ensure that these programs start automatically and in the correct order. For example, a database service should start before a web server that depends on it. Most background software is configured as a service during installation.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;service &amp;lt;service_name&amp;gt; start&lt;/code&gt;    : Start a service. (old command, still works in some distros)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;systemctl start &amp;lt;service_name&amp;gt;&lt;/code&gt;  : Start a service. (new command, used in most modern distros)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;systemctl stop &amp;lt;service_name&amp;gt;&lt;/code&gt;   : Stop a service.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;systemctl status &amp;lt;service_name&amp;gt;&lt;/code&gt; : Check the status of a service (whether it's running or not).&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;systemctl enable &amp;lt;service_name&amp;gt;&lt;/code&gt; : Enable a service to start automatically at boot time.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;systemctl disable &amp;lt;service_name&amp;gt;&lt;/code&gt;: Disable a service from starting automatically at boot time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  How to configure a software/program as a service?
&lt;/h4&gt;

&lt;p&gt;Most modern Linux distributions use systemd to manage services. Each service is defined using a unit file, which is a configuration file (with a &lt;code&gt;.service&lt;/code&gt; extension) typically located in &lt;code&gt;/etc/systemd/system/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Steps to configure a software as a systemd service:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a unit file for the service. For example, if you want to create a service for a web application called "myapp", you would create a file named &lt;code&gt;myapp.service&lt;/code&gt; in the &lt;code&gt;/etc/systemd/system/&lt;/code&gt; directory.&lt;/li&gt;
&lt;li&gt;To add additional metadata about the service, such as a description or dependencies, you can include a &lt;code&gt;[Unit]&lt;/code&gt; section in the unit file.&lt;/li&gt;
&lt;li&gt;Define a section caled &lt;code&gt;[Service]&lt;/code&gt; in the unit file, where you specify the command to start the service and directive named &lt;code&gt;ExecStart&lt;/code&gt; to specify the command that will be executed to start the service. If the application has other dependencies, commands or scripts to run before or after starting the main application, you can specify them using directives like &lt;code&gt;ExecStartPre&lt;/code&gt; or &lt;code&gt;ExecStartPost&lt;/code&gt;. If the app needs to be restarted if it crashes, you can use the &lt;code&gt;Restart&lt;/code&gt; directive. &lt;/li&gt;
&lt;li&gt;To configure the service to start automatically at boot time, define a section called &lt;code&gt;[Install]&lt;/code&gt; in the unit file. In this section, you can specify the target that the service should be associated with using the &lt;code&gt;WantedBy&lt;/code&gt; directive. For example, if you want the service to start when the system reaches the multi-user target (which is a common target for services), you would add the following lines to the unit file.&lt;/li&gt;
&lt;li&gt;After defining the &lt;code&gt;[Install]&lt;/code&gt; section, you can enable the service to start at boot time using the &lt;code&gt;systemctl&lt;/code&gt; command: &lt;code&gt;sudo systemctl enable myapp.service&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Save the unit file and reload the systemd manager configuration to recognize the new service: &lt;code&gt;sudo systemctl daemon-reload&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Start the service using the &lt;code&gt;systemctl&lt;/code&gt; command: &lt;code&gt;sudo systemctl start myapp.service&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;Stop the service using the &lt;code&gt;systemctl&lt;/code&gt; command: &lt;code&gt;sudo systemctl stop myapp.service&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Check the status of the service: &lt;code&gt;sudo systemctl status myapp.service&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Unit file contents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight systemd"&gt;&lt;code&gt;&lt;span class="k"&gt;[Unit]&lt;/span&gt;
&lt;span class="nt"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;My Web Application Service

&lt;span class="k"&gt;[Service]&lt;/span&gt;
&lt;span class="nt"&gt;ExecStart&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;/usr/bin/python3 /path/to/myapp.py
&lt;span class="nt"&gt;ExecStartPre&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;/usr/bin/echo "Starting myapp service..."
&lt;span class="nt"&gt;ExecStartPost&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;/usr/bin/echo "myapp service started successfully!"
&lt;span class="nt"&gt;Restart&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;always

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

&lt;/div&gt;


&lt;p&gt;I have written an example blog on configuring a linux service:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/ubayedbinsufian/linux-services-made-simple-create-control-and-remove-your-first-systemd-service-3mi9-temp-slug-6453320" class="crayons-story__hidden-navigation-link"&gt;Linux Services Made Simple: Create, Control, and Remove Your First systemd Service&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="/ubayedbinsufian" 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%2F3496590%2F41f63d8e-df22-495b-a00f-2794cc5aa34f.jpg" alt="ubayedbinsufian profile" class="crayons-avatar__image" width="96" height="96"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/ubayedbinsufian" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Ubayed Bin Sufian
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Ubayed Bin Sufian
                
              
              &lt;div id="story-author-preview-content-3588586" 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="/ubayedbinsufian" 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%2F3496590%2F41f63d8e-df22-495b-a00f-2794cc5aa34f.jpg" class="crayons-avatar__image" alt="" width="96" height="96"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Ubayed Bin Sufian&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/ubayedbinsufian/linux-services-made-simple-create-control-and-remove-your-first-systemd-service-3mi9-temp-slug-6453320" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;&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/ubayedbinsufian/linux-services-made-simple-create-control-and-remove-your-first-systemd-service-3mi9-temp-slug-6453320" id="article-link-3588586"&gt;
          Linux Services Made Simple: Create, Control, and Remove Your First systemd Service
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/linux"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;linux&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/systemdesign"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;systemdesign&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/beginners"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;beginners&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/ubayedbinsufian/linux-services-made-simple-create-control-and-remove-your-first-systemd-service-3mi9-temp-slug-6453320#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"&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;
&lt;br&gt;


&lt;h2&gt;
  
  
  Vi Editor
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;vi&lt;/code&gt; is a powerful text editor that is commonly used in Linux environments. In devops and cloud environments, you will often need to edit configuration files, write scripts, or manage code directly on the server. Knowing how to use &lt;code&gt;vi&lt;/code&gt; allows you to efficiently make changes to files without needing a graphical interface, which is especially important when working on remote servers via SSH. vi editor comes by default in most Linux distributions. Types of vi editors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;vi&lt;/code&gt;: The original version of the editor.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;vim&lt;/code&gt; (Vi IMproved): An enhanced version of vi with additional features and improvements. It is widely used and often the default vi editor in many Linux distributions.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;nvim&lt;/code&gt; (Neovim): A modern fork of vim that aims to improve performance and add new features while maintaining compatibility with vim. It is gaining popularity among developers for its extensibility and improved user experience.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;nano&lt;/code&gt;: A simpler text editor that is easier for beginners to use. It provides a more user-friendly interface compared to vi and vim, making it a good choice for those who are new to command-line text editing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Basic vi Commands
&lt;/h3&gt;

&lt;p&gt;Vi editor has two main modes: &lt;strong&gt;command mode&lt;/strong&gt; and &lt;strong&gt;insert mode&lt;/strong&gt;. When you open a file in vi, you start in command mode, where you can navigate through the file and execute commands. To edit the file, you need to switch to insert mode. Here are some basic commands to get started with vi editor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;vi filename&lt;/code&gt;: Open a file in vi editor. This will open the specified file in command mode.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;i&lt;/code&gt;: Switch to insert mode to start editing the file. In insert mode, you can type and make changes to the file. To return to command mode from insert mode, press the &lt;code&gt;Esc&lt;/code&gt; key.&lt;/li&gt;
&lt;li&gt;Use the arrow keys to navigate through the file in command mode. You can also use &lt;code&gt;h&lt;/code&gt;, &lt;code&gt;j&lt;/code&gt;, &lt;code&gt;k&lt;/code&gt;, and &lt;code&gt;l&lt;/code&gt; keys for left, down, up, and right navigation respectively.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;x&lt;/code&gt;: Delete the character under the cursor in command mode.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;dd&lt;/code&gt;: Delete the entire line where the cursor is located in command mode.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;yy&lt;/code&gt;: Copy the entire line where the cursor is located in command mode.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;p&lt;/code&gt;: Paste the copied line below the current line in command mode.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Ctrl + u&lt;/code&gt;: Scroll up half a page in command mode.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Ctrl + d&lt;/code&gt;: Scroll down half a page in command mode.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;:&lt;/code&gt;: Enter command-line mode in vi editor. In this mode, you can execute various commands to save, quit, or perform other actions on the file.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;:w&lt;/code&gt;: Save the changes made to the file in command-line mode.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;:q&lt;/code&gt;: Quit the vi editor in command-line mode. If you have unsaved changes, it will prompt you to save before quitting.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;:wq&lt;/code&gt;: Save the changes and quit the vi editor in command-line mode.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/search_term&lt;/code&gt;: Search for a specific term in the file in command mode. This will highlight the occurrences of the search term in the file. You can navigate through the search results using &lt;code&gt;n&lt;/code&gt; (next) and &lt;code&gt;N&lt;/code&gt; (previous) commands in command mode.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff3prldl5hhja942alnhj.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%2Ff3prldl5hhja942alnhj.png" alt="vi filename" width="800" height="57"&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%2F9a5npy83wlay4nfjsh48.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%2F9a5npy83wlay4nfjsh48.png" alt="Insert mode" width="800" height="426"&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%2Fumhvrpt5oa8175iowzts.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%2Fumhvrpt5oa8175iowzts.png" alt="search in vi" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This wasn’t about memorizing commands, it was about getting comfortable with the environment where DevOps actually happens.&lt;/p&gt;

&lt;p&gt;If you understand these Linux basics, you’ve already taken a solid first step that many beginners skip.&lt;/p&gt;

&lt;p&gt;In the next part of this series, we’ll move from commands to &lt;strong&gt;hands-on practice&lt;/strong&gt;, you’ll learn how to &lt;strong&gt;build your own lab using VirtualBox&lt;/strong&gt;, so you can experiment, break things, and learn by doing.&lt;/p&gt;

&lt;p&gt;Because DevOps isn’t learned by reading, it’s learned by doing.&lt;/p&gt;

&lt;p&gt;This is part of my DevOps Prerequisite series:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;DevOps Prerequisite #1: Linux Basics You Actually Need (this post)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Build Your Own Lab: Virtualization for DevOps Beginners (next)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Why Vagrant Still Matters (and When It Doesn’t)&lt;/li&gt;
&lt;li&gt;Networking for DevOps: The Only Concepts You Need&lt;/li&gt;
&lt;li&gt;YAML Explained for Future DevOps Engineers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Disclaimer: I have used GH copilot for writing the topics, Gemini Nano Banana for image generation and ChatGPT for the html snippet and other concepts.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reference:&lt;/strong&gt;&lt;br&gt;
💡 Want a visual walkthrough?&lt;br&gt;
This video does a great job explaining the basics covered here. Use it as a supplement—not a replacement:   &lt;iframe src="https://www.youtube.com/embed/Wvf0mBNGjXY?start=2256"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>devops</category>
      <category>linux</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
