<?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: SUBAIR NURUDEEN ADEWALE</title>
    <description>The latest articles on DEV Community by SUBAIR NURUDEEN ADEWALE (@subair09).</description>
    <link>https://dev.to/subair09</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%2F2941121%2F8ac1702b-1880-408f-b2bb-139ec9f4154a.jpg</url>
      <title>DEV Community: SUBAIR NURUDEEN ADEWALE</title>
      <link>https://dev.to/subair09</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/subair09"/>
    <language>en</language>
    <item>
      <title>Automated Azure Multi-VM Private Networking with Terraform (Infrastructure as Code</title>
      <dc:creator>SUBAIR NURUDEEN ADEWALE</dc:creator>
      <pubDate>Fri, 27 Feb 2026 17:42:49 +0000</pubDate>
      <link>https://dev.to/subair09/automated-azure-multi-vm-private-networking-with-terraform-infrastructure-as-code-29pg</link>
      <guid>https://dev.to/subair09/automated-azure-multi-vm-private-networking-with-terraform-infrastructure-as-code-29pg</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This project demonstrates how to design and deploy a secure multi-virtual machine environment on Microsoft Azure using Terraform Infrastructure as Code (IaC) principles.&lt;/p&gt;

&lt;p&gt;The infrastructure provisions two Linux virtual machines within the same virtual network and subnet, enabling private communication between them without manual configuration inside the operating systems.&lt;/p&gt;

&lt;p&gt;By using reusable Terraform modules for networking and compute resources, the deployment follows real-world DevOps practices such as automation, modular design, resource dependency management, and cloud governance through tagging.&lt;/p&gt;

&lt;p&gt;The project validates internal connectivity at the infrastructure level using Azure networking diagnostics, proving that both virtual machines can communicate securely over private IP addresses.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project Objective&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The objective of this project is to build a production-style cloud infrastructure that demonstrates practical skills in cloud automation, networking architecture, and Infrastructure as Code.&lt;/p&gt;

&lt;p&gt;Specifically, the project aims to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automate Azure resource provisioning using Terraform&lt;/li&gt;
&lt;li&gt;Deploy and configure two Linux virtual machines&lt;/li&gt;
&lt;li&gt;Design a virtual network and subnet for private communication&lt;/li&gt;
&lt;li&gt;Implement network security rules allowing internal ICMP traffic&lt;/li&gt;
&lt;li&gt;Validate VM-to-VM connectivity without logging into the machines&lt;/li&gt;
&lt;li&gt;Apply modular Terraform design for reusable infrastructure&lt;/li&gt;
&lt;li&gt;Demonstrate real-world DevOps and Cloud Engineering practices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Architecture You’ll Build&lt;/strong&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%2F7e0dza9yxc1hrk8hjple.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%2F7e0dza9yxc1hrk8hjple.png" alt=" " width="489" height="211"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Both VMs can ping each other because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Same subnet&lt;/li&gt;
&lt;li&gt;NSG allows internal traffic&lt;/li&gt;
&lt;li&gt;Private networking&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 1 Create terraform root project folder&lt;/strong&gt;&lt;br&gt;
Create the directory and create the provider.tf file inside it (Mkdir terraform-azure-2vm-network/provider.tf)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Mkdir terraform-azure-2vm-network&lt;/code&gt;&lt;br&gt;
 &lt;code&gt;cd terraform-azure-2vm-network&lt;/code&gt;&lt;br&gt;
 &lt;code&gt;New-item or touch provider.tf&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%2Fq1u9m3bxk35shlzhkjq8.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%2Fq1u9m3bxk35shlzhkjq8.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Copy this configuration code into the provider.tf file&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;terraform {
  required_version = "&amp;gt;= 1.5.0"

  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~&amp;gt; 3.100"
    }
  }
}

provider "azurerm" {
  features {}
}
&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%2Fjym6e1e4wtrdcasaowxu.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%2Fjym6e1e4wtrdcasaowxu.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create the terraform-azure-2vm-network/variables.tf file&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;New-item or touch variables.tf&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;Copy and paste this config into the variables.tf files&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;variable "location" {
  default = "East US"
}

variable "rg_name" {
  default = "rg-2vm-network"
}

variable "admin_username" {
  default = "azureuser"
}

variable "admin_password" {
  sensitive = true
}

variable "vm_size" {
  default = "Standard_B1s"
}
&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%2F4fyx947hce1izutg8suh.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%2F4fyx947hce1izutg8suh.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create the terraform-azure-2vm-network/terraform.tfvars file&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;New-item or touch terraform.tfvars&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;Copy and paste this config into the terraform.tfvars files&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;admin_password = "P@ssword12345!"
&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%2Farl6nb4efryyslwfvcig.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%2Farl6nb4efryyslwfvcig.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create the terraform-azure-2vm-network/main.tf file&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;New-item or touch main.tf&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;Copy and paste this config into the main.tf files&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Resource Group
resource "azurerm_resource_group" "rg" {
  name     = var.rg_name
  location = var.location
}

# Network Module
module "network" {
  source              = "./modules/network"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
}

# VM 1
module "vm1" {
  source              = "./modules/linux_vm"
  vm_name             = "vm-1"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  subnet_id           = module.network.subnet_id
  nsg_id              = module.network.nsg_id
  admin_username      = var.admin_username
  admin_password      = var.admin_password
  vm_size             = var.vm_size
}

# VM 2
module "vm2" {
  source              = "./modules/linux_vm"
  vm_name             = "vm-2"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  subnet_id           = module.network.subnet_id
  nsg_id              = module.network.nsg_id
  admin_username      = var.admin_username
  admin_password      = var.admin_password
  vm_size             = var.vm_size
}

&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%2Fx6vukas8fhgw7md5nnz1.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%2Fx6vukas8fhgw7md5nnz1.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create the terraform-azure-2vm-network/outputs.tf file&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;New-item or touch outputs.tf&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;Copy and paste this config into the outputs.tf files&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;output "vm1_private_ip" {
  value = module.vm1.private_ip
}

output "vm2_private_ip" {
  value = module.vm2.private_ip
}

output "ping_instruction" {
  value = "VMs are in same subnet — they can ping using private IPs"
}

&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%2F77ehawnu40di0czw6mlc.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%2F77ehawnu40di0czw6mlc.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2 Create terraform  Network Modules **&lt;br&gt;
Create the parent folder **Modules&lt;/strong&gt; and Create the sub-folder &lt;strong&gt;Network&lt;/strong&gt; and Create the file &lt;strong&gt;Variable.tf&lt;/strong&gt; inside the Network folder.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mkdir Modules&lt;/code&gt;&lt;br&gt;
&lt;code&gt;cd Modules&lt;/code&gt;&lt;br&gt;
&lt;code&gt;mkdir Network&lt;/code&gt;&lt;br&gt;
&lt;code&gt;cd Network&lt;/code&gt;&lt;br&gt;
&lt;code&gt;New-item variables.tf&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%2Ffa94hqqepfmssdcncjrw.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%2Ffa94hqqepfmssdcncjrw.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy this config into the &lt;strong&gt;modules/network/variables.tf&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;variable "location" {}
variable "resource_group_name" {}

&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%2F5871sb6hu00fg7w7e7xj.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%2F5871sb6hu00fg7w7e7xj.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create the modules/network/main.tf file&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;New-item or touch main.tf&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Copy this config into the main.tf file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resource "azurerm_virtual_network" "vnet" {
  name                = "vnet-2vm"
  address_space       = ["10.0.0.0/16"]
  location            = var.location
  resource_group_name = var.resource_group_name
}

resource "azurerm_subnet" "subnet" {
  name                 = "subnet-2vm"
  resource_group_name  = var.resource_group_name
  virtual_network_name = azurerm_virtual_network.vnet.name
  address_prefixes     = ["10.0.1.0/24"]
}

# Network Security Group allowing internal ping
resource "azurerm_network_security_group" "nsg" {
  name                = "nsg-2vm"
  location            = var.location
  resource_group_name = var.resource_group_name
}

resource "azurerm_network_security_rule" "allow_icmp" {
  name                        = "Allow-Internal-ICMP"
  priority                    = 100
  direction                   = "Inbound"
  access                      = "Allow"
  protocol                    = "Icmp"
  source_port_range           = "*"
  destination_port_range      = "*"
  source_address_prefix       = "VirtualNetwork"
  destination_address_prefix  = "VirtualNetwork"
  resource_group_name         = var.resource_group_name
  network_security_group_name = azurerm_network_security_group.nsg.name
}
resource "azurerm_network_security_rule" "allow_ssh" {
  name                        = "allow-ssh"
  priority                    = 200
  direction                   = "Inbound"
  access                      = "Allow"
  protocol                    = "Tcp"
  source_port_range           = "*"
  destination_port_range      = "22"
  source_address_prefix       = "*"
  destination_address_prefix  = "*"

  resource_group_name         = var.resource_group_name
  network_security_group_name = azurerm_network_security_group.nsg.name
}
&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%2Fwn5agt7greyl2h544b89.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%2Fwn5agt7greyl2h544b89.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create the modules/network/outputs.tf file.&lt;br&gt;
&lt;code&gt;New-item or touch outputs.tf&lt;/code&gt;&lt;br&gt;
Copy this Config into the outputs.tf file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;output "subnet_id" {
  value = azurerm_subnet.subnet.id
}

output "nsg_id" {
  value = azurerm_network_security_group.nsg.id
}
&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%2Fsorm9bkwu6hrcj51lqv3.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%2Fsorm9bkwu6hrcj51lqv3.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Step 3 Create the LINUX VM Module.&lt;/p&gt;

&lt;p&gt;Create the sub folder directory linux_vm/variables.tf inside the parent folder Modules.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mkdir linux_vm&lt;/code&gt;&lt;br&gt;
&lt;code&gt;cd linux_vm&lt;/code&gt;&lt;br&gt;
&lt;code&gt;New-item variables.tf or touch variables.tf&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%2Fzifg40slxjm1xu4v1l30.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%2Fzifg40slxjm1xu4v1l30.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy the config into the variables.tf files&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;variable "vm_name" {}
variable "location" {}
variable "resource_group_name" {}
variable "subnet_id" {}
variable "nsg_id" {}
variable "admin_username" {}
variable "admin_password" {}
variable "vm_size" {}

&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%2F0nowvgq7e6gsqs8byazn.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%2F0nowvgq7e6gsqs8byazn.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create the file modules/linux_vm/main.tf and copy the config into the file. &lt;br&gt;
&lt;code&gt;New-item main.tf&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resource "azurerm_network_interface" "nic" {
  name                = "${var.vm_name}-nic"
  location            = var.location
  resource_group_name = var.resource_group_name

  ip_configuration {
    name                          = "internal"
    subnet_id                     = var.subnet_id
    private_ip_address_allocation = "Dynamic"
    public_ip_address_id          = azurerm_public_ip.public_ip.id
  }
}

resource "azurerm_network_interface_security_group_association" "assoc" {
  network_interface_id      = azurerm_network_interface.nic.id
  network_security_group_id = var.nsg_id
}

resource "azurerm_linux_virtual_machine" "vm" {
  name                = var.vm_name
  resource_group_name = var.resource_group_name
  location            = var.location
  size                = var.vm_size

  admin_username = var.admin_username
  admin_password = var.admin_password
  disable_password_authentication = false

  network_interface_ids = [
    azurerm_network_interface.nic.id
  ]

  os_disk {
    caching              = "ReadWrite"
    storage_account_type = "Standard_LRS"
  }

  source_image_reference {
    publisher = "Canonical"
    offer     = "0001-com-ubuntu-server-jammy"
    sku       = "22_04-lts"
    version   = "latest"
  }
}
&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%2Fxrb7o6whv1lfy0pj2c3m.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%2Fxrb7o6whv1lfy0pj2c3m.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create the file modules/linux_vm/outputs.tf and copy the config into the outputs.tf file.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;New-item or touch outputs.tf&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;output "private_ip" {
  value = azurerm_network_interface.nic.private_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%2Fja0y2ntkyekxcrrq9qvk.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%2Fja0y2ntkyekxcrrq9qvk.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4 Run terraform&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Inside project root:&lt;/p&gt;

&lt;p&gt;Login into azure &lt;code&gt;az login&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%2F6r0sub10zxdfkblim3eq.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%2F6r0sub10zxdfkblim3eq.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;terraform init&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%2Fgvom0zd4i9eocp9s4u1b.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%2Fgvom0zd4i9eocp9s4u1b.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;terraform plan&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%2Fksf6bhxjhxxi1gktguda.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%2Fksf6bhxjhxxi1gktguda.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;terraform apply&lt;/code&gt;&lt;br&gt;
You will be prompted &lt;br&gt;
Do you want to perform these actions?&lt;br&gt;
  Terraform will perform the actions described above.&lt;br&gt;
  Only 'yes' will be accepted to approve.&lt;/p&gt;

&lt;p&gt;Enter a value: yes&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%2Fqr9p5oa5q1xbor62m5sg.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%2Fqr9p5oa5q1xbor62m5sg.png" alt=" " width="800" height="425"&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%2Fn8rj0nnaab9v1abeb2mj.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%2Fn8rj0nnaab9v1abeb2mj.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Step 5 Get Ping vm2 from vm1 to confirm communication&lt;/em&gt;&lt;br&gt;
use the command &lt;/p&gt;

&lt;p&gt;&lt;code&gt;az vm run-command invoke --resource-group rg-2vm-network --name vm-1 --command-id RunShellScript --scripts "ping -c 4 10.0.1.5"&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frzqndb7d9j3vkv5rjqlw.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%2Frzqndb7d9j3vkv5rjqlw.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ping vm1 from vm2 to confirm communication&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;&lt;code&gt;az vm run-command invoke --resource-group rg-2vm-network --name vm-1 --command-id RunShellScript --scripts "ping -c 4 10.0.1.5"&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm5uhk4or6d84lqu05tw1.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%2Fm5uhk4or6d84lqu05tw1.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6 Clean up resource&lt;/strong&gt; &lt;br&gt;
Run the command &lt;code&gt;terraform destroy&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%2Fdfen1d6rb2ht335x3fmj.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%2Fdfen1d6rb2ht335x3fmj.png" alt=" " width="800" height="425"&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%2F13cusmrgqhul5ytsrvk3.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%2F13cusmrgqhul5ytsrvk3.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This project successfully demonstrates the practical implementation of Infrastructure as Code using Terraform with the AzureRM provider on Microsoft Azure. Two Linux virtual machines were provisioned within the same virtual network and subnet, configured with appropriate network security rules, and validated for secure internal communication using private IP addressing.&lt;/p&gt;

&lt;p&gt;By enabling controlled ICMP traffic through a Network Security Group and verifying connectivity via Azure Run Command, the deployment confirms that both virtual machines can communicate without relying on public exposure. This reflects real-world cloud architecture practices where internal services interact securely within isolated network boundaries.&lt;/p&gt;

&lt;p&gt;Beyond resource provisioning, this project showcases end-to-end cloud engineering workflow: modular Terraform structure, reusable infrastructure components, network configuration, security rule management, and operational validation through command-line automation. It highlights the ability to design, deploy, and verify scalable cloud infrastructure using modern DevOps practices.&lt;/p&gt;

</description>
      <category>terraform</category>
      <category>azure</category>
      <category>ai</category>
      <category>networking</category>
    </item>
    <item>
      <title>Deploy .NET 8 App to Azure Kubernetes Service (AKS)</title>
      <dc:creator>SUBAIR NURUDEEN ADEWALE</dc:creator>
      <pubDate>Tue, 10 Feb 2026 22:09:02 +0000</pubDate>
      <link>https://dev.to/subair09/deploy-net-8-app-to-azure-kubernetes-service-aks-5d99</link>
      <guid>https://dev.to/subair09/deploy-net-8-app-to-azure-kubernetes-service-aks-5d99</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Modern software delivery increasingly relies on cloud-native technologies such as containers, Kubernetes, and automated deployment pipelines. This project demonstrates the end-to-end process of building, containerizing, and deploying a .NET 8 Web API to Azure Kubernetes Service (AKS) using industry best practices.&lt;/p&gt;

&lt;p&gt;By developing a Weather Forecast API, the project simulates a real-world DevOps workflow where applications are tested locally, packaged with Docker, stored in Azure Container Registry, deployed to Kubernetes, and automatically updated through CI/CD. The goal is to gain practical experience in deploying scalable and production-ready applications in a cloud environment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Architecture Flow&lt;/strong&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%2Fki6xxvzh5l8enu5mmuiv.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%2Fki6xxvzh5l8enu5mmuiv.png" alt=" " width="690" height="1306"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Required Software&lt;br&gt;
Install the following tools in this order:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Visual Studio Code&lt;/li&gt;
&lt;li&gt;.NET 8 SDK&lt;/li&gt;
&lt;li&gt;Git&lt;/li&gt;
&lt;li&gt;Docker Desktop,Start Docker Desktop after installation&lt;/li&gt;
&lt;li&gt;Azure CLI&lt;/li&gt;
&lt;li&gt;kubectl&lt;/li&gt;
&lt;li&gt;GitHub CLI (optional but recommended)&lt;/li&gt;
&lt;li&gt;Required Accounts&lt;/li&gt;
&lt;li&gt;GitHub account (free)&lt;/li&gt;
&lt;li&gt;Azure account (free tier available)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Verify Installations&lt;/strong&gt;&lt;br&gt;
Run the following commands:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dotnet --version&lt;/li&gt;
&lt;li&gt;git --version&lt;/li&gt;
&lt;li&gt;docker --version&lt;/li&gt;
&lt;li&gt;az --version&lt;/li&gt;
&lt;li&gt;kubectl version --client&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If any command fails, fix it before proceeding.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Create and Test the .NET Application Locally&lt;/strong&gt;&lt;br&gt;
Why This Step Matters&lt;br&gt;
You never deploy untested code.&lt;/p&gt;

&lt;p&gt;Testing locally allows you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Catch errors early&lt;/li&gt;
&lt;li&gt;Validate endpoints&lt;/li&gt;
&lt;li&gt;Avoid expensive cloud debugging&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;1.1 Create Project Structure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use the command to create directory and to enter into the directory&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mkdir weather-app-demo&lt;/code&gt;&lt;br&gt;
&lt;code&gt;cd weather-app-demo&lt;/code&gt;&lt;br&gt;
&lt;code&gt;mkdir WeatherApp&lt;/code&gt;&lt;br&gt;
&lt;code&gt;cd WeatherApp&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%2Ffk13ly8zve81duykl26k.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%2Ffk13ly8zve81duykl26k.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.2 Initialize the .NET Web API&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet new webapi -minimal&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This creates a minimal API with fewer files and faster startup.&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%2F9cupretli7smdjkagx82.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%2F9cupretli7smdjkagx82.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.3 Add Required Packages&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This command adds the Health Checks library to your .NET project.&lt;/p&gt;

&lt;p&gt;In simple terms:&lt;br&gt;
It installs a package that allows your app to report whether it is healthy or not.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet add package Microsoft.Extensions.Diagnostics.HealthChecks&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%2F1s4pvmx9gij7t52zji3n.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%2F1s4pvmx9gij7t52zji3n.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet add package Swashbuckle.AspNetCore&lt;/code&gt;&lt;br&gt;
This installs Swagger support into your .NET Web API project.&lt;/p&gt;

&lt;p&gt;Swashbuckle is the library that automatically generates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API documentation&lt;/li&gt;
&lt;li&gt;Interactive testing UI
In Simple Terms:
It gives you a web page where you can see and test all your API endpoints.&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%2Fvd80ihd6nyctvg0543mk.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%2Fvd80ihd6nyctvg0543mk.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Code .&lt;/code&gt;  &lt;/p&gt;

&lt;p&gt;It opens the current folder in Visual Studio Code.&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%2Fxl7p5ma2y79f12z8jdzu.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%2Fxl7p5ma2y79f12z8jdzu.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.4 Replace Program.cs&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;var builder = WebApplication.CreateBuilder(args);

// Services
builder.Services.AddHealthChecks();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

// Kestrel config for containers
builder.WebHost.ConfigureKestrel(options =&amp;gt;
{
    options.ListenAnyIP(8080);
});

var app = builder.Build();

// Middleware
app.UseSwagger();
app.UseSwaggerUI();

// Endpoints
app.MapGet("/", () =&amp;gt; new
{
    Message = "Welcome to the Weather App!",
    Version = "1.0.0",
    Timestamp = DateTime.UtcNow
});

app.MapGet("/weather", () =&amp;gt;
{
    var summaries = new[]
    {
        "Freezing", "Bracing", "Chilly", "Cool",
        "Mild", "Warm", "Hot", "Scorching"
    };

    return Enumerable.Range(1, 5).Select(i =&amp;gt; new
    {
        Date = DateOnly.FromDateTime(DateTime.Now.AddDays(i)),
        TemperatureC = Random.Shared.Next(-20, 40),
        Summary = summaries[Random.Shared.Next(summaries.Length)]
    });
});

// Health endpoint for Kubernetes
app.MapHealthChecks("/health");

app.Run();

&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%2Fc3g39gawxewm6a14ia1t.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%2Fc3g39gawxewm6a14ia1t.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.5 Test Locally&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;dotnet run&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Test endpoints:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://localhost:8080/" rel="noopener noreferrer"&gt;http://localhost:8080/&lt;/a&gt;&lt;/strong&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%2F87tjs3xu6wsajgpsjasb.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%2F87tjs3xu6wsajgpsjasb.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://localhost:8080/weather" rel="noopener noreferrer"&gt;http://localhost:8080/weather&lt;/a&gt;&lt;/strong&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%2Fkeh8252jaqyur6c56vlb.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%2Fkeh8252jaqyur6c56vlb.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://localhost:8080/swagger" rel="noopener noreferrer"&gt;http://localhost:8080/swagger&lt;/a&gt;&lt;/strong&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%2Fvwpoqfp2tic2509yb2io.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%2Fvwpoqfp2tic2509yb2io.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="http://localhost:8080/health" rel="noopener noreferrer"&gt;http://localhost:8080/health&lt;/a&gt;&lt;/strong&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%2Fefhsoup1q6zaqgjifcuo.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%2Fefhsoup1q6zaqgjifcuo.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If this works, your app is ready for containerization.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Containerize the Application with Docker&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Why Containerize?&lt;br&gt;
Containers ensure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Same runtime everywhere&lt;/li&gt;
&lt;li&gt;No “works on my machine” issues&lt;/li&gt;
&lt;li&gt;Smooth Kubernetes deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2.1 Create Dockerfile&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use the command &lt;code&gt;touch or New-item Dockerfile&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%2Fpw3vq4axqh32wlv67gvk.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%2Fpw3vq4axqh32wlv67gvk.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy the docker instruction into the dockerfile&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Runtime
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 8080

# Build
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY weatherApp.csproj .
RUN dotnet restore
COPY . .
RUN dotnet publish -c Release -o /app/publish

# Final image
FROM base
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "weatherApp.dll"]
&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%2Fy3gc2c23c1mkca1vmfg5.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%2Fy3gc2c23c1mkca1vmfg5.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.2 Create .dockerignore&lt;/strong&gt;&lt;br&gt;
Use the command &lt;code&gt;touch or New-item .dockerignore&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%2Fxxv6fsoxtyacvi2xd94x.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%2Fxxv6fsoxtyacvi2xd94x.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy the code into the .dockerignore file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bin/
obj/
.vs/
.vscode/
.git/
.gitignore
Dockerfile
README.md
*.log
&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%2Fdx7bwv0zvdnx4lgxg6tj.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%2Fdx7bwv0zvdnx4lgxg6tj.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.3 Build and Test Container Locally&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker build -t weather-app:local .&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%2Fcpnvzybqm0itqph09pkc.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%2Fcpnvzybqm0itqph09pkc.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker run -p 8080:8080 weather-app:local&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%2Ffjkb3ef9qtbjglh46sdq.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%2Ffjkb3ef9qtbjglh46sdq.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Test again in browser or with curl.&lt;br&gt;
If it works locally, it will work in AKS.&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%2F2gzxbsjwc1asssfg0pnm.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%2F2gzxbsjwc1asssfg0pnm.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Create Azure Infrastructure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.1 Login to Azure&lt;/strong&gt;&lt;br&gt;
use the command &lt;code&gt;az login&lt;/code&gt; or &lt;code&gt;az login --allow-no-subscriptions&lt;/code&gt; &lt;br&gt;
once prompted to select a subscription or tenant ID, Click on the ENTER key on your keyboard.&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%2F6srkoqrzam65wwjo6je6.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%2F6srkoqrzam65wwjo6je6.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.2 Create Resource Group&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;az group create --name student-demo --location eastus&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%2Fb04hk6fnpf6713f7206l.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%2Fb04hk6fnpf6713f7206l.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.3 Create Azure Container Registry (ACR)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.3.1 Register your subscription to use Microsoft.ContainerRegistry&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use the command to register the service &lt;code&gt;az provider register --namespace Microsoft.ContainerRegistry&lt;/code&gt;&lt;br&gt;
and use &lt;code&gt;az provider show --namespace Microsoft.ContainerRegistry --query registrationState&lt;/code&gt; to check the registration status.&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%2F72ygujo3wc1eaqwrsuzd.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%2F72ygujo3wc1eaqwrsuzd.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.3.2  Create Azure Container Registry (ACR)&lt;/strong&gt;&lt;br&gt;
Use the command to create Azure Container Registry and give it a Unique name.&lt;br&gt;
&lt;code&gt;az acr create --resource-group student-demo --name studentdemoacr --sku Basic&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%2Fwcnmwignecvyluwsc68q.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%2Fwcnmwignecvyluwsc68q.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.4 Build &amp;amp; Push Image Using ACR&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;az acr build --registry studentdemoacr --image weather-app:latest .&lt;/code&gt; or Instead of using &lt;strong&gt;az acr build&lt;/strong&gt;, you can:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Build locally with Docker and push manually&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker build -t skillstudentdemoacr.azurecr.io/weather-app:latest .&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%2F3l8uxnfkltcnm10yr0x4.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%2F3l8uxnfkltcnm10yr0x4.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Login into Azure Container registry *&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;az acr login --name skillstudentdemoacr&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%2Fel08ihoifgloi0ffyqcm.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%2Fel08ihoifgloi0ffyqcm.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Push image to Azure Container registry&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker push skillstudentdemoacr.azurecr.io/weather-app:latest&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%2Feqb4tdoc4f5emrfxpdd7.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%2Feqb4tdoc4f5emrfxpdd7.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.5 Create AKS Cluster with ACR Attached&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Register your subscription to use &lt;strong&gt;Microsoft.ContainerService&lt;/strong&gt; first before creating the AKS cluster.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;az provider register --namespace Microsoft.ContainerService&lt;/code&gt;&lt;br&gt;
use this to check the status &lt;code&gt;az provider show --namespace Microsoft.ContainerService --query registrationState&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%2Fwr719stswbzhlvkod554.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%2Fwr719stswbzhlvkod554.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create aks cluster&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;az aks create --resource-group student-demo --name skillstudent-aks --node-count 1 --attach-acr skillstudentdemoacr --enable-managed-identity --generate-ssh-keys --location eastus&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%2F0re6uimxe10kh2umn8xl.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%2F0re6uimxe10kh2umn8xl.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.6 Connect kubectl to AKS&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;az aks get-credentials --resource-group student-demo --name student-aks&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Verify &lt;code&gt;kubectl get nodes&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%2Fn7qs0c931wf0tgf9g5or.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%2Fn7qs0c931wf0tgf9g5or.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Deploy to Kubernetes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4.1 Create Kubernetes Manifests&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a directory  &lt;code&gt;mkdir k8s&lt;/code&gt;&lt;br&gt;
Enter the direwctory &lt;code&gt;cd k8s&lt;/code&gt;&lt;br&gt;
Create deployment.yaml file using &lt;code&gt;New-item or touch deployment.yaml&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%2Fisgl30qyfy2goqpx2glz.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%2Fisgl30qyfy2goqpx2glz.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy this code into the deployment.yaml file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: apps/v1
kind: Deployment
metadata:
  name: weather-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: weather-app
  template:
    metadata:
      labels:
        app: weather-app
    spec:
      containers:
      - name: weather-app
        image: studentdemoacr.azurecr.io/weather-app:latest
        ports:
        - containerPort: 8080
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
        readinessProbe:
          httpGet:
            path: /health
            port: 8080
&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%2Fg9lk7d8xxc2be2ty2b7w.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%2Fg9lk7d8xxc2be2ty2b7w.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create service.yaml file using &lt;code&gt;New-item or touch service.yaml&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%2Fanfigma1pyal98ym226u.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%2Fanfigma1pyal98ym226u.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy this code into the service.yaml&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: v1
kind: Service
metadata:
  name: weather-service
spec:
  type: LoadBalancer
  selector:
    app: weather-app
  ports:
  - port: 80
    targetPort: 8080

&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%2F3iuhg0783ttqo1efxfr9.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%2F3iuhg0783ttqo1efxfr9.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4.2 Apply Manifests&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;kubectl apply -f deployment.yaml&lt;/code&gt;&lt;br&gt;
&lt;code&gt;kubectl apply -f service.yaml&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Check status:&lt;br&gt;
&lt;code&gt;kubectl get pods&lt;/code&gt;&lt;br&gt;
&lt;code&gt;kubectl get services&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%2Fnwg33diegb35xav2dych.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%2Fnwg33diegb35xav2dych.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: CI/CD with GitHub Actions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5.1 Initialize Git&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git init&lt;/code&gt;&lt;br&gt;
&lt;code&gt;git add .&lt;/code&gt;&lt;br&gt;
&lt;code&gt;git commit -m "Initial Weather App"&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%2Ft7b1tni1kp65qfhl22py.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%2Ft7b1tni1kp65qfhl22py.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5.2 Create GitHub Repo&lt;/strong&gt;&lt;br&gt;
*&lt;em&gt;Login to Github *&lt;/em&gt;&lt;br&gt;
Use rename your branch to main using &lt;code&gt;git branch -m main&lt;/code&gt;&lt;br&gt;
&lt;code&gt;Use git remote add origin https://github.com/Subair-09/WeatherAPP.git&lt;/code&gt; to add repository.&lt;br&gt;
&lt;code&gt;Use git push origin main&lt;/code&gt; to push the codes to github&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%2F3454t2uclc494ri1rkgv.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%2F3454t2uclc494ri1rkgv.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5.3 Create Workflow File&lt;/strong&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%2Fu64y74w3w0le2nl7zrnt.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%2Fu64y74w3w0le2nl7zrnt.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy and paste this code in the .github/workflows/deploy.yml file &lt;br&gt;
name: CI/CD to AKS&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4

    - uses: azure/login@v1
      with:
        creds: ${{ secrets.AZURE_CREDENTIALS }}

    - run: |
        az acr build \
          --registry ${{ secrets.ACR_NAME }} \
          --image weather-app:${{ github.sha }} .

    - run: |
        az aks get-credentials \
          --resource-group ${{ secrets.RESOURCE_GROUP }} \
          --name ${{ secrets.CLUSTER_NAME }}

    - run: |
        kubectl set image deployment/weather-app \
        weather-app=${{ secrets.ACR_NAME }}.azurecr.io/weather-app:${{ github.sha }}
&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%2Fzbj2j9u2v82nzplgp82r.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%2Fzbj2j9u2v82nzplgp82r.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6: Access the Application&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;Use the EXTERNAL-IP in your browser.&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%2F3ti59lcuf3t7o50f6ecu.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%2F3ti59lcuf3t7o50f6ecu.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Push Github workflow to github&lt;/strong&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%2Fcq7t79pploxae5y6jy6o.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%2Fcq7t79pploxae5y6jy6o.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Github action running&lt;/strong&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%2Fbpfgdoi77dqfbf8ckr3l.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%2Fbpfgdoi77dqfbf8ckr3l.png" alt=" " width="800" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This project successfully demonstrates a complete, real-world cloud-native deployment workflow using modern DevOps practices. Starting from local development of a .NET 8 Web API, the application was containerized with Docker, securely stored in Azure Container Registry, and deployed to Azure Kubernetes Service with proper health checks, scalability, and service exposure.&lt;/p&gt;

&lt;p&gt;By integrating GitHub Actions for CI/CD, the deployment process was fully automated, ensuring that every change pushed to the repository results in a reliable and repeatable update to the Kubernetes cluster. This mirrors how production systems are built, tested, and delivered in professional cloud environments.&lt;/p&gt;

&lt;p&gt;Overall, the project reinforces key concepts such as containerization, Kubernetes orchestration, infrastructure provisioning, and continuous delivery on Azure. It provides a strong foundation for building scalable, resilient, and production-ready applications, and serves as a practical reference for engineers transitioning into cloud and DevOps roles.&lt;/p&gt;

</description>
      <category>azure</category>
      <category>kubernetes</category>
      <category>containers</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Branching &amp; Merging Lab: Building Production-Ready DevOps Workflows</title>
      <dc:creator>SUBAIR NURUDEEN ADEWALE</dc:creator>
      <pubDate>Tue, 27 Jan 2026 13:36:19 +0000</pubDate>
      <link>https://dev.to/subair09/branching-merging-lab-building-production-ready-devops-workflows-5767</link>
      <guid>https://dev.to/subair09/branching-merging-lab-building-production-ready-devops-workflows-5767</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Modern DevOps teams rely on strong source code management practices to deliver software quickly safely and consistently. At the center of this process is branching and merging the workflow that allows multiple developers to work in parallel without breaking production systems.&lt;/p&gt;

&lt;p&gt;In this hands on lab project you will simulate how real world DevOps teams manage code changes from development to production using Git. You will practice creating feature branches synchronizing with the main branch resolving changes and merging code using industry best practices.&lt;/p&gt;

&lt;p&gt;This project is designed to help you move beyond theory and experience how professional teams collaborate test and ship code in a controlled production safe environment. By the end of this lab you will understand not just how branching works but why it is critical to DevOps success.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project Objectives&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By completing this project you will be able to&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Understand the importance of branching in DevOps workflows&lt;/li&gt;
&lt;li&gt;Learn why teams avoid working directly on the main branch and how branching reduces risk&lt;/li&gt;
&lt;li&gt;Create and manage feature branches effectively&lt;/li&gt;
&lt;li&gt;Develop new features in isolated environments without disrupting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;** Step 1: Prepare Your Repository**&lt;br&gt;
Run:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git clone https://github.com/Subair-09/Stylish-E-commerce.git&lt;/code&gt; (This command downloads a copy of the project from GitHub to your local machine.) and Git creates a new folder called Stylish-E-commerce&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd Stylish-E-commerce&lt;/code&gt; (This command moves you into the project folder so you can run Git commands inside it. Without this step, Git will not know which project you are working on.)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git checkout main&lt;/code&gt; (This command switches you to the main branch of the project.)&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git pull&lt;/code&gt; (This command updates your local main branch with the latest changes from GitHub.)&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%2Fcb4ne0g4gyu9u387w1lu.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%2Fcb4ne0g4gyu9u387w1lu.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Checkpoint&lt;/strong&gt;: &lt;strong&gt;git status&lt;/strong&gt; shows a clean working tree&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%2Fmnuw9npoy3pld2rxh4nt.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%2Fmnuw9npoy3pld2rxh4nt.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Create a Feature Branch&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git checkout -b feature/amazing-feature&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This command creates a new branch and immediately switches you to it.&lt;/p&gt;

&lt;p&gt;It does two things at once:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creates a new branch&lt;/li&gt;
&lt;li&gt;The branch name is feature/amazing-feature&lt;/li&gt;
&lt;li&gt;This branch is used to work on a new feature&lt;/li&gt;
&lt;li&gt;It is separate from the main branch, so your changes are safe&lt;/li&gt;
&lt;li&gt;Switches to the new branch&lt;/li&gt;
&lt;li&gt;After running the command, you are no longer on main&lt;/li&gt;
&lt;li&gt;Any changes you make now happen only in this feature branch&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Make a Change&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Edit a file OR&lt;/li&gt;
&lt;li&gt;Add a new feature OR&lt;/li&gt;
&lt;li&gt;Improve documentation
add a file feature.html by using the command&lt;code&gt;New-item or touch feature.html&lt;/code&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%2Fr1hmcjtrk837fspq3rcn.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%2Fr1hmcjtrk837fspq3rcn.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;use the command &lt;code&gt;code .&lt;/code&gt; (This command opens the current folder in Visual Studio Code.)&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%2Fp8i18zp9b2egujoj84vi.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%2Fp8i18zp9b2egujoj84vi.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;use the command &lt;code&gt;git status&lt;/code&gt;&lt;br&gt;
Checkpoint: Files appear as modified or new&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%2F4iinpjz33f6ch3levd80.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%2F4iinpjz33f6ch3levd80.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Commit Your Work&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git add .&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This command tells Git to stage all the changes you have made in the project for the next commit.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What it does:&lt;/li&gt;
&lt;li&gt;Adds all modified files&lt;/li&gt;
&lt;li&gt;Adds new files&lt;/li&gt;
&lt;li&gt;Prepares them to be saved in Git history&lt;/li&gt;
&lt;li&gt;The dot . means:&lt;/li&gt;
&lt;li&gt;“Add everything in this folder and subfolders.”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;git commit -m "Add amazing feature"&lt;/p&gt;

&lt;p&gt;This command saves your staged changes into Git with a message describing what you did.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What it does:&lt;/li&gt;
&lt;li&gt;Creates a new commit (a snapshot of your code)&lt;/li&gt;
&lt;li&gt;Records the changes permanently in Git history&lt;/li&gt;
&lt;li&gt;Adds a clear message so others understand your work&lt;/li&gt;
&lt;li&gt;The -m flag means:&lt;/li&gt;
&lt;li&gt;“Use this message to describe the change.”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Checkpoint: Commit created successfully&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%2F7mzrlcv3s9ct8h4l8wcv.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%2F7mzrlcv3s9ct8h4l8wcv.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Sync With Main&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git checkout main&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This command switches you to the main branch, which contains the stable and production ready version of the code.&lt;/li&gt;
&lt;li&gt;You do this to make sure you are working from the correct base before updating or merging anything.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;git pull&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This command updates your local main branch with the latest changes from the remote repository (GitHub).&lt;/p&gt;

&lt;p&gt;It:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fetches new commits from GitHub&lt;/li&gt;
&lt;li&gt;merges them into your local main&lt;/li&gt;
&lt;li&gt;ensures your local main is up to date&lt;/li&gt;
&lt;li&gt;This is important so you don’t work with outdated code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;git checkout feature/amazing-feature&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This command switches you to your feature branch, where you are developing new functionality.&lt;/li&gt;
&lt;li&gt;At this point, your feature branch may be behind main, which is why the next step is important.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;git merge main&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This command merges the latest changes from main into your feature branch.&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%2Fcl5j4tonyx8ozauvoyx0.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%2Fcl5j4tonyx8ozauvoyx0.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6: Merge to Main&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git checkout main&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This command switches you to the main branch, which contains the production ready and stable version of the code.&lt;/p&gt;

&lt;p&gt;You must be on the branch you want to receive the changes before merging.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git merge feature/amazing-feature&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This command merges the work from the feature/amazing-feature branch into the main branch.&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%2Fgwhw1x7z5d5a4288btvu.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%2Fgwhw1x7z5d5a4288btvu.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;** Step 7: Clean Up**&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git branch -d feature/amazing-feature&lt;/code&gt;&lt;br&gt;
This command deletes the feature branch called feature/amazing-feature from your local repository.&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%2Fmo8sctq6u1uv9wu4ym05.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%2Fmo8sctq6u1uv9wu4ym05.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Conclusion &lt;/p&gt;

&lt;p&gt;In this lab project, you practiced how real DevOps teams manage code changes safely and efficiently using Git branching and merging workflows. By working with feature branches, synchronizing with the main branch, and merging only tested changes, you experienced how teams protect production systems while still moving fast.&lt;/p&gt;

&lt;p&gt;This project demonstrated why the main branch must always remain stable and why all development should happen in isolated branches. You also learned how frequent integration, clear commits, and branch cleanup help reduce risk, improve collaboration, and keep codebases production ready.&lt;/p&gt;

&lt;p&gt;By completing this lab, you have built a strong foundation in source code management that directly supports CI/CD pipelines, team collaboration, and modern DevOps practices. These skills are essential for working in real world engineering teams where stability, speed, and reliability matter.&lt;/p&gt;

&lt;p&gt;You are now ready to apply this workflow in larger projects, automate it with pipelines, and collaborate confidently in any DevOps environment.&lt;/p&gt;

</description>
      <category>git</category>
      <category>cloud</category>
      <category>devops</category>
      <category>programming</category>
    </item>
    <item>
      <title>Deploying a Node.js Application to AWS Elastic Beanstalk</title>
      <dc:creator>SUBAIR NURUDEEN ADEWALE</dc:creator>
      <pubDate>Wed, 31 Dec 2025 11:21:08 +0000</pubDate>
      <link>https://dev.to/subair09/deploying-a-nodejs-application-to-aws-elastic-beanstalk-3455</link>
      <guid>https://dev.to/subair09/deploying-a-nodejs-application-to-aws-elastic-beanstalk-3455</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Deploying a Node.js application is one thing — deploying it reliably, securely, and at scale is another. As applications grow beyond local development, developers often face challenges around server configuration, environment management, scalability, and deployment automation.&lt;/p&gt;

&lt;p&gt;AWS Elastic Beanstalk simplifies this process by abstracting much of the infrastructure complexity while still giving developers control over their application environment. With built-in support for Node.js, Elastic Beanstalk allows you to focus on writing code while AWS handles provisioning, load balancing, scaling, and monitoring behind the scenes.&lt;/p&gt;

&lt;p&gt;In this article, we’ll walk through a practical, step-by-step guide to deploying a Node.js application to AWS Elastic Beanstalk. Whether you’re transitioning from local development or looking to standardize your deployment workflow, this guide will help you understand the deployment process, common pitfalls, and best practices for running Node.js applications in production on AWS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Log in to your AWS Management Console.&lt;/strong&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%2Fg1cws8q3vo6smrqo2iep.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%2Fg1cws8q3vo6smrqo2iep.png" alt=" " width="800" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: In the search bar, type &lt;code&gt;Elastic Beanstalk&lt;/code&gt; and select it from the services list.&lt;/strong&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%2Frs2qq4qrza5xnfe1m08r.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%2Frs2qq4qrza5xnfe1m08r.png" alt=" " width="800" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Navigate to Environments, then click &lt;code&gt;Create Environment&lt;/code&gt; to begin the setup process.&lt;/strong&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%2F1ayox8g1burixtgunb13.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%2F1ayox8g1burixtgunb13.png" alt=" " width="800" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Select a web server environment and enter an application name (for example, officeApp).&lt;/strong&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%2Fk82d1jmywzzoq75n1ms3.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%2Fk82d1jmywzzoq75n1ms3.png" alt=" " width="800" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: The environment name will be populated automatically. Select the platform in this case, choose Node.js since the application is built with Node.js. All other settings, including the **platform branch&lt;/strong&gt; and &lt;strong&gt;platform settings&lt;/strong&gt;, will be populated by default.&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%2Fu5g7lte1yi5xl2ryg12e.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%2Fu5g7lte1yi5xl2ryg12e.png" alt=" " width="800" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Step 6: Select the Sample application, choose Single instance under configuration, and then click Next.&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%2Fuspqgdnaeays9kl0t4f1.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%2Fuspqgdnaeays9kl0t4f1.png" alt=" " width="800" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 7: Configure Service Access&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For the Service Role, select &lt;strong&gt;Create role&lt;/strong&gt; if no existing role is available.&lt;/li&gt;
&lt;li&gt;During the role creation process, leave all configuration parameters at their default values.&lt;/li&gt;
&lt;li&gt;Proceed by clicking Next on both the Select trusted entity and Add permissions steps.&lt;/li&gt;
&lt;li&gt;Update the Role name to a unique and descriptive identifier.&lt;/li&gt;
&lt;li&gt;Complete the process by clicking &lt;strong&gt;Create role&lt;/strong&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%2F4ae51rk6zgg17so5bs1a.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%2F4ae51rk6zgg17so5bs1a.png" alt=" " width="800" height="423"&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%2Fv1tje5t9f9lfhjotcygw.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%2Fv1tje5t9f9lfhjotcygw.png" alt=" " width="800" height="423"&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%2F2s7m7s845n18y9grz7md.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%2F2s7m7s845n18y9grz7md.png" alt=" " width="800" height="423"&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%2F4w3utsh7fzgnq4pi0mvw.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%2F4w3utsh7fzgnq4pi0mvw.png" alt=" " width="800" height="423"&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%2Fyb80sktnvrlisengawzf.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%2Fyb80sktnvrlisengawzf.png" alt=" " width="800" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Just as the previous, For &lt;strong&gt;EC2 instance profile&lt;/strong&gt; select &lt;strong&gt;Create role&lt;/strong&gt; if no existing role is available.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;During the role creation process, leave all configuration parameters at their default values.&lt;/li&gt;
&lt;li&gt;Proceed by clicking Next on both the Select &lt;strong&gt;trusted entity and Add permissions steps&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Update the Role name to a unique and descriptive identifier.&lt;/li&gt;
&lt;li&gt;Complete the process by clicking &lt;strong&gt;Create role&lt;/strong&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%2Fhbkpmzqrhtndrd8o7jwr.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%2Fhbkpmzqrhtndrd8o7jwr.png" alt=" " width="800" height="423"&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%2Frp055b1rnjclbhadlfp4.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%2Frp055b1rnjclbhadlfp4.png" alt=" " width="800" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the &lt;strong&gt;EC2 Key Pair&lt;/strong&gt;, locate the service using the AWS Management Console search bar.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new key pair by providing a unique and descriptive name.&lt;/li&gt;
&lt;li&gt;Leave all other configuration options at their default settings.&lt;/li&gt;
&lt;li&gt;Complete the process by selecting Create key pair.&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%2Flpaa8xnvvknnrdst0e8w.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%2Flpaa8xnvvknnrdst0e8w.png" alt=" " width="800" height="423"&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%2Fs6mffzplw8pvffrvgtfy.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%2Fs6mffzplw8pvffrvgtfy.png" alt=" " width="800" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click** Next** on Configure service page afterwards.&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%2Fvw2x4dexdlvm5kjv21sw.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%2Fvw2x4dexdlvm5kjv21sw.png" alt=" " width="800" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 8: Set up networking, database, and tags&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select the &lt;strong&gt;default VPC&lt;/strong&gt; from the available options in the dropdown menu.&lt;/li&gt;
&lt;li&gt;Enable **Public IP address assignment **for the instances.&lt;/li&gt;
&lt;li&gt;From the Instance Subnet options, select any available subnet.&lt;/li&gt;
&lt;li&gt;Leave all remaining parameters at their default values, then click Next to proceed.&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%2Fhnuz01l9oecn7jvjviiu.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%2Fhnuz01l9oecn7jvjviiu.png" alt=" " width="800" height="423"&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%2Fzi9529z5tubmcokhi192.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%2Fzi9529z5tubmcokhi192.png" alt=" " width="800" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 9: Configure instance traffic and scaling&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Select an existing EC2 Security Group from the dropdown list.&lt;br&gt;
Leave all other configuration parameters at their default values, then click Next to continue.&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%2F1es426yea9v2gvw8rbf2.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%2F1es426yea9v2gvw8rbf2.png" alt=" " width="800" height="423"&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%2Fwsg2681nz85k389i3b7n.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%2Fwsg2681nz85k389i3b7n.png" alt=" " width="800" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 10: Configure updates, monitoring, and logging&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Select the appropriate CloudWatch metrics instance and the corresponding CloudWatch metrics environment from their respective fields simultaneously&lt;br&gt;
Leave all other configuration parameters at their default values, then click Next to continue.&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%2F8hsupz85n3ul60hh29hr.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%2F8hsupz85n3ul60hh29hr.png" alt=" " width="800" height="423"&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%2Fkp1kii3g6rqb45bnz53c.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%2Fkp1kii3g6rqb45bnz53c.png" alt=" " width="800" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now review the entire steps and click &lt;strong&gt;create&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Once the Environment is successfully lunched and the health status shows green and OK. Click the URL link listed for Domain to browse your application.&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%2Fz487dq270r1qiuuyu710.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%2Fz487dq270r1qiuuyu710.png" alt=" " width="800" height="423"&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%2F0icbzgyoksen36t5k7m8.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%2F0icbzgyoksen36t5k7m8.png" alt=" " width="800" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To access the E*&lt;em&gt;lastic Beanstalk–managed EC2 instance shell&lt;/em&gt;&lt;em&gt;, navigate to **Amazon Elastic Compute Cloud (EC2)&lt;/em&gt;* and select the relevant Instance ID.&lt;/p&gt;

&lt;p&gt;From the Instance Overview page, click &lt;strong&gt;Connect&lt;/strong&gt;, then select Connect again to initiate an in-browser SSH session.&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%2Fj3zwcz1oa179jc39c19o.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%2Fj3zwcz1oa179jc39c19o.png" alt=" " width="800" height="423"&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%2Fmcynt667ys22obi2ezef.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%2Fmcynt667ys22obi2ezef.png" alt=" " width="800" height="423"&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%2F50utuqrxn9updsk6fe9u.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%2F50utuqrxn9updsk6fe9u.png" alt=" " width="800" height="423"&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%2Fsd10ugghychvjj6ajcfm.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%2Fsd10ugghychvjj6ajcfm.png" alt=" " width="800" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Conclusion&lt;/p&gt;

&lt;p&gt;In this project, we successfully deployed a Node.js application to AWS Elastic Beanstalk using a structured and repeatable approach. By leveraging Elastic Beanstalk, we were able to abstract away much of the underlying infrastructure complexity while still maintaining control over critical configuration options such as networking, security, scaling, and monitoring.&lt;/p&gt;

&lt;p&gt;Throughout the deployment process, we configured service access roles, networking and subnets, instance settings, and CloudWatch monitoring, ensuring the environment was production-ready. Once the environment was launched and its health status turned green, accessing the application through the provided domain confirmed a successful deployment.&lt;/p&gt;

&lt;p&gt;AWS Elastic Beanstalk proves to be a powerful platform for developers who want to deploy Node.js applications quickly without managing servers manually. It offers a balance between simplicity and flexibility, making it ideal for both beginners and experienced developers. With this foundation in place, you can now extend the deployment by integrating CI/CD pipelines, custom domains, HTTPS, environment variables, and scaling policies to support real-world production workloads.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>linux</category>
      <category>cloud</category>
      <category>automation</category>
    </item>
    <item>
      <title>Complete CI/CD Pipeline with Node.js, Docker, and Kubernetes</title>
      <dc:creator>SUBAIR NURUDEEN ADEWALE</dc:creator>
      <pubDate>Tue, 23 Dec 2025 16:40:15 +0000</pubDate>
      <link>https://dev.to/subair09/complete-cicd-pipeline-with-nodejs-docker-and-kubernetes-2604</link>
      <guid>https://dev.to/subair09/complete-cicd-pipeline-with-nodejs-docker-and-kubernetes-2604</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This guide provides a hands-on, end-to-end walkthrough for building, testing, containerizing, and deploying a modern Node.js web application using real-world DevOps best practices.&lt;/p&gt;

&lt;p&gt;Instead of focusing only on writing application code, this project is designed to help you understand how software is built, tested, packaged, automated, and deployed in professional environments. By the end of this guide, you will have a fully functional Node.js application with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automated testing&lt;/li&gt;
&lt;li&gt;A CI/CD pipeline using GitHub Actions&lt;/li&gt;
&lt;li&gt;Docker containerization&lt;/li&gt;
&lt;li&gt;Kubernetes deployment configurations&lt;/li&gt;
&lt;li&gt;A clear staging and production workflow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The project intentionally uses core Node.js (without frameworks like Express) to help you understand what happens under the hood, making it ideal for DevOps engineers, backend developers, cloud engineers, and beginners transitioning into DevOps.&lt;/p&gt;

&lt;p&gt;This guide follows a step-by-step approach, ensuring you can complete the project in short sessions while gaining practical, job-ready skills.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Objectives&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By completing this project, you will be able to:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Build a production-ready Node.js web application&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a basic HTTP server&lt;/li&gt;
&lt;li&gt;Serve HTML pages and JSON APIs&lt;/li&gt;
&lt;li&gt;Implement health checks, metrics, and system info endpoints&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Apply software engineering best practices&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use Git for version control&lt;/li&gt;
&lt;li&gt;Write automated tests with Jest and Supertest&lt;/li&gt;
&lt;li&gt;Enforce code quality using ESLint&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Implement CI/CD with GitHub Actions&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatically run tests and linting on every push&lt;/li&gt;
&lt;li&gt;Build and push Docker images to a container registry&lt;/li&gt;
&lt;li&gt;Scan container images for security vulnerabilities&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Containerize applications using Docker&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create optimized, multi-stage Docker images&lt;/li&gt;
&lt;li&gt;Run applications securely as a non-root user&lt;/li&gt;
&lt;li&gt;Configure health checks and proper signal handling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Run and manage applications locally with Docker Compose&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Simplify local development and testing&lt;/li&gt;
&lt;li&gt;Manage environment variables and service health&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Prepare applications for Kubernetes deployment&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create staging and production Kubernetes manifests&lt;/li&gt;
&lt;li&gt;Configure replicas, probes, and resource limits&lt;/li&gt;
&lt;li&gt;Follow environment-based deployment strategies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Prepare applications for Kubernetes deployment&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create staging and production Kubernetes manifests&lt;/li&gt;
&lt;li&gt;Configure replicas, probes, and resource limits&lt;/li&gt;
&lt;li&gt;Follow environment-based deployment strategies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Understand real-world DevOps workflows&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use branch-based deployments (develop - staging, main - production)&lt;/li&gt;
&lt;li&gt;Monitor CI/CD pipelines and container builds&lt;/li&gt;
&lt;li&gt;Troubleshoot common DevOps and deployment issues&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prerequisites – Download These First
&lt;/h2&gt;

&lt;p&gt;Before we start building the CI/CD pipeline, you need to install a few essential tools. These tools form the foundation of the development, containerization, and automation workflow used throughout this project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Node.js (v18 or higher)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node.js is the runtime used to build and run our web application.&lt;/li&gt;
&lt;li&gt;Current LTS (2025): v20.x&lt;/li&gt;
&lt;li&gt;Download: &lt;a href="https://nodejs.org/" rel="noopener noreferrer"&gt;https://nodejs.org/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Choose the LTS version for stability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Verify installation:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;node --version&lt;/code&gt;&lt;br&gt;
&lt;code&gt;npm --version&lt;/code&gt;&lt;/p&gt;

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

&lt;p&gt;Node.js: v18.x+ or v20.x+&lt;/p&gt;

&lt;p&gt;npm: 9.x+ or 10.x+&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Git (Latest Stable Version)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Git is used for version control and collaboration. It also triggers our CI/CD pipeline when code is pushed to GitHub.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Download: &lt;a href="https://git-scm.com/downloads" rel="noopener noreferrer"&gt;https://git-scm.com/downloads&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Select your operating system and complete the installation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Verify installation:&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;git --version&lt;/code&gt;&lt;/p&gt;

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

&lt;p&gt;Git version 2.34+&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Docker Desktop (Latest Version)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Docker allows us to package the application into containers so it runs the same everywhere — solving the classic “it works on my machine” problem.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Download: &lt;a href="https://www.docker.com/products/docker-desktop/" rel="noopener noreferrer"&gt;https://www.docker.com/products/docker-desktop/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Install and start Docker Desktop after installation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Verify installation:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker --version&lt;/code&gt;&lt;br&gt;
&lt;code&gt;docker-compose --version&lt;/code&gt;&lt;/p&gt;

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

&lt;p&gt;Docker version 24.x+&lt;/p&gt;

&lt;p&gt;Docker Compose available and running&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub Account&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub hosts your source code and runs the automated CI/CD pipeline using GitHub Actions.&lt;/li&gt;
&lt;li&gt;Sign up: &lt;a href="https://github.com" rel="noopener noreferrer"&gt;https://github.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;You will use GitHub to:&lt;/li&gt;
&lt;li&gt;Store your project code&lt;/li&gt;
&lt;li&gt;Trigger automated tests&lt;/li&gt;
&lt;li&gt;Build Docker images&lt;/li&gt;
&lt;li&gt;Deploy to staging and production environments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Code Editor (Optional but Recommended)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A code editor makes writing, reading, and managing your code much easier.&lt;/p&gt;

&lt;p&gt;Recommended:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;VS Code: &lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;https://code.visualstudio.com/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Alternatives:&lt;/li&gt;
&lt;li&gt;Sublime Text&lt;/li&gt;
&lt;li&gt;Atom&lt;/li&gt;
&lt;li&gt;Any editor you’re comfortable with&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Final Verification Checklist&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run the following commands to confirm everything is installed correctly:&lt;/p&gt;

&lt;p&gt;node --version    # v18.x+ or v20.x+&lt;br&gt;
npm --version     # 9.x+ or 10.x+&lt;br&gt;
git --version     # 2.34+&lt;br&gt;
docker --version  # 24.x+&lt;/p&gt;

&lt;p&gt;If all commands return valid versions, you’re ready to move on.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 1: Set Up Git for Version Control
&lt;/h2&gt;

&lt;p&gt;What this step does: it Configures Git on your machine so it knows who you are when you make commits, and sets up proper project tracking.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One-time Git Configuration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git config --global user.name "Your Name"&lt;/code&gt;&lt;br&gt;
&lt;code&gt;git config --global user.email "you@example.com"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;1.1 Select** Terminal** at the top of visual studio code and select *&lt;em&gt;new terminal *&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%2Fi9jwvfoqvke2o13y3bc8.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%2Fi9jwvfoqvke2o13y3bc8.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;1.2 Enter the One-time Git Configuration&lt;/p&gt;

&lt;p&gt;What this step does: it Configures Git on your machine so it knows who you are when you make commits, and sets up proper project tracking.&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%2Fe72bi8oob99vbk55pbvu.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%2Fe72bi8oob99vbk55pbvu.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.3 Create and Initialize Project&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mkdir my-devops-project&lt;/code&gt;&lt;br&gt;
&lt;code&gt;cd my-devops-project&lt;/code&gt;&lt;br&gt;
&lt;code&gt;git init&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mkdir my-devops-project&lt;/code&gt;&lt;br&gt;
Creates a new folder (directory) named my-devops-project.&lt;/p&gt;

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

&lt;p&gt;&lt;code&gt;cd my-devops-project&lt;/code&gt;&lt;br&gt;
What it does: Moves you into the newly created folder, Your terminal is now pointing to: &lt;strong&gt;.../my-devops-project&lt;/strong&gt; Anything you create next will live inside this folder.&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%2Fvnsvr403lpcb9ifwxgds.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%2Fvnsvr403lpcb9ifwxgds.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git init&lt;/code&gt;&lt;br&gt;
What it does: Initializes a new Git repository in the current folder&lt;br&gt;
Behind the scenes: Git creates a hidden .git/ directory This folder stores: Version history, Branches, Commits and configurations.&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%2Ftl2epqlfv1nb87t7pjp0.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%2Ftl2epqlfv1nb87t7pjp0.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;code .&lt;/code&gt;&lt;br&gt;
use code . to open the current folder in Visual Studio Code.&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%2Fko6i1nqjbm3wvqcw4hwm.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%2Fko6i1nqjbm3wvqcw4hwm.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Current folder (my-devops-project)&lt;/strong&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%2F69wbkzqxz1u6fiuxakwb.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%2F69wbkzqxz1u6fiuxakwb.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 2: Build a Node.js Web App
&lt;/h2&gt;

&lt;p&gt;What this step does: Creates a web application using Node.js that can serve web pages and API endpoints.&lt;/p&gt;

&lt;p&gt;Initialize Node.js Project using &lt;strong&gt;npm init -y&lt;/strong&gt;&lt;br&gt;
What this step does: Creates a package.json file that describes your project and manages dependencies.&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%2F245mjll80g3qtkpkxnod.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%2F245mjll80g3qtkpkxnod.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.1 Update package.json&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Open the package.json file and update it with the appropriate project details and scripts that will be used throughout the CI/CD pipeline.&lt;br&gt;
This includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Project name and description&lt;/li&gt;
&lt;li&gt;Entry point (app.js or server.js)&lt;/li&gt;
&lt;li&gt;Start and test scripts&lt;/li&gt;
&lt;li&gt;Metadata used during builds and deployments
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "name": "my-devops-project",
  "version": "1.0.0",
  "description": "DevOps learning project with Node.js",
  "main": "app.js",
  "scripts": {
    "start": "node app.js",
    "test": "jest",
    "dev": "node app.js",
    "lint": "eslint ."
  },
  "keywords": ["devops", "nodejs", "docker"],
  "author": "Your Name",
  "license": "MIT",
  "engines": {
    "node": "&amp;gt;=18.0.0"
  },
  "devDependencies": {
    "jest": "^29.7.0",
    "eslint": "^8.57.0",
    "supertest": "^7.1.4"
  }
}
&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%2F71sxk4knd1q7rlfn3s87.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%2F71sxk4knd1q7rlfn3s87.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;2.2 Create Application File (app.js) *&lt;/em&gt;&lt;br&gt;
What this code does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creates an HTTP server that listens on port 3000&lt;/li&gt;
&lt;li&gt;Serves different endpoints (/, /health, /info, /metrics)&lt;/li&gt;
&lt;li&gt;Includes security headers and proper error handling&lt;/li&gt;
&lt;li&gt;Provides graceful shutdown capability&lt;/li&gt;
&lt;li&gt;Exports the server for testing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Create app.js file  using &lt;strong&gt;touch&lt;/strong&gt; app.js or &lt;strong&gt;New-item&lt;/strong&gt; app.js.&lt;/p&gt;

&lt;p&gt;the app.js file is the entry point i.e the starting point of our application it contains configurations. It is the file that Node.js loads first when the application starts.&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%2F8ej8lzhxiiryqcz7s6bx.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%2F8ej8lzhxiiryqcz7s6bx.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy this code into the applicagion file app.js.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// core modules
const http = require("http");
const url = require("url");

// environment configuration
const PORT = process.env.PORT || 3000;
const ENVIRONMENT = process.env.NODE_ENV || "development";

let requestCount = 0;

// helper: send JSON responses
function sendJSON(res, statusCode, data) {
  res.statusCode = statusCode;
  res.setHeader("Content-Type", "application/json");
  res.end(JSON.stringify(data, null, 2));
}

// helper: send HTML responses
function sendHTML(res, statusCode, content) {
  res.statusCode = statusCode;
  res.setHeader("Content-Type", "text/html");
  res.end(content);
}

// helper: send Prometheus metrics
function sendMetrics(res) {
  const mem = process.memoryUsage();
  const metrics = `
# HELP http_requests_total Total HTTP requests
# TYPE http_requests_total counter
http_requests_total ${requestCount}

# HELP app_uptime_seconds Application uptime in seconds
# TYPE app_uptime_seconds gauge
app_uptime_seconds ${process.uptime()}

# HELP nodejs_memory_usage_bytes Node.js memory usage
# TYPE nodejs_memory_usage_bytes gauge
nodejs_memory_usage_bytes{type="rss"} ${mem.rss}
nodejs_memory_usage_bytes{type="heapUsed"} ${mem.heapUsed}
nodejs_memory_usage_bytes{type="heapTotal"} ${mem.heapTotal}
nodejs_memory_usage_bytes{type="external"} ${mem.external}
`;
  res.statusCode = 200;
  res.setHeader("Content-Type", "text/plain");
  res.end(metrics);
}

// main server
const server = http.createServer((req, res) =&amp;gt; {
  requestCount++;
  const timestamp = new Date().toISOString();
  const { pathname } = url.parse(req.url, true);

  // logging
  console.log(
    `${timestamp} - ${req.method} ${pathname} - ${
      req.headers["user-agent"] || "Unknown"
    }`
  );

  // CORS headers
  res.setHeader("Access-Control-Allow-Origin", "*");
  res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
  res.setHeader("Access-Control-Allow-Headers", "Content-Type");

  // security headers
  res.setHeader("X-Content-Type-Options", "nosniff");
  res.setHeader("X-Frame-Options", "DENY");
  res.setHeader("X-XSS-Protection", "1; mode=block");

  // route handling
  switch (pathname) {
    case "/":
      sendHTML(
        res,
        200,
        `
&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
  &amp;lt;title&amp;gt;DevOps Lab 2025&amp;lt;/title&amp;gt;
  &amp;lt;style&amp;gt;
    body { font-family: Arial, sans-serif; max-width: 800px; margin: 50px auto; padding: 20px; }
    .header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 20px; border-radius: 8px; }
    .endpoint { background: #f8f9fa; padding: 15px; margin: 10px 0; border-radius: 5px; border-left: 4px solid #007bff; }
  &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
  &amp;lt;div class="header"&amp;gt;
    &amp;lt;h1&amp;gt;DevOps Lab 2025&amp;lt;/h1&amp;gt;
    &amp;lt;p&amp;gt;Modern Node.js application with CI/CD pipeline&amp;lt;/p&amp;gt;
  &amp;lt;/div&amp;gt;
  &amp;lt;h2&amp;gt;Available Endpoints:&amp;lt;/h2&amp;gt;
  &amp;lt;div class="endpoint"&amp;gt;&amp;lt;strong&amp;gt;GET /&amp;lt;/strong&amp;gt; - This welcome page&amp;lt;/div&amp;gt;
  &amp;lt;div class="endpoint"&amp;gt;&amp;lt;strong&amp;gt;GET /health&amp;lt;/strong&amp;gt; - Health check (JSON)&amp;lt;/div&amp;gt;
  &amp;lt;div class="endpoint"&amp;gt;&amp;lt;strong&amp;gt;GET /info&amp;lt;/strong&amp;gt; - System information&amp;lt;/div&amp;gt;
  &amp;lt;div class="endpoint"&amp;gt;&amp;lt;strong&amp;gt;GET /metrics&amp;lt;/strong&amp;gt; - Prometheus metrics&amp;lt;/div&amp;gt;
  &amp;lt;p&amp;gt;Environment: &amp;lt;strong&amp;gt;${ENVIRONMENT}&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;
  &amp;lt;p&amp;gt;Server time: &amp;lt;strong&amp;gt;${timestamp}&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;
  &amp;lt;p&amp;gt;Requests served: &amp;lt;strong&amp;gt;${requestCount}&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;`
      );
      break;

    case "/health":
      sendJSON(res, 200, {
        status: "healthy",
        timestamp,
        uptime: process.uptime(),
        environment: ENVIRONMENT,
        version: "1.0.0",
        node_version: process.version,
        requests_served: requestCount,
      });
      break;

    case "/info":
      sendJSON(res, 200, {
        platform: process.platform,
        architecture: process.arch,
        node_version: process.version,
        memory_usage: process.memoryUsage(),
        environment: ENVIRONMENT,
        pid: process.pid,
        uptime: process.uptime(),
      });
      break;

    case "/metrics":
      sendMetrics(res);
      break;

    default:
      sendJSON(res, 404, {
        error: "Not Found",
        message: `Route ${pathname} not found`,
        timestamp,
      });
  }
});

// graceful shutdown
function shutdown(signal) {
  console.log(`\nReceived ${signal}, shutting down gracefully...`);
  server.close(() =&amp;gt; {
    console.log("Server closed");
    process.exit(0);
  });
}
process.on("SIGTERM", () =&amp;gt; shutdown("SIGTERM"));
process.on("SIGINT", () =&amp;gt; shutdown("SIGINT"));

// start server
server.listen(PORT, () =&amp;gt; {
  console.log(`🚀 Server running at http://localhost:${PORT}/`);
  console.log(`Environment: ${ENVIRONMENT}`);
  console.log(`Node.js version: ${process.version}`);
});

// export for testing
module.exports = server;
&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%2Fon5v8usbo9yvdp8buoy4.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%2Fon5v8usbo9yvdp8buoy4.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2.3 Install Dependencies&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Install testing and development tools using &lt;br&gt;
&lt;code&gt;npm install --save-dev jest eslint supertest&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Install all dependencies (creates node_modules folder)&lt;br&gt;
&lt;code&gt;npm install&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;What you'll see:&lt;/p&gt;

&lt;p&gt;A node_modules/ folder with all installed packages&lt;br&gt;
A package-lock.json file that locks dependency versions&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%2Fjqald0ra5ugnipv1v156.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%2Fjqald0ra5ugnipv1v156.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 3: Create Proper Tests
&lt;/h2&gt;

&lt;p&gt;What this step does: Sets up automated testing so you can verify your application works correctly every time you make changes.&lt;/p&gt;

&lt;p&gt;3.1 Create tests directory and test file&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a folder for your tests&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;mkdir tests&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create the main test file&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;touch tests/app.test.js&lt;/code&gt; or &lt;code&gt;New-item tests/app.test.js&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%2F50pkchr0qlwh2vqcrvqh.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%2F50pkchr0qlwh2vqcrvqh.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Copy this code into tests/app.test.js:&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;const request = require('supertest');
const server = require('../app');

describe('App Endpoints', () =&amp;gt; {
  afterAll(() =&amp;gt; {
    server.close();
  });

  test('GET / should return welcome page', async () =&amp;gt; {
    const response = await request(server).get('/');
    expect(response.status).toBe(200);
    expect(response.text).toContain('DevOps Lab 2025');
  });

  test('GET /health should return health status', async () =&amp;gt; {
    const response = await request(server).get('/health');
    expect(response.status).toBe(200);
    expect(response.body.status).toBe('healthy');
    expect(response.body.timestamp).toBeDefined();
    expect(typeof response.body.uptime).toBe('number');
  });

  test('GET /info should return system info', async () =&amp;gt; {
    const response = await request(server).get('/info');
    expect(response.status).toBe(200);
    expect(response.body.platform).toBeDefined();
    expect(response.body.node_version).toBeDefined();
  });

  test('GET /metrics should return prometheus metrics', async () =&amp;gt; {
    const response = await request(server).get('/metrics');
    expect(response.status).toBe(200);
    expect(response.text).toContain('http_requests_total');
    expect(response.text).toContain('app_uptime_seconds');
  });

  test('GET /nonexistent should return 404', async () =&amp;gt; {
    const response = await request(server).get('/nonexistent');
    expect(response.status).toBe(404);
    expect(response.body.error).toBe('Not Found');
  });
});
&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%2F87mrw46pqdoq725cyt1i.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%2F87mrw46pqdoq725cyt1i.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create Jest configuration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create jest.config.js using the command &lt;code&gt;touch jest.config.js&lt;/code&gt; or &lt;code&gt;New-item jest.config.js&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%2Fn7nhitl03i3wx70y3lnx.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%2Fn7nhitl03i3wx70y3lnx.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Copy the code into the jest.config.js file&lt;/em&gt;*&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
  testEnvironment: 'node',
  collectCoverage: true,
  coverageDirectory: 'coverage',
  testMatch: ['**/tests/**/*.test.js'],
  verbose: true
};
&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%2Fio8m9c0uy82ttar04k8d.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%2Fio8m9c0uy82ttar04k8d.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: GitHub Actions CI/CD Pipeline
&lt;/h2&gt;

&lt;p&gt;What this step does: Creates an automated pipeline that runs tests and builds Docker images every time you push code to GitHub.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4.1 Create workflow directory&lt;/strong&gt;&lt;br&gt;
Create the GitHub Actions directory structure using the command&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mkdir -p .github/workflows&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4.2 Create CI/CD pipeline file&lt;/strong&gt;&lt;br&gt;
Create .github/workflows/ci.yml using the command &lt;code&gt;touch .github/workflows/ci.yml&lt;/code&gt; or &lt;code&gt;New-item github/workflows/ci.yml&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%2Fm88zv56u9fv00qnimwca.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%2Fm88zv56u9fv00qnimwca.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4.3 Copy this code into the CI/CD Pipeline file.&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: CI/CD Pipeline

on:
  push:
    branches: [ main, develop ]
    tags: [ 'v*' ]
  pull_request:
    branches: [ main ]

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  test:
    name: Test &amp;amp; Lint
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [20, 22]

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Setup Node.js ${{ matrix.node-version }}
        uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: 'npm'

      - name: Install dependencies
        run: npm ci

      - name: Run linting
        run: npm run lint

      - name: Run tests
        run: npm test

      - name: Security audit
        run: npm audit --audit-level=critical || echo "Audit completed with warnings"

  build:
    name: Build &amp;amp; Push Image
    runs-on: ubuntu-latest
    needs: test
    if: github.event_name == 'push'

    permissions:
      contents: read
      packages: write
      security-events: write

    outputs:
      image-tag: ${{ steps.meta.outputs.tags }}
      image-digest: ${{ steps.build.outputs.digest }}

    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
        with:
          platforms: linux/amd64,linux/arm64

      - name: Log in to Container Registry
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Extract metadata
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
          tags: |
            type=ref,event=branch
            type=ref,event=pr
            type=semver,pattern={{version}}
            type=semver,pattern={{major}}.{{minor}}
            type=sha,prefix={{branch}}-
            type=raw,value=${{ github.run_id }}
            type=raw,value=latest,enable={{is_default_branch}}
          labels: |
            org.opencontainers.image.title=DevOps Lab 2025
            org.opencontainers.image.description=Modern Node.js DevOps application

      - name: Build and push Docker image
        id: build
        uses: docker/build-push-action@v5
        with:
          context: .
          platforms: linux/amd64,linux/arm64
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max
          target: production

      - name: Run Trivy vulnerability scanner
        uses: aquasecurity/trivy-action@0.24.0
        with:
          image-ref: ${{ steps.meta.outputs.tags }}
          format: 'sarif'
          output: 'trivy-results.sarif'
          severity: 'CRITICAL,HIGH'
        continue-on-error: true

      - name: Upload Trivy scan results
        uses: github/codeql-action/upload-sarif@v3
        if: always() &amp;amp;&amp;amp; hashFiles('trivy-results.sarif') != ''
        with:
          sarif_file: 'trivy-results.sarif'

  deploy-staging:
    name: Deploy to Staging
    runs-on: ubuntu-latest
    needs: build
    if: github.ref == 'refs/heads/develop'
    environment: staging

    steps:
      - name: Deploy to Staging
        run: |
          echo "🚀 Deploying to staging environment..."
          echo "Image: ${{ needs.build.outputs.image-tag }}"
          echo "Digest: ${{ needs.build.outputs.image-digest }}"
          # Add your staging deployment commands here (kubectl, helm, etc.)

  deploy-production:
    name: Deploy to Production
    runs-on: ubuntu-latest
    needs: build
    if: github.ref == 'refs/heads/main'
    environment: production

    steps:
      - name: Deploy to Production
        run: |
          echo "🎯 Deploying to production environment..."
          echo "Image: ${{ needs.build.outputs.image-tag }}"
          echo "Digest: ${{ needs.build.outputs.image-digest }}"
          # Add your production deployment commands here
&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%2Fva5nocrcm1dc2q9i1cug.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%2Fva5nocrcm1dc2q9i1cug.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Dockerfile
&lt;/h2&gt;

&lt;p&gt;What this step does: Creates instructions for Docker to build a container image of your application that can run anywhere.&lt;/p&gt;

&lt;p&gt;What this Dockerfile does:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uses multi-stage builds for smaller image size&lt;/li&gt;
&lt;li&gt;Installs curl for health checks&lt;/li&gt;
&lt;li&gt;Creates a non-root user for security&lt;/li&gt;
&lt;li&gt;Sets up proper file permissions&lt;/li&gt;
&lt;li&gt;Configures health checks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Create Dockerfile:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;create a dockerfile using the command &lt;code&gt;touch Dockerfile&lt;/code&gt; or &lt;code&gt;New-item Dockerfile&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%2Fdkxt1tncds2w0wy5j0jl.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%2Fdkxt1tncds2w0wy5j0jl.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Copy the docker instructions into the Dockerfile.&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;# Multi-stage build for optimized image
FROM node:20-alpine AS dependencies

# Update packages for security
RUN apk update &amp;amp;&amp;amp; apk upgrade --no-cache

WORKDIR /app

# Copy package files first for better caching
COPY package*.json ./

# Install only production dependencies
RUN npm ci --only=production &amp;amp;&amp;amp; npm cache clean --force

# Production stage  
FROM node:20-alpine AS production

# Update packages and install necessary tools
RUN apk update &amp;amp;&amp;amp; apk upgrade --no-cache &amp;amp;&amp;amp; \
    apk add --no-cache curl dumb-init &amp;amp;&amp;amp; \
    rm -rf /var/cache/apk/*

# Create non-root user with proper permissions
RUN addgroup -g 1001 -S nodejs &amp;amp;&amp;amp; \
    adduser -S nodeuser -u 1001 -G nodejs

WORKDIR /app

# Copy dependencies from previous stage with proper ownership
COPY --from=dependencies --chown=nodeuser:nodejs /app/node_modules ./node_modules

# Copy application code with proper ownership
COPY --chown=nodeuser:nodejs package*.json ./
COPY --chown=nodeuser:nodejs app.js ./

# Switch to non-root user
USER nodeuser

# Expose port
EXPOSE 3000

# Health check with proper timing for Node.js startup
HEALTHCHECK --interval=30s --timeout=10s --start-period=15s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1

# Use dumb-init for proper signal handling in containers
ENTRYPOINT ["dumb-init", "--"]

# Start application
CMD ["npm", "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%2F6wdax1w7zbjc854e94qf.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%2F6wdax1w7zbjc854e94qf.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Essential Configuration Files
&lt;/h2&gt;

&lt;p&gt;What this step does: Creates configuration files that tell various tools what to ignore, how to behave, and what settings to use.&lt;/p&gt;

&lt;p&gt;Create .dockerignore using the command &lt;code&gt;touch .dockerignore&lt;/code&gt; or &lt;code&gt;New-item .dockerignore&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%2Fykc5domu7japv1c754qw.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%2Fykc5domu7japv1c754qw.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy this code into the .dockerignore file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Node.js dependencies
node_modules
npm-debug.log*
yarn-error.log*

# Git &amp;amp; CI/CD
.git
.github

# Environment variables
.env
.env.local
.env.*.local

# Logs
logs
*.log

# Test &amp;amp; coverage files
tests/
coverage
.nyc_output
jest.config.js

# Linting &amp;amp; config files
.eslintrc*
README.md

# IDE &amp;amp; editor files
.vscode
.idea
*.swp
*.swo

# OS-specific files
.DS_Store
Thumbs.db
&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%2Fj8k9wqndszycu85ik5jr.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%2Fj8k9wqndszycu85ik5jr.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6.1 Create .gitignore&lt;/strong&gt;&lt;br&gt;
Create .gitignore usinf the command &lt;code&gt;touch .gitignore&lt;/code&gt; or &lt;code&gt;New-item .gitignore&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%2Fm7y6880fn2uw3lfbxnf9.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%2Fm7y6880fn2uw3lfbxnf9.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy this code into the .gitignore file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Node.js dependencies
node_modules
npm-debug.log*
yarn-error.log*

# Git &amp;amp; CI/CD
.git
.github

# Environment variables
.env
.env.local
.env.*.local

# Logs
logs
*.log

# Test &amp;amp; coverage files
tests/
coverage
.nyc_output
jest.config.js

# Linting &amp;amp; config files
.eslintrc*
README.md

# IDE &amp;amp; editor files
.vscode
.idea
*.swp
*.swo

# OS-specific files
.DS_Store
Thumbs.db
&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%2Fjo3ube1gbpsdgsm4r5xq.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%2Fjo3ube1gbpsdgsm4r5xq.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6.2 Create environment template&lt;/strong&gt;&lt;br&gt;
Create .env.example using the command &lt;code&gt;touch .env.example&lt;/code&gt; or &lt;code&gt;touch New-item .env.example&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%2F7q8mdg6o5lg33xqnzhjz.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%2F7q8mdg6o5lg33xqnzhjz.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy this configuration into the .env.example file and save.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;# Server Configuration PORT=3000 NODE_ENV=production  # Logging LOG_LEVEL=info&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%2Fv33xy6pzdgr9fmg4ay6x.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%2Fv33xy6pzdgr9fmg4ay6x.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6.3 Create ESLint configuration&lt;/strong&gt;&lt;br&gt;
Create .eslintrc.js file using the command &lt;code&gt;touch .eslintrc.js&lt;/code&gt; or &lt;code&gt;New-item .eslintrc.js&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%2Fn319jbu43q9ykscci9vk.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%2Fn319jbu43q9ykscci9vk.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy this code into the .eslintrc.js file and save.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
  env: {
    node: true,
    es2021: true,
    jest: true
  },
  extends: ['eslint:recommended'],
  parserOptions: {
    ecmaVersion: 12,
    sourceType: 'module'
  },
  rules: {
    'no-console': 'off',
    'no-unused-vars': ['error', { 'argsIgnorePattern': '^_' }]
  }
};

&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%2Fre3o4dk9r1xf4sxnunka.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%2Fre3o4dk9r1xf4sxnunka.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 7: Docker Compose for Development
&lt;/h2&gt;

&lt;p&gt;What this step does: Creates a Docker Compose file that makes it easy to run your application and any supporting services with a single command.&lt;/p&gt;

&lt;p&gt;Create docker-compose.yml using the command &lt;code&gt;touch docker-compose.yml&lt;/code&gt; or &lt;code&gt;New-item docker-compose.yml&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%2Faxclpvg9e2q55baz6n0j.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%2Faxclpvg9e2q55baz6n0j.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy this code into the docker-compose.yml file and save.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;version: '3.8'
services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=development
      - PORT=3000
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 10s

&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%2Fz5qql8aem8j7ywwq3xlh.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%2Fz5qql8aem8j7ywwq3xlh.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 8: Test Everything Locally
&lt;/h2&gt;

&lt;p&gt;What this step does: Shows you how to actually run and test your application locally before deploying it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install and Test Locally&lt;/strong&gt;&lt;br&gt;
Install all dependencies from package.json using the command &lt;code&gt;npm install&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%2Fo9binidq0fwr8urmcgkp.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%2Fo9binidq0fwr8urmcgkp.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Run your test suite to make sure everything works using the command&lt;br&gt;
&lt;code&gt;npm test&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%2Fa75c509qpqplrxnhuujg.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%2Fa75c509qpqplrxnhuujg.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Start the application server using the command &lt;br&gt;
&lt;code&gt;npm start&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%2Ftkqf6bkqp8b9kx2d0zbi.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%2Ftkqf6bkqp8b9kx2d0zbi.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What you'll see:&lt;/p&gt;

&lt;p&gt;Tests should pass with green checkmarks: ✓ GET / should return welcome page&lt;br&gt;
Server starts and shows: 🚀 Server running at &lt;a href="http://localhost:3000/" rel="noopener noreferrer"&gt;http://localhost:3000/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test endpoints (in a new terminal window) by copying and pasting each into a terminal.&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;curl http://localhost:3000/&lt;/code&gt;        # Homepage&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%2Fob876ta2p6xcdrjbm52l.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%2Fob876ta2p6xcdrjbm52l.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;curl http://localhost:3000/health&lt;/code&gt;   # Health check JSON&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%2Fhrn6dp69icwsdylhdulw.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%2Fhrn6dp69icwsdylhdulw.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;curl http://localhost:3000/info&lt;/code&gt;    # System info JSON  &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%2Forbkxwxyorpu9gzidcny.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%2Forbkxwxyorpu9gzidcny.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;curl &lt;a href="http://localhost:3000/metrics" rel="noopener noreferrer"&gt;http://localhost:3000/metrics&lt;/a&gt;  # Prometheus metrics&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%2Fexm55mbtcfcr070v80un.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%2Fexm55mbtcfcr070v80un.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy the url localhost:3000 into a browser to see your application.&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%2F5rf6rpvh7l1l5ki3s5e3.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%2F5rf6rpvh7l1l5ki3s5e3.png" alt=" " width="800" height="411"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Docker Commands&lt;/strong&gt;&lt;br&gt;
Start docker desktop application to start the docker engine and run the docker command to build the image &lt;br&gt;
&lt;strong&gt;# Build image&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker build -t my-devops-app:latest .&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%2Fjksammllv4pjsdg9tvkg.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%2Fjksammllv4pjsdg9tvkg.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Navigate to docker desktop to see the image &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%2F0is7ny5jfcsfmmt6g3tz.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%2F0is7ny5jfcsfmmt6g3tz.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Run container&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;docker run -d --name my-devops-container -p 3000:3000 --restart unless-stopped my-devops-app:latest&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%2F2fp0xis8l2mmckpu7rnt.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%2F2fp0xis8l2mmckpu7rnt.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Navigate to docker desktop to see the container&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%2F7mgpopa5882wvcnk1pbn.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%2F7mgpopa5882wvcnk1pbn.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Check container status&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;docker ps&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%2Fbadbu50vzb4kcbh8nav9.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%2Fbadbu50vzb4kcbh8nav9.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;docker logs my-devops-container&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%2Fw8xz8bl5vn5t3tkqonv6.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%2Fw8xz8bl5vn5t3tkqonv6.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test health check&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;curl http://localhost:3000/health&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%2Fjezavdg095ybodvwlq0l.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%2Fjezavdg095ybodvwlq0l.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stop container&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;docker stop my-devops-container&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%2Fzhrawgiyz4946d78r0k4.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%2Fzhrawgiyz4946d78r0k4.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Navigate to Docker desktop to see the stopped container &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%2Fj4dpn7txgfmluv7v5ouy.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%2Fj4dpn7txgfmluv7v5ouy.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Remove the container&lt;/strong&gt; &lt;br&gt;
docker rm my-devops-container&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%2Fmm88ob6l51rgbcc88fpr.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%2Fmm88ob6l51rgbcc88fpr.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Navigate to Docker desktop to see if the container as been removed.&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%2Fchauuc5spsz5gldnvt1o.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%2Fchauuc5spsz5gldnvt1o.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Docker Compose Commands&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Start all services defined in docker-compose.yml&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;docker-compose up -d&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%2F9j71smwmvk8nj2hmzyv2.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%2F9j71smwmvk8nj2hmzyv2.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;View real-time logs from all services&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;docker-compose logs -f&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%2F1uo8utiq98dwk05spc3n.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%2F1uo8utiq98dwk05spc3n.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stop all services and clean up&lt;/strong&gt;&lt;br&gt;
docker-compose down&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%2Fbkksp2nnbuh5limeks4j.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%2Fbkksp2nnbuh5limeks4j.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 9: Deploy to GitHub
&lt;/h2&gt;

&lt;p&gt;What this step does: Commits your code to Git and pushes it to GitHub so the automated CI/CD pipeline can start working.&lt;br&gt;
Initial commit&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Add all files to Git staging area&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;git add .&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create your first commit with a descriptive message&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;git commit -m "Initial commit&lt;/code&gt;: Complete DevOps setup with working CI/CD"&lt;/p&gt;

&lt;p&gt;Connect to GitHub&lt;br&gt;
IMPORTANT: Before running these commands:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to GitHub.com and create a new repository called my-devops-project&lt;/li&gt;
&lt;li&gt;DO NOT initialize it with README, .gitignore, or license (we already have these)&lt;/li&gt;
&lt;li&gt;Copy the repository URL from GitHub&lt;/li&gt;
&lt;li&gt;Replace YOUR_GITHUB_USERNAME below with your actual GitHub username
Set main as the default branch &lt;code&gt;git branch -M main&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;# Connect to your GitHub repository (UPDATE THIS URL!)&lt;/li&gt;
&lt;li&gt;git remote add origin &lt;a href="https://github.com/YOUR_GITHUB_USERNAME/my-devops-project.git" rel="noopener noreferrer"&gt;https://github.com/YOUR_GITHUB_USERNAME/my-devops-project.git&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;# Push your code to GitHub for the first time &lt;code&gt;git push origin main&lt;/code&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%2F4np6tkobg2r03wldmrjh.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%2F4np6tkobg2r03wldmrjh.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What you'll see: Your code appears on GitHub, and the CI/CD pipeline starts running automatically.&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%2Fgkwzh8iyx9cldtp5exfi.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%2Fgkwzh8iyx9cldtp5exfi.png" alt=" " width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 10: Kubernetes Deployment Configurations
&lt;/h2&gt;

&lt;p&gt;What this step does: Creates Kubernetes configuration files that define how your application should run in staging and production environments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create directories&lt;/strong&gt;&lt;br&gt;
Create directories for Kubernetes configurations&lt;br&gt;
&lt;code&gt;mkdir -p k8s/staging&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Create Staging Deployment file *&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Create k8s/staging/deployment.yml file using touch  &lt;code&gt;k8s/staging/deployment.yml&lt;/code&gt; or &lt;code&gt;New-item k8s/staging/deployment.yml&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%2Fclp7rchfv55t51tsfqs2.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%2Fclp7rchfv55t51tsfqs2.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy this code into the deployment file &lt;br&gt;
NOTE: Update YOUR_GITHUB_USERNAME in the image URL below!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apiVersion: apps/v1
kind: Deployment
metadata:
  name: devops-app-staging
  namespace: staging
spec:
  replicas: 2
  selector:
    matchLabels:
      app: devops-app
      environment: staging
  template:
    metadata:
      labels:
        app: devops-app
        environment: staging
    spec:
      containers:
      - name: app
        image: ghcr.io/YOUR_GITHUB_USERNAME/my-devops-project:develop-latest
        ports:
        - containerPort: 3000
        env:
        - name: NODE_ENV
          value: "staging"
        - name: PORT
          value: "3000"
        livenessProbe:
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 5
          periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
  name: devops-app-service-staging
  namespace: staging
spec:
  selector:
    app: devops-app
    environment: staging
  ports:
  - protocol: TCP
    port: 80
    targetPort: 3000
  type: LoadBalancer
&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%2Fzhewtn4c02x0pg8b7s05.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%2Fzhewtn4c02x0pg8b7s05.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create Production Deployment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create k8s/production directory using the command &lt;code&gt;mkdir k8s/production&lt;/code&gt; and create the depployment file &lt;code&gt;touch k8s/production/deployment.yml&lt;/code&gt; or &lt;code&gt;New-item k8s/production/deployment.yml&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%2F3d7o7acq2l76wm2b2v6a.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%2F3d7o7acq2l76wm2b2v6a.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy this code into the k8s/production/deployment.yml file &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE: Update YOUR_GITHUB_USERNAME in the image URL below&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;apiVersion: apps/v1
kind: Deployment
metadata:
  name: devops-app-production
  namespace: production
spec:
  replicas: 3
  selector:
    matchLabels:
      app: devops-app
      environment: production
  template:
    metadata:
      labels:
        app: devops-app
        environment: production
    spec:
      containers:
      - name: app
        image: ghcr.io/YOUR_GITHUB_USERNAME/my-devops-project:latest
        ports:
        - containerPort: 3000
        env:
        - name: NODE_ENV
          value: "production"
        - name: PORT
          value: "3000"
        resources:
          requests:
            memory: "128Mi"
            cpu: "100m"
          limits:
            memory: "256Mi"
            cpu: "200m"
        livenessProbe:
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 5
          periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
  name: devops-app-service-production
  namespace: production
spec:
  selector:
    app: devops-app
    environment: production
  ports:
  - protocol: TCP
    port: 80
    targetPort: 3000
  type: LoadBalancer
&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%2Feka1jfspv03al1c1x22l.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%2Feka1jfspv03al1c1x22l.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 11: Complete Deployment Workflow
&lt;/h2&gt;

&lt;p&gt;What this step does: Shows you how to use the complete CI/CD pipeline with proper branching strategy for staging and production deployments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Branch-based Deployment Strategy&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;develop branch: Automatically deploys to staging environment&lt;/li&gt;
&lt;li&gt;main branch: Automatically deploys to production environment&lt;/li&gt;
&lt;li&gt;Pull requests: Run tests only (no deployment)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Deploy Changes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Deploy to staging:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create and switch to develop branch&lt;/strong&gt;&lt;br&gt;
use the command &lt;code&gt;git checkout -b develop&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Make your changes, then commit and push&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;git add .&lt;/code&gt;&lt;br&gt;
&lt;code&gt;git commit -m "Add new feature&lt;/code&gt;&lt;br&gt;
&lt;code&gt;git push origin develop&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%2Fr5q3xvtljt9ylkc5ldsx.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%2Fr5q3xvtljt9ylkc5ldsx.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What happens: GitHub Actions automatically runs tests and deploys to staging.&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%2Frb069r2xh9bze1fgfjfk.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%2Frb069r2xh9bze1fgfjfk.png" alt=" " width="800" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deploy to production:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Switch to main branch&lt;br&gt;
&lt;code&gt;git checkout main&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Merge changes from develop&lt;br&gt;
&lt;code&gt;git merge develop&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Push to trigger production deployment&lt;br&gt;
&lt;code&gt;git push origin main&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%2Fc0tgsya9w51ohluecnrk.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%2Fc0tgsya9w51ohluecnrk.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;What happens: GitHub Actions runs full pipeline and deploys to production.&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%2F1vn0z4eoyhhkdq48086a.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%2F1vn0z4eoyhhkdq48086a.png" alt=" " width="800" height="362"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Monitor Deployments&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Check GitHub Actions status&lt;/p&gt;

&lt;p&gt;Visit: &lt;strong&gt;&lt;a href="https://github.com/YOUR_GITHUB_USERNAME/my-devops-project/actions" rel="noopener noreferrer"&gt;https://github.com/YOUR_GITHUB_USERNAME/my-devops-project/actions&lt;/a&gt;&lt;/strong&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%2Fgn8avik2lpd6xdqf779a.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%2Fgn8avik2lpd6xdqf779a.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check your container registry&lt;br&gt;
Visit: &lt;strong&gt;&lt;a href="https://github.com/YOUR_GITHUB_USERNAME/REPO" rel="noopener noreferrer"&gt;https://github.com/YOUR_GITHUB_USERNAME/REPO&lt;/a&gt; NAME/pkgs/container/REPO NAME&lt;/strong&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%2F57606svsbqjppreijcbt.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%2F57606svsbqjppreijcbt.png" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Test your deployed applications (once you have URLs)&lt;/p&gt;

&lt;p&gt;curl &lt;a href="https://your-staging-url.com/health" rel="noopener noreferrer"&gt;https://your-staging-url.com/health&lt;/a&gt;      # Staging health check&lt;br&gt;
curl &lt;a href="https://your-production-url.com/health" rel="noopener noreferrer"&gt;https://your-production-url.com/health&lt;/a&gt;   # Production health check&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
This project successfully demonstrates a complete DevOps workflow for modern web application development. We transformed a basic Node.js application into a professional, automated system with CI/CD pipelines, containerization, and deployment strategies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Achievements&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;End-to-End Automation&lt;/strong&gt;: GitHub Actions automates testing, building, and deployment from code to production&lt;br&gt;
&lt;strong&gt;Containerization&lt;/strong&gt;: Docker creates secure, portable images that run consistently anywhere&lt;br&gt;
&lt;strong&gt;Professional Testing&lt;/strong&gt;: Jest and Supertest ensure application reliability with automated tests&lt;br&gt;
&lt;strong&gt;Security Integration&lt;/strong&gt;: Trivy vulnerability scanning and security headers protect the application&lt;br&gt;
&lt;strong&gt;Kubernetes Ready&lt;/strong&gt;: Production-grade deployment configurations for staging and production&lt;br&gt;
&lt;strong&gt;Branch-Based Workflow&lt;/strong&gt;: Safe deployments using develop/staging and main/production branches&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>node</category>
      <category>docker</category>
      <category>git</category>
    </item>
    <item>
      <title>How to Containerize an Application.</title>
      <dc:creator>SUBAIR NURUDEEN ADEWALE</dc:creator>
      <pubDate>Thu, 06 Nov 2025 10:59:35 +0000</pubDate>
      <link>https://dev.to/subair09/how-to-containerize-an-application-1446</link>
      <guid>https://dev.to/subair09/how-to-containerize-an-application-1446</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In today’s software development landscape, containerization has become an essential practice for building, deploying, and managing applications efficiently. This project focuses on containerizing a simple Node.js Todo List Manager application using Docker. By packaging the application and its dependencies into a container, developers can ensure consistency across different environments, simplify deployment, and improve scalability. Whether you're new to Docker or just getting started with containerization, this project offers a hands-on experience that demonstrates how to move an application from a local environment to a portable, containerized setup.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before you begin, ensure you have the following installed and set up on your system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker Desktop (latest version) – to build, run, and manage containers.&lt;/li&gt;
&lt;li&gt;Git client – to clone the project repository and manage source control.&lt;/li&gt;
&lt;li&gt;An IDE or text editor – such as Visual Studio Code, for editing and managing project files.&lt;/li&gt;
&lt;li&gt;(Optional but recommended) Basic understanding of terminal or command-line operations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 1 : Get the app&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Steps to Get the App and Run it in Visual Studio Code&lt;/li&gt;
&lt;li&gt;Open Visual Studio Code&lt;/li&gt;
&lt;li&gt;Launch VS Code on your computer.&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%2F61a9pqy6cmisc2yv4w2d.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%2F61a9pqy6cmisc2yv4w2d.png" alt=" " width="800" height="529"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open the Terminal&lt;/li&gt;
&lt;li&gt;Click on Terminal at the top menu and select new terminal&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%2F1zxv147c8x8h8snru0ck.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%2F1zxv147c8x8h8snru0ck.png" alt=" " width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clone the Application Repository&lt;/li&gt;
&lt;li&gt;In the terminal, type the following command and press Enter:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;git clone &lt;a href="https://github.com/docker/getting-started-app.git" rel="noopener noreferrer"&gt;https://github.com/docker/getting-started-app.git&lt;/a&gt;&lt;/strong&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%2Fyme3erlp125jare5u279.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%2Fyme3erlp125jare5u279.png" alt=" " width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Navigate into the App Folder
&lt;strong&gt;cd getting-started-app&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Open the Folder in VS Code (Optional)
&lt;strong&gt;code .&lt;/strong&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%2Fpsfd3vsva9fprn954xqb.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%2Fpsfd3vsva9fprn954xqb.png" alt=" " width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;View the contents of the cloned repository. You should see the following files and sub-directories.&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%2Frmug4qdp810q6zbeuxaf.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%2Frmug4qdp810q6zbeuxaf.png" alt=" " width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2 : Build image&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To build the image, you'll need to use a Dockerfile. A Dockerfile is simply a text-based file with no file extension that contains a script of instructions. Docker uses this script to build a container image.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In the getting-started-app directory, the same location as the package.json file, create a file named Dockerfile with the following contents:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This Dockerfile starts off with a node:lts-alpine base image, a light-weight Linux image that comes with Node.js and the Yarn package manager pre-installed. It copies all of the source code into the image, installs the necessary dependencies, and starts the application.&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%2F9ghm8ij0tvnrdmwg7lre.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%2F9ghm8ij0tvnrdmwg7lre.png" alt=" " width="800" height="512"&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%2Fzjkkx1lbgxsi5yq3eli1.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%2Fzjkkx1lbgxsi5yq3eli1.png" alt=" " width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build the image using the following commands:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;docker build -t getting-started-app .&lt;/strong&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%2Flyml0my1e0n3797cslyl.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%2Flyml0my1e0n3797cslyl.png" alt=" " width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Start an app container&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now that you have an image, you can run the application in a container using the docker run command.&lt;/li&gt;
&lt;li&gt;Run your container using the docker run command and specify the name of the image you just created:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;** docker run -d -p 127.0.0.1:3000:3000 getting-started**&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%2Fcjebvv3tueqvci6qqxvf.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%2Fcjebvv3tueqvci6qqxvf.png" alt=" " width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After a few seconds, open your web browser to &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;. You should see your app.&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%2Fecew539ak3bu6h1dajlz.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%2Fecew539ak3bu6h1dajlz.png" alt=" " width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By the end of this project, you will have successfully transformed a simple Node.js Todo List Manager into a fully containerized application. You’ll gain hands-on experience with Docker commands, image creation, and container management — valuable skills for modern DevOps and cloud-based development workflows. This exercise not only strengthens your understanding of containerization but also prepares you to deploy scalable, portable, and efficient applications in real-world environments.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>ubuntu</category>
      <category>containers</category>
      <category>ai</category>
    </item>
    <item>
      <title>My Personal Info &amp; Stats Display App Using C# Programming.</title>
      <dc:creator>SUBAIR NURUDEEN ADEWALE</dc:creator>
      <pubDate>Tue, 14 Oct 2025 13:26:06 +0000</pubDate>
      <link>https://dev.to/subair09/my-personal-info-stats-display-app-using-c-programming-3l13</link>
      <guid>https://dev.to/subair09/my-personal-info-stats-display-app-using-c-programming-3l13</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The “My Personal Info &amp;amp; Stats Display App” is a beginner friendly C# console project designed to strengthen my understanding of fundamental programming concepts such as data types, literals, and output formatting using Console.WriteLine(). In this project, I explored how to represent different types of data including strings, characters, integers, decimals, and booleans, and how each plays a unique role in programming. By combining these elements, the project displays basic personal details and computed values, helping me understand how C# handles and presents data in real world applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Project Description&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a C# console program that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Displays your personal information (using string and char)&lt;/li&gt;
&lt;li&gt;Shows your academic or skill statistics (using int and decimal)&lt;/li&gt;
&lt;li&gt;Indicates if you’ve completed a task or goal (using bool)&lt;/li&gt;
&lt;li&gt;Prints everything neatly formatted in the console window&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Create Your Project&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In Visual Studio Code, go to the menu bar and select Terminal, then choose New Terminal from the drop-down menu.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;-In your terminal type the command and type the** Enter key** on your keyboard&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;dotnet new console -n MyInfoApp&lt;/strong&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;dotnet new: tells the .NET SDK to create a new project.&lt;/li&gt;
&lt;li&gt;console: specifies the type of project (a console app that runs in the terminal).&lt;/li&gt;
&lt;li&gt;-n MyInfoApp: sets the name of the project to MyInfoApp.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;A new folder called MyInfoApp is created, containing files like:&lt;/li&gt;
&lt;li&gt;Program.cs (your main C# file)&lt;/li&gt;
&lt;li&gt;MyInfoApp.csproj (your project configuration 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%2F6sqhlfawxftnw9nd2fr5.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%2F6sqhlfawxftnw9nd2fr5.png" alt=" " width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Type the command and press &lt;strong&gt;Enter key&lt;/strong&gt; on your keyboard.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;cd MyInfoApp&lt;/strong&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;cd means “change directory.”&lt;/li&gt;
&lt;li&gt;This moves you into the newly created project folder so you can start working on your code.
Result:&lt;/li&gt;
&lt;li&gt;You are now inside the MyInfoApp folder in your terminal.&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%2Fx6dqbal6292q73jtpich.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%2Fx6dqbal6292q73jtpich.png" alt=" " width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Type the command and press &lt;strong&gt;Enter key&lt;/strong&gt; on your keyboard.
&lt;strong&gt;code .&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Explanation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;code opens Visual Studio Code.&lt;/li&gt;
&lt;li&gt;The . means “open the current folder” (in this case, MyInfoApp).&lt;/li&gt;
&lt;li&gt;Result:&lt;/li&gt;
&lt;li&gt;VS Code opens your project folder, ready for editing and running your app.&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%2Fsbu2d4lmqplloxe9mn5r.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%2Fsbu2d4lmqplloxe9mn5r.png" alt=" " width="800" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Type the code to pratice use of string literals and click the play button to run the program.&lt;/strong&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%2Fb1n4o14w4yno6w9sltoz.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%2Fb1n4o14w4yno6w9sltoz.png" alt=" " width="800" height="500"&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%2Fu58ndt8f7g2v5kvwn0yq.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%2Fu58ndt8f7g2v5kvwn0yq.PNG" alt=" " width="800" height="238"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Line-by-line Explanation&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Console.WriteLine("=====================================");&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This prints a line of equal signs on the console — it’s just decoration.&lt;/li&gt;
&lt;li&gt;You can think of it like drawing a border or header line.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Console.WriteLine("      My Personal Info Display App");&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This prints your app title with a few spaces before it.&lt;/li&gt;
&lt;li&gt;The spaces (" ") make the title appear centered visually&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Console.WriteLine("=====================================\n");&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This prints another line of equal signs (bottom border),&lt;/li&gt;
&lt;li&gt;and the \n at the end means go to a new line (line break).&lt;/li&gt;
&lt;li&gt;So, it adds one blank line after the header.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;string fullName = "Subair Nurudeen Adewale";&lt;br&gt;
string course = "C# Fundamentals at Skill.sch";&lt;br&gt;
string hobby = "Coding and Cloud Projects";&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;These create 3 string variables and store text in them:&lt;/li&gt;
&lt;li&gt;fullName holds your name&lt;/li&gt;
&lt;li&gt;course holds your course name&lt;/li&gt;
&lt;li&gt;hobby holds your hobby&lt;/li&gt;
&lt;li&gt;A string is just text inside double quotes " ".&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;- Console.WriteLine($"Name: {fullName}");&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The $ allows string interpolation, meaning you can insert variable values inside a text using {}.&lt;/li&gt;
&lt;li&gt;So here, {fullName} will be replaced by your actual name.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Console.WriteLine($"Course: {course}");&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Same idea - prints the text and your course variable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Console.WriteLine($"Hobby: {hobby}\n");&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prints your hobby, then adds a blank line after it (\n).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Output&lt;/strong&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%2Fhyub1gh69qgrn656cbq2.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%2Fhyub1gh69qgrn656cbq2.png" alt=" " width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Type the code to pratice use of **char literals **and click the play button to run the program.&lt;/strong&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%2Ffmi2q4v0vq8r4g3dusll.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%2Ffmi2q4v0vq8r4g3dusll.PNG" alt=" " width="800" height="305"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Explanation Step-by-Step&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Console.WriteLine("\n======= My Academic Grade ===============\n");&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Console.WriteLine() - prints a line to the screen.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The \n at the start and end means “new line” (a blank line).&lt;/li&gt;
&lt;li&gt;One before: leaves a space above the header.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Creating grade variables&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;char Mathgrade = 'A';&lt;br&gt;
Char Enggrade = 'B';&lt;br&gt;
char Chemgrade = 'C';&lt;br&gt;
char Phygrade = 'B';&lt;br&gt;
char Biograde = 'C';&lt;br&gt;
char Econgrade = 'A';&lt;br&gt;
char Comgrade = 'A';&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Each line declares a variable that stores a single character (a letter grade).&lt;/li&gt;
&lt;li&gt;char is short for character — it stores exactly one letter, number, or symbol.
You must use single quotes ' ' for characters (not double quotes " ").
&lt;strong&gt;Example:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;'A' - valid&lt;/p&gt;

&lt;p&gt;"A" - invalid (that’s a string, not a char)&lt;/p&gt;

&lt;p&gt;Here, each subject has its own variable:&lt;/p&gt;

&lt;p&gt;Variable    Subject Value&lt;br&gt;
Mathgrade   General Mathematics 'A'&lt;br&gt;
Enggrade    English Language    'B'&lt;br&gt;
Chemgrade   Chemistry           'C'&lt;br&gt;
Phygrade    Physics                 'B'&lt;br&gt;
Biograde    Biology                 'C'&lt;br&gt;
Econgrade   Economics           'A'&lt;br&gt;
Comgrade    Commerce            'A'&lt;/p&gt;

&lt;p&gt;Displaying each subject and its grade&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Console.WriteLine($"General Mathematics: {Mathgrade}");&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Uses string interpolation (the $ symbol) so you can mix text with variables.&lt;/li&gt;
&lt;li&gt;The {Mathgrade} is replaced by the value 'A'.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each following line does the same for other subjects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Console.WriteLine($"English Language: {Enggrade}");&lt;/li&gt;
&lt;li&gt;Console.WriteLine($"Chemistry: {Chemgrade}");&lt;/li&gt;
&lt;li&gt;Console.WriteLine($"Physics: {Phygrade}");&lt;/li&gt;
&lt;li&gt;Console.WriteLine($"Biology: {Biograde}");&lt;/li&gt;
&lt;li&gt;Console.WriteLine($"Economics: {Econgrade}");&lt;/li&gt;
&lt;li&gt;Console.WriteLine($"Commerce: {Comgrade}");&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%2Fzsngpxpzigw6oq1d8uy2.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%2Fzsngpxpzigw6oq1d8uy2.png" alt=" " width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Type the code to pratice use of **int literals&lt;/strong&gt; and click the play button to run the program.**&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%2Fmwvh6vazd5emmqlqzuk1.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%2Fmwvh6vazd5emmqlqzuk1.PNG" alt=" " width="800" height="236"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Explanation Step-by-Step&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Comment Line&lt;br&gt;
// --- Step 3: Use int literal ---&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Anything that starts with // is a comment — it’s ignored by the compiler.&lt;/li&gt;
&lt;li&gt;It’s used only for notes or explanations to make your code readable.&lt;/li&gt;
&lt;li&gt;This line tells you that this section is demonstrating how to use integer literals.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Integer Variables&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;int completedProjects = 5;&lt;br&gt;
int xpPoints = 100;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;int (short for integer) is a data type used to store whole numbers — no decimal points.&lt;/li&gt;
&lt;li&gt;Here you are creating two integer variables:&lt;/li&gt;
&lt;li&gt;completedProjects → stores the number 5&lt;/li&gt;
&lt;li&gt;xpPoints → stores the number 100&lt;/li&gt;
&lt;li&gt;“Literals” just means fixed values written directly into the code
(e.g. 5 and 100 are int literals because they are constant numbers).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Display Values&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Console.WriteLine($"Projects Completed: {completedProjects}");&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;Console.WriteLine($"XP Earned: {xpPoints}");&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Explanation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;$ → enables string interpolation (mixing text with variable values).&lt;/li&gt;
&lt;li&gt;{completedProjects} and {xpPoints} are replaced by the actual values stored in the variables.&lt;/li&gt;
&lt;li&gt;\n adds a blank line after printing, for cleaner spacing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Output&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%2Fgsg7lhl9eow7byuta2rb.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%2Fgsg7lhl9eow7byuta2rb.png" alt=" " width="800" height="489"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Type the code to pratice use of **decimal and float literals&lt;/strong&gt; and click the play button to run the program.**&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%2F0h3no6rrfesdxcah8vi3.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%2F0h3no6rrfesdxcah8vi3.PNG" alt=" " width="800" height="241"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Line-by-Line Explanation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Comment Line&lt;br&gt;
// --- Step 4: Use decimal and float literals ---&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This is a comment (ignored by the computer).&lt;/li&gt;
&lt;li&gt;It tells you this section shows how to use decimal and float values — numbers with decimal points.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Decimal Variable&lt;br&gt;
decimal successRate = 95.8m;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;decimal is a high-precision number type, used when you need very accurate decimal values (like money, percentages, or scientific data).&lt;/li&gt;
&lt;li&gt;The letter m at the end tells C# that 95.8 is a decimal literal.&lt;/li&gt;
&lt;li&gt;Without it, C# would think it’s a double and show an error.&lt;/li&gt;
&lt;li&gt;Think of decimal as a super accurate number type.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Float Variable&lt;br&gt;
float weeklyProgress = 0.85F;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;float is another data type for decimal numbers - less precise but uses less memory.&lt;/li&gt;
&lt;li&gt;The letter F tells C# that this is a float literal.&lt;/li&gt;
&lt;li&gt;The value 0.85 represents 85% progress (written in decimal form).&lt;/li&gt;
&lt;li&gt;Floats are useful when you don’t need extreme accuracy - like averages or progress values.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Displaying the Decimal Value&lt;br&gt;
Console.WriteLine($"Success Rate: {successRate}%");&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;$ allows you to combine text with the variable value.&lt;/li&gt;
&lt;li&gt;{successRate} is replaced by 95.8.&lt;/li&gt;
&lt;li&gt;It prints:&lt;/li&gt;
&lt;li&gt;Success Rate: 95.8%&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Displaying the Float Value (with a Calculation)&lt;br&gt;
Console.WriteLine($"Weekly Progress: {weeklyProgress}%");&lt;/p&gt;

&lt;p&gt;Explanation&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;$ - String Interpolation&lt;/li&gt;
&lt;li&gt;The $ before the string means you’re using string interpolation.&lt;/li&gt;
&lt;li&gt;It allows you to insert variable values directly into a string.&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%2Fijaoa4c0y1v5uph9iqko.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%2Fijaoa4c0y1v5uph9iqko.png" alt=" " width="800" height="489"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Type the code to pratice use of **decimal and float literals&lt;/strong&gt; and click the play button to run the program.**&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%2Fr95z99kh53gp8pqts02b.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%2Fr95z99kh53gp8pqts02b.png" alt=" " width="800" height="489"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Line-by-line Explanation&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;bool taskCompleted = true;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;bool is short for Boolean, a data type that holds only two possible values:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;true or false.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here, taskCompleted is a variable that stores whether your exercise is finished or not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;bool taskCompleted = true;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The task is done (true).&lt;/li&gt;
&lt;li&gt;If it were false, that would mean the task isn’t done.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Console.WriteLine($"Exercise Completed: {taskCompleted}");&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This line prints a message to the console.&lt;/li&gt;
&lt;li&gt;The $ allows string interpolation, which lets you embed variables inside strings using {}.&lt;/li&gt;
&lt;li&gt;{taskCompleted} will be replaced by the value stored in taskCompleted (in this case, true).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Console.WriteLine("\n=====================================");&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The \n means new line — it moves the cursor to the next line before printing the equals signs.&lt;/li&gt;
&lt;li&gt;It prints a decorative separator line to make your output look nice.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Console.WriteLine(" Thank you for viewing my profile!");&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This prints a simple closing message for your program.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Console.WriteLine("=====================================");&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Prints another separator line to complete the section visually.&lt;/p&gt;

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

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

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This project gave me hands on experience with one of the most important building blocks of C# which is data types. Through creating and displaying literal values, I learned how precision, syntax, and data representation affect program output. It was a great step in developing problem solving skills, logical thinking, and code structure understanding. The Personal Info &amp;amp; Stats Display App marks the beginning of my C# learning journey, setting the foundation for more complex applications such as data driven programs and user interactive systems in the future.&lt;/p&gt;

</description>
      <category>csharp</category>
      <category>programming</category>
      <category>webdev</category>
      <category>c</category>
    </item>
    <item>
      <title>Managing and Hosting My Resume on GitHub Using Git Bash</title>
      <dc:creator>SUBAIR NURUDEEN ADEWALE</dc:creator>
      <pubDate>Fri, 03 Oct 2025 09:14:22 +0000</pubDate>
      <link>https://dev.to/subair09/managing-and-hosting-my-resume-on-github-using-git-bash-34pd</link>
      <guid>https://dev.to/subair09/managing-and-hosting-my-resume-on-github-using-git-bash-34pd</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In today’s tech-driven world, showcasing both technical skills and personal branding is essential. This project demonstrates how I used Git Bash and GitHub to version control and publish my professional resume. By doing so, I not only practiced core Git commands but also created a transparent, accessible, and always-updated space for recruiters and collaborators to view my career journey.&lt;/p&gt;

&lt;p&gt;This project focuses on practical usage of Git for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Initializing a local repository.&lt;/li&gt;
&lt;li&gt;Adding and committing files.&lt;/li&gt;
&lt;li&gt;Connecting to a remote GitHub repository.&lt;/li&gt;
&lt;li&gt;Pushing updates to maintain the latest version of my resume.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before starting, you need to have Git installed on your system. Follow these steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Download Git: Visit the official Git website at &lt;a href="https://git-scm.com" rel="noopener noreferrer"&gt;https://git-scm.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Install Git: Download the version for your operating system (Windows, macOS, or Linux) and follow the installation prompts.&lt;/li&gt;
&lt;li&gt;On Windows, you will also get Git Bash, a command-line tool to run Git commands.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Step 1: Sign in to your Github account to Create a New Repository.&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%2F4ok9q274qb7lorz1hhaq.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%2F4ok9q274qb7lorz1hhaq.png" alt=" " width="800" height="630"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click the + icon in the top-right corner and select New Repository.&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%2Fh4ae20ax8xxv07f2sdk0.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%2Fh4ae20ax8xxv07f2sdk0.PNG" alt=" " width="800" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Give your repository a name (e.g., Resume).&lt;/li&gt;
&lt;li&gt;Choose whether you want it to be Public or Private.&lt;/li&gt;
&lt;li&gt;Click Create Repository.&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%2Fa0mfxeca2hxo1eh1a9n6.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%2Fa0mfxeca2hxo1eh1a9n6.PNG" alt=" " width="800" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Configure Git environment&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configure your Git environment by logging into GitHub from your Git terminal.&lt;/li&gt;
&lt;li&gt;Open Git Bash on your computer.&lt;/li&gt;
&lt;li&gt;Type the following command to set your username:
-** git config --global user.name "YourGitHubUsername"**&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;&lt;strong&gt;git config --global user.name "Subair-09"&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Type the following command to set the email associated with your GitHub account:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;git config --global user.email "&lt;a href="mailto:youremail@example.com"&gt;youremail@example.com&lt;/a&gt;"&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;git config --global user.email "&lt;a href="mailto:nuddywale@gmail.com"&gt;nuddywale@gmail.com&lt;/a&gt;"&lt;/strong&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%2F1eco4nmpania4qaykule.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%2F1eco4nmpania4qaykule.PNG" alt=" " width="800" height="399"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;shows all the Git configuration settings currently active on your system using the command 
&lt;strong&gt;git config --list&lt;/strong&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%2F14jm2hzqbxstsvpd7le9.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%2F14jm2hzqbxstsvpd7le9.PNG" alt=" " width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Create a Directory in Git Bash and Name It After My GitHub Repository&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Type this command to create a directory in Git bash and name it your repository name you created in GitHub&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;mkdir Resume&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Type this command to CD(Open) into your directory&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;cd Resume&lt;/strong&gt;&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%2Fmsfs5bq8rau9t2pw0v2c.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%2Fmsfs5bq8rau9t2pw0v2c.PNG" alt=" " width="800" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Type this command to initializes a new Git repository in your current directory and Creates a hidden .git folder inside your project directory.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;-git init&lt;/strong&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%2Fxojw2it3e4un1a7aeofd.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%2Fxojw2it3e4un1a7aeofd.PNG" alt=" " width="800" height="133"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Git init&lt;/strong&gt; will create a new Git repository folder in the current directory on your local host.&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%2Fl637d2matzubshm8z8z5.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%2Fl637d2matzubshm8z8z5.PNG" alt=" " width="800" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Create a File Inside the Directory&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To create a new file in your directory, use the touch command followed by the file name and extension:&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;touch filename.extension&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;touch resume.html&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This will create an empty file named index.html inside your current directory.&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%2F53nig43q5z68yd9y95vp.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%2F53nig43q5z68yd9y95vp.PNG" alt=" " width="800" height="395"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Step 3.1 Edit Your File Using the vi Text Editor&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open the file in the vi editor by typing:&lt;/li&gt;
&lt;li&gt;vi resume.html&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%2F1aa3i2wus589vibwo2il.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%2F1aa3i2wus589vibwo2il.PNG" alt=" " width="800" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Press the i key to enter insert mode, which allows you to type and edit text in the file.&lt;/li&gt;
&lt;li&gt;Add your HTML code of your resume to the resume.html file.&lt;/li&gt;
&lt;li&gt;To save and exit:&lt;/li&gt;
&lt;li&gt;Press the Esc key to leave insert mode.&lt;/li&gt;
&lt;li&gt;Type :wq and press Enter.&lt;/li&gt;
&lt;li&gt;w = write (save changes)&lt;/li&gt;
&lt;li&gt;q = quit (exit the editor)&lt;/li&gt;
&lt;li&gt;Your changes will now be saved to resume.html&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%2Fiqx7ac2wdybnej3z4fsl.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%2Fiqx7ac2wdybnej3z4fsl.PNG" alt=" " width="800" height="515"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Step 4: Connect Local Repository to GitHub *&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click on the &lt;strong&gt;Code&lt;/strong&gt; button in Github and copy the HTTPs link.&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%2Fuw36bn177ao1xr0lmcal.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%2Fuw36bn177ao1xr0lmcal.PNG" alt=" " width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4.1 Connect the local repository to Github using the command&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;git remote add origin &lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;git remote add origin &lt;a href="https://github.com/Subair-09/Resume.git" rel="noopener noreferrer"&gt;https://github.com/Subair-09/Resume.git&lt;/a&gt;&lt;/strong&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%2Fw8jsqys5zlqazbgxi7wi.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%2Fw8jsqys5zlqazbgxi7wi.PNG" alt=" " width="800" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4.2: Add Your File to Git&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Type the following command to stage your resume.html file so it can be tracked and uploaded to GitHub:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;git add resume.html&lt;/strong&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%2Fns3rfldbii800ngp34z2.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%2Fns3rfldbii800ngp34z2.PNG" alt=" " width="800" height="202"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4.3 : Check the Status&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run this command to view the current status of your repository and confirm the changes you’ve staged:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;git status&lt;/strong&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%2Fx72s76du4z03bmpl0vhn.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%2Fx72s76du4z03bmpl0vhn.PNG" alt=" " width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5: Committing Changes to My Project&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Before you can push to GitHub, you need to commit your changes.&lt;/li&gt;
&lt;li&gt;A commit is like saving a snapshot of your project history. Always add a message to describe what you’ve done.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;git commit -m "Added my professional resume file"&lt;/strong&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%2Fqlkatju05javvckl5snd.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%2Fqlkatju05javvckl5snd.PNG" alt=" " width="800" height="332"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Step 6: Pushing My Code to GitHub &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After committing, the next step is to push your code to GitHub so it’s available online.&lt;/li&gt;
&lt;li&gt;This command uploads your local commits to the master branch of your GitHub repository.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;git push origin master&lt;/strong&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%2Fjgvzamrbi3arxhq632be.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%2Fjgvzamrbi3arxhq632be.PNG" alt=" " width="800" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Step 7: resume.html Successfully Pushed to GitHub &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The resume.html file has been successfully pushed and is now available in my GitHub repository. You can view it directly on the GitHub website.&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%2Fm0sd4hxaoevbvmncixx2.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%2Fm0sd4hxaoevbvmncixx2.PNG" alt=" " width="800" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Step 8: Hosting My Resume on GitHub Pages &lt;/p&gt;

&lt;p&gt;After pushing my project to GitHub, I noticed the “&lt;strong&gt;Compare &amp;amp; Pull Request&lt;/strong&gt;” option, which usually appears when new commits are pushed. Since my goal was to publish the project as a live site, I moved to GitHub Pages settings.&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%2Fvd23nvej3vcjwc5vfs41.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%2Fvd23nvej3vcjwc5vfs41.PNG" alt=" " width="800" height="396"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I navigated to Settings &amp;gt; Pages.&lt;/li&gt;
&lt;li&gt;Under Build and Deployment, I changed the branch from main to master and clicked Save.&lt;/li&gt;
&lt;li&gt;GitHub automatically generated a deployment URL.&lt;/li&gt;
&lt;li&gt;I refreshed the page, and a “Visit site” link appeared.&lt;/li&gt;
&lt;li&gt;Clicking the link opened my project, and my resume.html file was successfully displayed online.&lt;/li&gt;
&lt;li&gt;Now my resume is live and accessible via a public GitHub Pages URL.&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%2Fy7tc8vh2xufpi3q0v4p5.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%2Fy7tc8vh2xufpi3q0v4p5.PNG" alt=" " width="800" height="453"&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%2F78jpvf6unq6f7o8es7jn.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%2F78jpvf6unq6f7o8es7jn.PNG" alt=" " width="800" height="391"&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%2Fjpnj76sqekgclrol5xp6.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%2Fjpnj76sqekgclrol5xp6.PNG" alt=" " width="800" height="538"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This project successfully demonstrates how Git and GitHub can be used not only as version control tools but also as platforms for personal branding and professional visibility. By walking through the process of initializing a local repository, committing changes, pushing updates, and deploying through GitHub Pages, I was able to transform my resume from a static document into a live, web-accessible portfolio.&lt;/p&gt;

&lt;p&gt;Through this workflow, I gained practical experience in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mastering essential Git commands (git init, git add, git commit, git push).&lt;/li&gt;
&lt;li&gt;Understanding the importance of version control in tracking and managing project changes.&lt;/li&gt;
&lt;li&gt;Leveraging GitHub as a hosting platform to create a publicly available professional asset.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The end result is a dynamic, always-up-to-date resume site that recruiters, collaborators, and peers can access with ease. Beyond showcasing technical ability, this project highlights the value of combining technical competence with personal branding, ensuring that my professional journey is both transparent and accessible in today’s digital world.&lt;/p&gt;

</description>
      <category>bash</category>
      <category>linux</category>
      <category>git</category>
      <category>githubactions</category>
    </item>
    <item>
      <title>Mastering Linux: User &amp; Permission Management with a Mock Company Project</title>
      <dc:creator>SUBAIR NURUDEEN ADEWALE</dc:creator>
      <pubDate>Sat, 27 Sep 2025 10:02:33 +0000</pubDate>
      <link>https://dev.to/subair09/mastering-linux-user-permission-management-with-a-mock-company-project-52d5</link>
      <guid>https://dev.to/subair09/mastering-linux-user-permission-management-with-a-mock-company-project-52d5</guid>
      <description>&lt;p&gt;Introduction&lt;/p&gt;

&lt;p&gt;In Linux system administration, managing users, groups, and permissions is one of the most critical skills. It ensures that only the right people have access to sensitive files, while promoting collaboration in shared environments. In this project, we simulate a real-world scenario by creating multiple users, assigning them to groups, and managing access to shared directories and project files. This hands-on approach gives you practical experience with essential commands like adduser, groupadd, usermod, chmod, chown, and id.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tasks to be Completed&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create Groups&lt;br&gt;
Set up 2 groups (e.g., devs and staff) using groupadd.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Create Users&lt;br&gt;
Add 5 new users with adduser or useradd.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Assign Users to Groups&lt;br&gt;
Use usermod -aG to assign users to the correct group.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set Up a Shared Project Directory&lt;br&gt;
Create a directory (/home/company_projects) and configure it with the SGID bit so all files inherit the group ownership.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Manage Permissions&lt;br&gt;
Use chmod to enforce rules (e.g., only group members can read/write, others are denied).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Test Group Collaboration&lt;br&gt;
Have one user (e.g., alice) create a file and another group member (e.g., bob) edit it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Confirm that non-members (e.g., carol) cannot access the directory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Change File Ownership&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Practice with chown and chgrp to assign ownership of files to specific users or groups.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Verify and Troubleshoot&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use commands like id, groups, ls -l, and stat to confirm changes.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Most commands require root privileges. Prefix with sudo when needed, or run as root:&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;sudo -i&lt;/strong&gt; or &lt;strong&gt;sudo su -&lt;/strong&gt;  if you want a root shell&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Create two groups&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Choose meaningful group names. Example: devs and staff.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- sudo groupadd devs&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;- sudo groupadd staff&lt;/strong&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%2F6zaeyimeh2lww2fqw3vs.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%2F6zaeyimeh2lww2fqw3vs.PNG" alt=" " width="800" height="190"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verify groups exist:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- getent group devs&lt;/strong&gt;&lt;br&gt;
&lt;strong&gt;- getent group staff&lt;/strong&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%2Fvj6h58c4axb4z2f3unes.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%2Fvj6h58c4axb4z2f3unes.PNG" alt=" " width="800" height="200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2 : Create five users&lt;/strong&gt;&lt;br&gt;
Create five user using the command &lt;strong&gt;adduser&lt;/strong&gt;, adduser will prompt for a password and optional info.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sudo adduser alice&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%2Funwbdr4l557ggfv6r6g3.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%2Funwbdr4l557ggfv6r6g3.PNG" alt=" " width="800" height="377"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sudo adduser bob&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%2Fplmicux3bj8fnch0lc5s.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%2Fplmicux3bj8fnch0lc5s.PNG" alt=" " width="800" height="378"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sudo adduser carol&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%2Flv5fytvxga147gjvra02.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%2Flv5fytvxga147gjvra02.PNG" alt=" " width="800" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sudo adduser dave&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%2Fjeat31czwnnkphthrhmi.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%2Fjeat31czwnnkphthrhmi.PNG" alt=" " width="800" height="363"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sudo adduser eve&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%2Fwzp9ukuon0qmee55c6oo.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%2Fwzp9ukuon0qmee55c6oo.PNG" alt=" " width="800" height="412"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;logout of the current user to see all new users added&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%2Fuuc4z7ee1i6ow2je2v8m.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%2Fuuc4z7ee1i6ow2je2v8m.PNG" alt=" " width="800" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3 :Assign users to groups&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Decide group membership. Example mapping:&lt;/li&gt;
&lt;li&gt;devs: alice, bob&lt;/li&gt;
&lt;li&gt;staff: carol, dave, eve&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Add users to groups (use &lt;strong&gt;-aG&lt;/strong&gt; user to each group)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sudo usermod -aG devs alice&lt;/li&gt;
&lt;li&gt;sudo usermod -aG devs bob&lt;/li&gt;
&lt;li&gt;sudo usermod -aG staff carol&lt;/li&gt;
&lt;li&gt;sudo usermod -aG staff dave&lt;/li&gt;
&lt;li&gt;sudo usermod -aG staff eve&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%2Fmp0koeq6gjnwpz5ojwyl.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%2Fmp0koeq6gjnwpz5ojwyl.PNG" alt=" " width="800" height="240"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Verify membership:&lt;/strong&gt;&lt;br&gt;
verify membership by using the command &lt;strong&gt;sudo getent group devs and sudo getent group staff&lt;/strong&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%2F29dvqiixwq6532tl41uf.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%2F29dvqiixwq6532tl41uf.PNG" alt=" " width="800" height="286"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4 : Create a shared project directory&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create a directory that group members can read/write. We'll create a company_projects folder in the home directory:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- mkdir -p /home/company_projects&lt;/strong&gt; (create a parent directory in the home directory)   &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;sudo chmod g+s /home/company_projects 
The g+s (setgid on directory) is what makes a shared project folder behave like a real team workspace.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;sudo chown root:devs /home/company_projects&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;chown → change owner of a file or directory.&lt;/li&gt;
&lt;li&gt;root:devs &lt;/li&gt;
&lt;li&gt;root = new owner of the directory&lt;/li&gt;
&lt;li&gt;devs = new group of the directory&lt;/li&gt;
&lt;li&gt;/home/company_projects → the target directory.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;sudo chmod u+rwx /home/company_projects&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;chmod → change file/directory permissions.&lt;/li&gt;
&lt;li&gt;u → refers to the owner of the directory.&lt;/li&gt;
&lt;li&gt;+rwx → add read (r), write (w), and execute (x) permissions.&lt;/li&gt;
&lt;li&gt;Effect: The owner of ~/company_projects can list contents, create/delete files, and enter the directory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;sudo chmod g+rwx /home/company_projects&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;chmod: change permissions.&lt;/li&gt;
&lt;li&gt;g: refers to the group of the file/directory (in your case, the group might be devs because of sudo chown root:devs).&lt;/li&gt;
&lt;li&gt;+rwx: add three permissions:&lt;/li&gt;
&lt;li&gt;r (read): group members can list the files inside.&lt;/li&gt;
&lt;li&gt;w (write): group members can create new files, delete files, and make changes.&lt;/li&gt;
&lt;li&gt;x (execute): group members can enter the directory and access its contents.&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%2Fp69acunjmonp4joptdvg.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%2Fp69acunjmonp4joptdvg.PNG" alt=" " width="800" height="271"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5 : Test the shared directory behavior&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;switched to the alice account and tried to enter /home/company_projects&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;su - alice&lt;/li&gt;
&lt;li&gt;cd /home/company_projects&lt;/li&gt;
&lt;li&gt;touch file_from_alice.txt&lt;/li&gt;
&lt;li&gt;ls&lt;/li&gt;
&lt;li&gt;shows: file_from_alice.txt&lt;/li&gt;
&lt;li&gt;ls -l&lt;/li&gt;
&lt;li&gt;shows a line similar to:&lt;/li&gt;
&lt;li&gt;-rw-rw-r-- 1 alice devs 0 Sep 27 08:40 file_from_alice.txt&lt;/li&gt;
&lt;li&gt;What this shows:&lt;/li&gt;
&lt;li&gt;The file owner is alice.&lt;/li&gt;
&lt;li&gt;The file group is devs — it inherited the directory group (devs) because the parent directory had the setgid bit.&lt;/li&gt;
&lt;li&gt;File permissions are -rw-rw-r-- (owner read/write, group read/write, others read). &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%2Fo0xh100c9e32jlkppu1d.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%2Fo0xh100c9e32jlkppu1d.PNG" alt=" " width="800" height="155"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5.1 As another devs member (bob), confirm you can edit/delete:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;su - bob&lt;/li&gt;
&lt;li&gt;cd ~/company_projects&lt;/li&gt;
&lt;li&gt;echo "hello" &amp;gt;&amp;gt; testfile_from_alice.txt&lt;/li&gt;
&lt;li&gt;cat testfile_from_alice.txt  allowed because group has write permission&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%2F3176eoc13icrnn1npkxo.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%2F3176eoc13icrnn1npkxo.PNG" alt=" " width="800" height="261"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5.2 A non-member (e.g., carol, in staff) should be denied because they are not a member of the group devs, they belong to the staff group:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;su - carol&lt;br&gt;
cd /home/company_projects&lt;br&gt;
this should fail with "Permission denied"&lt;br&gt;
touch should_fail.txt&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%2Fs2nem1zhpdn95aast4le.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%2Fs2nem1zhpdn95aast4le.PNG" alt=" " width="800" height="230"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6 : Manage file ownership and group on existing files&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Set owner and group for a file or directory using the command &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;sudo chown alice:devs /home/company_projects/somefile.txt&lt;/strong&gt;&lt;br&gt;
The owner of the directory is alice and now belong to the devs team.&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%2F4h4ag5o42ad6dfuye44b.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%2F4h4ag5o42ad6dfuye44b.PNG" alt=" " width="800" height="200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6.1 change only group&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;sudo chgrp staff ~/company_projects/some_other_file.txt&lt;/p&gt;

&lt;p&gt;Before the command&lt;/p&gt;

&lt;p&gt;The directory /home/company_projects had:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Owner: alice&lt;/li&gt;
&lt;li&gt;Group: devs&lt;/li&gt;
&lt;li&gt;Shown by:&lt;/li&gt;
&lt;li&gt;drwxrwsr-x 2 alice devs 4096 Sep 27 09:15 /home/company_projects&lt;/li&gt;
&lt;li&gt;Step: sudo chgrp staff /home/company_projects&lt;/li&gt;
&lt;li&gt;chgrp = change group ownership&lt;/li&gt;
&lt;li&gt;staff = new group&lt;/li&gt;
&lt;li&gt;So, this command changed the group of the directory from devs ➝ staff.&lt;/li&gt;
&lt;li&gt;Now the directory looks like:&lt;/li&gt;
&lt;li&gt;drwxrwsr-x 2 alice staff 4096 Sep 27 09:15 /home/company_projects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Meaning:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Owner is still alice&lt;/li&gt;
&lt;li&gt;Group is now staff&lt;/li&gt;
&lt;li&gt;Next: su - carol&lt;/li&gt;
&lt;li&gt;switched to user carol.&lt;/li&gt;
&lt;li&gt;Carol goes into /home/company_projects and creates a file:&lt;/li&gt;
&lt;li&gt;touch man.txt&lt;/li&gt;
&lt;li&gt;Now when you list:&lt;/li&gt;
&lt;li&gt;-rw-rw-r-- 1 carol staff 0 Sep 27 09:53 man.txt&lt;/li&gt;
&lt;li&gt;-rw-rw-r-- 1 alice devs 16 Sep 27 09:23 testfile_from_alice.txt&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why this happened:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;man.txt&lt;/li&gt;
&lt;li&gt;Owner = carol (because she created it).&lt;/li&gt;
&lt;li&gt;Group = staff (because the directory /home/company_projects now belongs to group staff AND it has the setgid bit s set → that s in drwxrwsr-x).&lt;/li&gt;
&lt;li&gt;The setgid bit ensures new files created inside inherit the directory’s group.&lt;/li&gt;
&lt;li&gt;testfile_from_alice.txt&lt;/li&gt;
&lt;li&gt;This was created earlier by Alice when the group was still devs.&lt;/li&gt;
&lt;li&gt;So it keeps alice:devs.&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%2Fy6ygu30t1g2okmmrlu7h.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%2Fy6ygu30t1g2okmmrlu7h.PNG" alt=" " width="800" height="334"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this project, we explored how Linux handles file ownership, groups, and permissions through practical examples. By using commands such as chown, chgrp, and chmod, we demonstrated how to assign files and directories to specific users and groups, as well as how to control access levels.&lt;br&gt;
A key highlight was the use of the setgid (s) permission on directories, which ensures that newly created files inherit the group ownership of the parent directory. This feature makes collaboration easier in shared project folders, as users automatically create files that belong to the intended group.&lt;br&gt;
From the exercises, we saw how ownership transitions (e.g., alice:devs ➝ alice:staff) affect who can read, write, or execute within shared directories, and how different users (alice, carol, etc.) interact with files depending on group membership.&lt;/p&gt;

&lt;p&gt;Overall, this project demonstrates the importance of carefully managing permissions in multi-user environments. By applying these principles, system administrators can create secure, collaborative workspaces while maintaining control and accountability over files and directories.&lt;/p&gt;

</description>
      <category>bash</category>
      <category>ubuntu</category>
      <category>docker</category>
      <category>devops</category>
    </item>
    <item>
      <title>Mastering Linux: File &amp; Directory Management with a Mock Company Project</title>
      <dc:creator>SUBAIR NURUDEEN ADEWALE</dc:creator>
      <pubDate>Mon, 22 Sep 2025 11:53:09 +0000</pubDate>
      <link>https://dev.to/subair09/mastering-linux-file-directory-management-with-a-mock-company-project-499l</link>
      <guid>https://dev.to/subair09/mastering-linux-file-directory-management-with-a-mock-company-project-499l</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Linux is one of the most powerful and widely used operating systems in the world. From running servers and cloud platforms to powering embedded systems and supercomputers, its flexibility makes it a must-learn skill for anyone in technology. At the heart of Linux usage is the ability to effectively manage files and directories. Mastering this fundamental skill not only boosts efficiency but also lays the groundwork for advanced system administration, DevOps, and automation.&lt;/p&gt;

&lt;p&gt;In this project, “File &amp;amp; Directory Management for a Mock Company using Linux”, we simulate a real-world environment by creating and managing a company’s directory structure. This hands-on exercise helps learners understand how to navigate the Linux filesystem, manipulate files, and organize data effectively, using both absolute and relative paths, along with essential commands.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tasks to Cover in the Project&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here are the step-by-step applied tasks you will complete:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Set Up the Company Structure&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create directories for different departments (HR, Finance, Dev, Marketing).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Create and Manage Files&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add employee records, policy documents, budgets, and project files.&lt;/li&gt;
&lt;li&gt;Use commands like &lt;strong&gt;touch, ls, cat.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Copy, Move, and Rename Files&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Share policies across departments.&lt;/li&gt;
&lt;li&gt;Move misplaced project files.&lt;/li&gt;
&lt;li&gt;Rename files correctly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Search and Find Files&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use find to locate files.&lt;/li&gt;
&lt;li&gt;Search content inside files with grep.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Compress and Backup Data&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Archive the company directory with tar and gzip.&lt;/li&gt;
&lt;li&gt;Extract the archive to test backup recovery.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Check Storage Usage&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Monitor directory size with du.&lt;/li&gt;
&lt;li&gt;Check disk space with df.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Work with Paths&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Practice using absolute paths (/home/user/company/...).&lt;/li&gt;
&lt;li&gt;Practice using relative paths (../finance/budget.txt).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 1 Create the Company Folder Structure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We will first create a parent directory named company, and inside this directory, we will create four subdirectories representing different departments of the organization:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Commands Used and Their Meanings&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;mkdir -p ~/company&lt;/li&gt;
&lt;li&gt;mkdir: Make Directory (creates a new folder)&lt;/li&gt;
&lt;li&gt;-p: Parents flag (creates parent directories if they don't exist)&lt;/li&gt;
&lt;li&gt;~/company: Path to the new directory (in the user's home folder)&lt;/li&gt;
&lt;li&gt;Meaning: Create a directory called "company" in the home directory&lt;/li&gt;
&lt;li&gt;mkdir -p ~/company/hr (and similar commands)&lt;/li&gt;
&lt;li&gt;Meaning: Create subdirectories (hr, finance, marketing, dev) inside the company directory&lt;/li&gt;
&lt;li&gt;ls&lt;/li&gt;
&lt;li&gt;Meaning: List contents of the current directory&lt;/li&gt;
&lt;li&gt;cd company&lt;/li&gt;
&lt;li&gt;cd: Change Directory&lt;/li&gt;
&lt;li&gt;Meaning: Move into the company directory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;1.1 Create the main company directory:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;- mkdir -p ~/company&lt;/strong&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%2Fhwp5brw7lfcul6z6hspe.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%2Fhwp5brw7lfcul6z6hspe.PNG" alt=" " width="800" height="256"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.2 Create department subdirectories:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;mkdir -p ~/company/hr&lt;br&gt;
mkdir -p ~/company/finance&lt;br&gt;
mkdir -p ~/company/marketing&lt;br&gt;
mkdir -p ~/company/dev&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%2F7goqq02yd6k0qbgicdzz.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%2F7goqq02yd6k0qbgicdzz.PNG" alt=" " width="800" height="245"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.3 Verify the directory structure:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ls&lt;br&gt;
This shows all files and directories in your current location, including the new "company" directory.&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%2F4h6379cxifwts2kfud0n.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%2F4h6379cxifwts2kfud0n.PNG" alt=" " width="800" height="222"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.4 Navigate into the company directory:&lt;/strong&gt;&lt;br&gt;
Navigate into the parent directory (company) using the cd command.&lt;br&gt;
*&lt;em&gt;cd *&lt;/em&gt; company&lt;/p&gt;

&lt;p&gt;ls&lt;br&gt;
This confirms that all four department directories (dev, finance, hr, marketing) were created successfully.&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%2Fdefj1nkl74yb6esupn32.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%2Fdefj1nkl74yb6esupn32.PNG" alt=" " width="800" height="316"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Create Some Sample Files&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;touch → creates empty files.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Here we simulate real company documents: HR gets employee records and policies, Finance gets budgets, Dev has project files, and Marketing has strategies.&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%2Fh82qxoqdf7trbmzddq5m.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%2Fh82qxoqdf7trbmzddq5m.PNG" alt=" " width="800" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can confirm they were created with:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ls ~/company/hr&lt;br&gt;
ls ~/company/finance&lt;br&gt;
ls ~/company/dev&lt;br&gt;
ls ~/company/marketing&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%2F6bb7wga0dz4un9dzt5pe.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%2F6bb7wga0dz4un9dzt5pe.PNG" alt=" " width="800" height="325"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Copy &amp;amp; Rename Files&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Copy HR policies to Marketing:&lt;/p&gt;

&lt;p&gt;cp copy files from one directory to another directory&lt;br&gt;
ls comfirm the policies.txt file is copied to marketing directory&lt;/p&gt;

&lt;p&gt;cp ~/company/hr/policies.txt ~/company/marketing/&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%2Fytgtppaliclarjlln2ob.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%2Fytgtppaliclarjlln2ob.PNG" alt=" " width="800" height="250"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;mv → use for renaming files.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The file in the dev folder (projectA.txt) is spelt wrongly, rename the file to project2025.txt&lt;/li&gt;
&lt;li&gt;cd into the dev directory&lt;/li&gt;
&lt;li&gt;ls to list the files in the directory&lt;/li&gt;
&lt;li&gt;use mv to rename the directory from projectA.txt to project2025.txt&lt;/li&gt;
&lt;li&gt;use ls to verify your change.&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%2Fcy18b5hma6mprwnenbdf.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%2Fcy18b5hma6mprwnenbdf.PNG" alt=" " width="800" height="299"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Search for Files&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;find → locates files and directories matching a pattern.&lt;/li&gt;
&lt;li&gt;grep -r → searches inside files for specific words recursively.&lt;/li&gt;
&lt;li&gt;This is useful for quickly tracking down documents.&lt;/li&gt;
&lt;li&gt;find ~/company -name "*.txt" locates files and directories that has the  .txt files.&lt;/li&gt;
&lt;li&gt;find ~/company -name "*.txt" locates files and directories that has the  .png files.&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%2Fiq5sfy4fpbhz9uijn325.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%2Fiq5sfy4fpbhz9uijn325.PNG" alt=" " width="800" height="304"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Search for the word “policy” inside files:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;grep -r "policies" ~/company&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%2Fem8gz215q3obp8qraz3w.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%2Fem8gz215q3obp8qraz3w.PNG" alt=" " width="800" height="282"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Step 5: Organize with Compression&lt;/p&gt;

&lt;p&gt;At some point, every company needs to back up its files to protect against accidental deletion, corruption, or system failure. In Linux, one of the most common tools for this is tar (short for tape archive). It allows you to bundle multiple files and directories into a single archive, and with the right options, compress it to save space.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5.1 Compress the company folder&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Command:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;tar -czvf company_backup.tar.gz ~/company&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;tar → archives multiple files and directories into one.&lt;/li&gt;
&lt;li&gt;-c → create a new archive.&lt;/li&gt;
&lt;li&gt;-z → compress the archive using gzip (makes it smaller in size).&lt;/li&gt;
&lt;li&gt;-v → verbose mode, shows the progress in the terminal as files are being archived.&lt;/li&gt;
&lt;li&gt;-f → specifies the filename of the archive (company_backup.tar.gz).&lt;/li&gt;
&lt;li&gt;~/company → the folder you want to back up.&lt;/li&gt;
&lt;li&gt;This command creates a compressed backup file named:&lt;/li&gt;
&lt;li&gt;company_backup.tar.gz&lt;/li&gt;
&lt;li&gt;in your current working directory.
&lt;strong&gt;Extract the backup to test&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Command:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;tar -xzvf company_backup.tar.gz -C ~/&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;-x → extract files from an archive.&lt;/li&gt;
&lt;li&gt;-z → tells tar the archive is compressed with gzip.&lt;/li&gt;
&lt;li&gt;-v → verbose mode, shows files being extracted.&lt;/li&gt;
&lt;li&gt;-f → specifies the filename of the archive.&lt;/li&gt;
&lt;li&gt;-C ~/ → tells tar where to extract the files (in this case, your home directory).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This simulates restoring the backup. After extraction, you should see the company folder again in your home directory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5.2 Compress the company folder:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;tar -czvf company_backup.tar.gz ~/company&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%2Fbkc0stq2h34cx7omj94q.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%2Fbkc0stq2h34cx7omj94q.PNG" alt=" " width="800" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5.3 Extract it to test:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;tar -xzvf company_backup.tar.gz -C ~/&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5.4 View whats inside the compressed folder&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check what’s inside your archive before extracting:&lt;/li&gt;
&lt;li&gt;This lists all files and directories stored in the archive.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;tar -tzvf company_backup.tar.gz&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%2Fgh593lg3p382sdzw9wd5.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%2Fgh593lg3p382sdzw9wd5.PNG" alt=" " width="800" height="503"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5.5 Extract into a new folder&lt;/strong&gt;&lt;br&gt;
Create a new folder &lt;strong&gt;(Restorefiles)&lt;/strong&gt; in the &lt;strong&gt;company&lt;/strong&gt; directory which is the parent directory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5.5.1 Preparation Setup&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;mkdir -p ~/company/Restorefiles&lt;/strong&gt;&lt;br&gt;
cd company&lt;br&gt;
ls&lt;br&gt;
cd ..&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Created a safe restoration area (Restorefiles) to extract backup files&lt;/li&gt;
&lt;li&gt;Verified your existing company structure before restoration&lt;/li&gt;
&lt;li&gt;Positioned yourself in the home directory ready for extraction&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5.1.2: Backup Extraction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;tar xzvf company_backup.tar.gz -C ~/company/Restorefiles&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Extracted a compressed backup archive (company_backup.tar.gz)&lt;/li&gt;
&lt;li&gt;Used safe extraction to an isolated location instead of overwriting original files&lt;/li&gt;
&lt;li&gt;Preserved the complete directory structure and file permissions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5.1.3 Verification &amp;amp; Inspection&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;cd ~/company/Restorefiles&lt;br&gt;
ls&lt;br&gt;
cd home&lt;br&gt;
ls&lt;br&gt;
cd vboxuser&lt;br&gt;
ls&lt;br&gt;
cd company&lt;br&gt;
ls&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Navigated through the extracted backup structure to verify contents&lt;/li&gt;
&lt;li&gt;Confirmed all data was intact: departments, files, and hierarchy&lt;/li&gt;
&lt;li&gt;Checked that the backup matched your expected company structure&lt;/li&gt;
&lt;li&gt;What Your Backup Contained&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%2Fbomw2i9f06ltd13qgrat.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%2Fbomw2i9f06ltd13qgrat.PNG" alt=" " width="800" height="510"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6: Check Storage &amp;amp; File Sizes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Commands:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6.1 Check company folder size:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;du -sh ~/company&lt;/strong&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%2Fzb4ozbc8y21z3xsukwzo.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%2Fzb4ozbc8y21z3xsukwzo.PNG" alt=" " width="800" height="240"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;the size is 60kilobytes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6.2 Check overall disk usage&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;df -h&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;du -sh → displays size of a directory in human-readable format.&lt;/p&gt;

&lt;p&gt;df -h → shows free/used space on mounted filesystems.&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%2F31xadnolegujsvjczkxn.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%2F31xadnolegujsvjczkxn.PNG" alt=" " width="800" height="262"&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%2Fanb1m185dqb409yvwm5j.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%2Fanb1m185dqb409yvwm5j.PNG" alt=" " width="800" height="169"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This project has demonstrated how Linux can be used to simulate and manage a real-world company’s file system. By creating a structured directory for departments, adding and organizing files, moving and renaming them, and finally securing everything with compression and backups, you have gained practical skills that every system administrator and DevOps engineer must master.&lt;/p&gt;

&lt;p&gt;Through these hands-on exercises, you learned how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create and navigate directories with mkdir and cd.&lt;/li&gt;
&lt;li&gt;Manage files using commands like touch, ls, cp, and mv.&lt;/li&gt;
&lt;li&gt;Search for files and content with find and grep.&lt;/li&gt;
&lt;li&gt;Back up and restore data with tar and gzip.&lt;/li&gt;
&lt;li&gt;Monitor storage usage with du and df.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By applying these skills to a mock company environment, you not only practiced Linux commands but also understood their importance in real workplace scenarios such as organizing data, maintaining backups, and ensuring efficient file management. Mastering these fundamentals provides a solid foundation for more advanced topics like shell scripting, permissions, user management, automation, and cloud deployment. With these skills in hand, you are well on your way to becoming confident in Linux system administration.&lt;/p&gt;

</description>
      <category>linux</category>
      <category>devops</category>
      <category>bash</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to Create DNS zones and configure DNS settings</title>
      <dc:creator>SUBAIR NURUDEEN ADEWALE</dc:creator>
      <pubDate>Wed, 10 Sep 2025 17:20:07 +0000</pubDate>
      <link>https://dev.to/subair09/how-to-create-dns-zones-and-configure-dns-settings-3c72</link>
      <guid>https://dev.to/subair09/how-to-create-dns-zones-and-configure-dns-settings-3c72</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In modern cloud environments, Domain Name System (DNS) plays a vital role in managing how applications and services communicate. Instead of relying on IP addresses, DNS provides user-friendly names that are easier to manage and remember. In this project, we focus on creating and configuring DNS zones and DNS settings within Microsoft Azure. By setting up private DNS zones, configuring DNS records, and integrating DNS settings with a virtual network, we ensure reliable name resolution for resources, improve security, and simplify network management.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tasks to Cover&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Create and configure a private DNS zone&lt;/strong&gt; – to manage DNS records within a secure, isolated environment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create and configure DNS records&lt;/strong&gt; – to map domain names to IP addresses or other resources.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configure DNS settings on a virtual network&lt;/strong&gt; – to ensure virtual machines and services in the VNet can resolve names efficiently.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 1 Create a private DNS zone&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Azure Private DNS provides a reliable, secure DNS service to manage and resolve domain names in a virtual network without the need to add a custom DNS solution. By using private DNS zones, you can use your own custom domain names rather than the Azure-provided names.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On the Azure portal, search for and select Private dns zones.&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%2F40lf26kepiktf4fq00h4.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%2F40lf26kepiktf4fq00h4.PNG" alt=" " width="800" height="475"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select + Create and configure the DNS zone.&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%2Fmuqeal12l5n6k6ctuv9l.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%2Fmuqeal12l5n6k6ctuv9l.PNG" alt=" " width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Subscription: Select your subscription&lt;/li&gt;
&lt;li&gt;Resource group: RG1&lt;/li&gt;
&lt;li&gt;Name: private.contoso.com&lt;/li&gt;
&lt;li&gt;Region: East US&lt;/li&gt;
&lt;li&gt;Select Review + create&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%2F50me1cs404qcrtl7kve3.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%2F50me1cs404qcrtl7kve3.PNG" alt=" " width="800" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select Create.&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%2F4jgdkzl6u19j7kbq3dae.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%2F4jgdkzl6u19j7kbq3dae.PNG" alt=" " width="800" height="476"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Wait for the DNS zone to deploy, and then select Go to resource.&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%2Fuvuhhu520qw464nvpps1.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%2Fuvuhhu520qw464nvpps1.PNG" alt=" " width="800" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Step 2 Create a virtual network link to your private DNS zone&lt;/p&gt;

&lt;p&gt;To resolve DNS records in a private DNS zone, resources must be linked to the private zone. A virtual network link associates the virtual network to the private zone.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the portal, continue working on the private.contoso.com DNS zone.&lt;/li&gt;
&lt;li&gt;In the DNS Management blade, select + Virtual network links.&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%2Fph8kruhc5wg6kd6n40zv.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%2Fph8kruhc5wg6kd6n40zv.PNG" alt=" " width="800" height="440"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select + Add” and configure the virtual network link.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Link name: app-vnet-link&lt;br&gt;
Virtual network: app-vnet&lt;br&gt;
Enable auto registration: Enabled&lt;br&gt;
Select Create and wait for the deployment to finish. If necessary, Refresh the page.&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%2F1jkcc71z62ax4e6pzhew.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%2F1jkcc71z62ax4e6pzhew.PNG" alt=" " width="800" height="505"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The virtual ntework as been link to the private DNS zone &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%2Fh8ht0wzbmzvcpei81aje.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%2Fh8ht0wzbmzvcpei81aje.PNG" alt=" " width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3 Create a DNS record set&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;DNS records provide information about the DNS zone.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the portal, continue working on the private.contoso.com DNS zone.&lt;/li&gt;
&lt;li&gt;In the DNS Management blade, select + Recordsets.&lt;/li&gt;
&lt;li&gt;Notice that two A records have automatically been created for each of the virtual machines.&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%2Fj08sgfw9eig4kf8qly2k.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%2Fj08sgfw9eig4kf8qly2k.PNG" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Select + Add and configure a record set. When finished select Add.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Name: backend&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Type: A&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;TTL: 1&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;IP address: 10.1.1.5&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%2Fda7reqdm6wygoxuxok23.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%2Fda7reqdm6wygoxuxok23.PNG" alt=" " width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DNS recordset as been created &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%2F1sh9hgz76hby043t1wcx.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%2F1sh9hgz76hby043t1wcx.PNG" alt=" " width="800" height="445"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: This record set implies there is a virtual machine in app-vnet with a private IP address of 10.1.1.5.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By completing this project, a fully functional DNS infrastructure is established within Azure. Private DNS zones and records provide centralized management of domain names, while linking DNS settings to the virtual network ensures seamless name resolution across applications and services. This configuration not only improves accessibility and connectivity but also enhances security by keeping DNS resolution internal to the environment. Overall, the project demonstrates how DNS in Azure can simplify network operations and provide a scalable foundation for future workloads.&lt;/p&gt;

</description>
      <category>networking</category>
      <category>devops</category>
      <category>azure</category>
      <category>aws</category>
    </item>
    <item>
      <title>How to Configure Network routing in Azure</title>
      <dc:creator>SUBAIR NURUDEEN ADEWALE</dc:creator>
      <pubDate>Wed, 10 Sep 2025 15:05:01 +0000</pubDate>
      <link>https://dev.to/subair09/how-to-configure-network-routing-in-azure-4g8l</link>
      <guid>https://dev.to/subair09/how-to-configure-network-routing-in-azure-4g8l</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In cloud networking, routing plays a vital role in ensuring that traffic between subnets, virtual networks, and external networks is directed efficiently and securely. Within Microsoft Azure, custom route tables allow administrators to control how traffic flows in and out of subnets, providing flexibility beyond the default system routing. This project focuses on configuring network routing in Azure by creating and associating a custom route table with subnets, and defining specific routes for traffic management. By completing this project, you will gain practical knowledge of how routing works in Azure and how to customize it to meet application or organizational requirements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tasks to Cover&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Create a Route Table&lt;/strong&gt; – Set up a custom route table that will manage routing rules within the virtual network.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add the Route Table&lt;/strong&gt; – Ensure the route table is properly integrated into the Azure environment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Associate the Route Table to the Subnets&lt;/strong&gt; – Link the created route table to one or more subnets so that its rules apply to traffic within those subnets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create a Route in the Route Table&lt;/strong&gt; – Define a custom route that controls how specific traffic is directed, ensuring traffic flows as intended.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 1 Create a Route Table&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Azure automatically creates a route table for each subnet within an Azure virtual network. The route table includes the default system routes. You can create route tables and routes to override Azure’s default system routes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Record the private IP address of app-vnet-firewall&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the search box at the top of the portal, enter Firewall. Select Firewall in the search results.&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%2Ft04ygjhptljn6vy82mvj.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%2Ft04ygjhptljn6vy82mvj.png" alt=" " width="800" height="467"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select app-vnet-firewall.&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%2Flkv8gyystbnq7cjst3ai.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%2Flkv8gyystbnq7cjst3ai.PNG" alt=" " width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select Overview and record the Private IP address.&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%2Fvys9ln33yvzwo634i4xx.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%2Fvys9ln33yvzwo634i4xx.PNG" alt=" " width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2 Add the route table&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the search box, enter Route tables. When Route table appears in the search results, select it.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;In the Route table page, select + Create and create the route table.&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%2Fl4acc443leds7p95z88w.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%2Fl4acc443leds7p95z88w.PNG" alt=" " width="800" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Complete the following configuration&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Subscription: Select your subscription&lt;/li&gt;
&lt;li&gt;Resource group: RG1&lt;/li&gt;
&lt;li&gt;Region: East US&lt;/li&gt;
&lt;li&gt;Name: app-vnet-firewall-rt&lt;/li&gt;
&lt;li&gt;Select Review + create &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%2F6pasuo6coau1uegp7opn.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%2F6pasuo6coau1uegp7opn.PNG" alt=" " width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select Create.&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%2Fotxd39gsggq7ygxju3sk.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%2Fotxd39gsggq7ygxju3sk.PNG" alt=" " width="800" height="509"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Wait for the route table to deploy, then select Go to resource.&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%2Fljxr1wqle67djt3qg305.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%2Fljxr1wqle67djt3qg305.PNG" alt=" " width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3 Associate the route table to the subnets&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the portal, continue working with the route table, select app-vnet-firewall-rt.&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%2Fmqh9tvvw8ndwyc19xooc.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%2Fmqh9tvvw8ndwyc19xooc.PNG" alt=" " width="800" height="378"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the Settings blade, select Subnets and then + Associate.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Configure an association to the frontend subnet, then select OK.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Virtual network: app-vnet (RG1)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Subnet: frontend&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%2Fvwc05kl4n5rjgwxcs66h.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%2Fvwc05kl4n5rjgwxcs66h.PNG" alt=" " width="800" height="458"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Configure an association to the backend subnet, then select OK.&lt;/li&gt;
&lt;li&gt;Virtual network: app-vnet (RG1)&lt;/li&gt;
&lt;li&gt;Subnet: backend&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%2Fdxsp9crqk073oee4eenf.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%2Fdxsp9crqk073oee4eenf.PNG" alt=" " width="800" height="462"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Frontend and the Backend subnets as been associated to the route table.&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%2Fwehpmw25mr46w85coovz.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%2Fwehpmw25mr46w85coovz.PNG" alt=" " width="800" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4 Create a route in the route table&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the portal, continue working with the route table, select app-vnet-firewall-rt.&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%2Fmqh9tvvw8ndwyc19xooc.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%2Fmqh9tvvw8ndwyc19xooc.PNG" alt=" " width="800" height="378"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In the Settings blade, select Routes and then + Add.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Configure the route, then select Add.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Route name    outbound-firewall&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Destination type  IP addresses&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Destination IP addresses/CIDR range   0.0.0.0/0&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Next hop type Virtual appliance&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Next hop address: private IP address of the firewall (10.0.2.4)&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%2Frjgat7jrlma707eix6v0.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%2Frjgat7jrlma707eix6v0.PNG" alt=" " width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Route was created successfully in the route table&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%2Fft447s9l4xtjlxh2py7o.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%2Fft447s9l4xtjlxh2py7o.PNG" alt=" " width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By completing this project, a custom route table has been successfully created, associated, and configured within Azure. These steps ensure greater control over traffic flow in the virtual network, enabling administrators to optimize performance, enforce security, and implement custom networking requirements. This exercise demonstrates the practical application of Azure’s routing capabilities and establishes a foundation for more advanced network designs.&lt;/p&gt;

</description>
      <category>networking</category>
      <category>microsoft</category>
      <category>azure</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
