<?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: Ibrahim Bio Abubakar</title>
    <description>The latest articles on DEV Community by Ibrahim Bio Abubakar (@ibrahimbioabu).</description>
    <link>https://dev.to/ibrahimbioabu</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%2F2896883%2Fdc7ddd1e-4622-4821-a0f3-b44ed8b2a901.jpeg</url>
      <title>DEV Community: Ibrahim Bio Abubakar</title>
      <link>https://dev.to/ibrahimbioabu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ibrahimbioabu"/>
    <language>en</language>
    <item>
      <title>How to Create an EC2 VM in AWS (Step-by-Step Guide for Beginners)</title>
      <dc:creator>Ibrahim Bio Abubakar</dc:creator>
      <pubDate>Thu, 25 Sep 2025 14:55:54 +0000</pubDate>
      <link>https://dev.to/ibrahimbioabu/how-to-create-an-ec2-vm-in-aws-step-by-step-guide-for-beginners-481</link>
      <guid>https://dev.to/ibrahimbioabu/how-to-create-an-ec2-vm-in-aws-step-by-step-guide-for-beginners-481</guid>
      <description>&lt;p&gt;Amazon EC2 (Elastic Compute Cloud) is one of the most popular services in AWS, allowing you to launch and manage virtual machines in the cloud. In this guide, we’ll walk through creating a &lt;strong&gt;Demo EC2&lt;/strong&gt; instance using the &lt;strong&gt;Amazon Linux AMI&lt;/strong&gt; and a &lt;strong&gt;t2.micro free-tier instance type&lt;/strong&gt;. We’ll also add a simple user data script to run on startup.&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;An &lt;a href="https://aws.amazon.com/" rel="noopener noreferrer"&gt;AWS account&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Basic familiarity with AWS Management Console&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 1: Log in to AWS Management Console
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Head over to &lt;a href="https://console.aws.amazon.com/" rel="noopener noreferrer"&gt;AWS Console&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;From the &lt;strong&gt;Services&lt;/strong&gt; menu, search for &lt;strong&gt;EC2&lt;/strong&gt; and click on it.&lt;/li&gt;
&lt;/ol&gt;

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




&lt;h2&gt;
  
  
  Step 2: Launch an Instance
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Click &lt;strong&gt;Launch instance&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ol&gt;
&lt;li&gt;Give your instance a name: &lt;code&gt;Demo EC2&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

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




&lt;h2&gt;
  
  
  Step 3: Choose Amazon Machine Image (AMI)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;In the &lt;strong&gt;Application and OS Images&lt;/strong&gt; section, choose:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Amazon Linux&lt;/strong&gt; (Free Tier eligible).&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%2Fz4g0w1thogagyz8en0iq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz4g0w1thogagyz8en0iq.png" alt="Image 4" width="765" height="474"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  ⚡ Step 4: Select Instance Type
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;From the &lt;strong&gt;Instance type&lt;/strong&gt; dropdown, select:&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;t2.micro&lt;/strong&gt; (Free Tier eligible).&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%2Fbial8vir9hte7vom8fn2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbial8vir9hte7vom8fn2.png" alt="Image 5" width="800" height="286"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5: Configure User Data (Startup Script)
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Scroll down to &lt;strong&gt;Advanced details&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;User data&lt;/strong&gt; section, paste the following script:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
   &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Hurray!!! We got this working"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /home/ec2-user/startup.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;blockquote&gt;
&lt;p&gt;This script will create a file named &lt;code&gt;startup.txt&lt;/code&gt; with the message inside.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Step 6: Configure Key Pair
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Either select an existing key pair or create a new one.&lt;/li&gt;
&lt;li&gt;This will allow you to SSH into your instance later.&lt;/li&gt;
&lt;/ol&gt;

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




&lt;h2&gt;
  
  
  Step 7: Configure Network Settings
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Choose default VPC and subnet (unless you want custom networking).&lt;/li&gt;
&lt;li&gt;Allow &lt;strong&gt;SSH traffic&lt;/strong&gt; from your IP.&lt;/li&gt;
&lt;li&gt;Allow &lt;strong&gt;HTTP traffic&lt;/strong&gt; from the internet.&lt;/li&gt;
&lt;/ol&gt;

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




&lt;h2&gt;
  
  
  Step 8: Launch the Instance
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Review all settings.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ol&gt;
&lt;li&gt;Click &lt;strong&gt;Launch instance&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Your &lt;strong&gt;Demo EC2&lt;/strong&gt; instance will now spin up in the cloud! &lt;/p&gt;

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




&lt;h2&gt;
  
  
  Step 9: Verify User Data Script
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Once the instance is running, select connect for EC2 Instance Connect.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ol&gt;
&lt;li&gt;Ensure the &lt;strong&gt;Connection type&lt;/strong&gt; is set to &lt;code&gt;Connect using a Public IP&lt;/code&gt;, &lt;code&gt;Puplic IPv4 address&lt;/code&gt; is selected and the &lt;strong&gt;Username&lt;/strong&gt; is &lt;code&gt;ec2-user&lt;/code&gt;; then select &lt;code&gt;Connect&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;We have now successfully connected to the Amazon Linux 2023 machine: &lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;Run:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;cat&lt;/span&gt; /home/ec2-user/startup.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ol&gt;
&lt;li&gt;You should see:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   Hurray!!! We got this working
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






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

&lt;p&gt;In just a few steps, you’ve launched your first &lt;strong&gt;Amazon EC2 instance&lt;/strong&gt; using &lt;strong&gt;Amazon Linux&lt;/strong&gt; on a &lt;strong&gt;t2.micro free-tier&lt;/strong&gt; machine. With the user data script, we confirmed automation works right at startup.&lt;/p&gt;

&lt;p&gt;Next steps: Try customizing the user data script to install software packages, run web servers, or deploy applications automatically.&lt;/p&gt;




</description>
      <category>aws</category>
      <category>ec2</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Build Once, Deploy Everywhere: Deploying a .NET 8 API with Docker, AKS &amp; GitHub Actions</title>
      <dc:creator>Ibrahim Bio Abubakar</dc:creator>
      <pubDate>Wed, 24 Sep 2025 18:39:57 +0000</pubDate>
      <link>https://dev.to/ibrahimbioabu/build-once-deploy-everywhere-deploying-a-net-8-api-with-docker-aks-github-actions-4h4o</link>
      <guid>https://dev.to/ibrahimbioabu/build-once-deploy-everywhere-deploying-a-net-8-api-with-docker-aks-github-actions-4h4o</guid>
      <description>&lt;p&gt;Cloud-native development can feel overwhelming at first—containers, Kubernetes, CI/CD pipelines, cloud providers, etc. This tutorial walks you step by step from writing a simple .NET 8 Web API to deploying it on Azure Kubernetes Service (AKS) with a fully automated GitHub Actions CI/CD pipeline.&lt;/p&gt;

&lt;p&gt;We’ll go beyond just writing code. You’ll also learn &lt;strong&gt;how and why&lt;/strong&gt; each tool fits into the bigger cloud-native picture.&lt;/p&gt;




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

&lt;p&gt;By completing this tutorial, you will master:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Building production-ready .NET 8 Web APIs&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Containerizing applications with Docker&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Deploying to Azure Kubernetes Service (AKS)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Setting up CI/CD pipelines with GitHub Actions&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Applying cloud-native development best practices&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;We’ll build a Weather Forecast API and deploy it to the cloud.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Backend&lt;/strong&gt; → .NET 8 Web API&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Containerization&lt;/strong&gt; → Docker&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cloud Platform&lt;/strong&gt; → Azure Kubernetes Service (AKS)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Automation&lt;/strong&gt; → GitHub Actions for CI/CD&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;&lt;strong&gt;Required Software&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Install these tools (in order):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;Visual Studio Code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dotnet.microsoft.com/en-us/download/dotnet/8.0" rel="noopener noreferrer"&gt;.NET 8 SDK&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://git-scm.com/downloads" rel="noopener noreferrer"&gt;Git&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.docker.com/products/docker-desktop/" rel="noopener noreferrer"&gt;Docker Desktop&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;⚠️ Remember: Start Docker Desktop after installation&lt;/p&gt;

&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/cli/azure/install-azure-cli" rel="noopener noreferrer"&gt;Azure CLI&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://kubernetes.io/docs/tasks/tools/" rel="noopener noreferrer"&gt;kubectl&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://cli.github.com/" rel="noopener noreferrer"&gt;GitHub CLI&lt;/a&gt; (optional)&lt;/p&gt;

&lt;p&gt;Required Accounts&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;(free)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://azure.microsoft.com/en-gb/pricing/purchase-options/azure-account?icid=azurefreeaccount" rel="noopener noreferrer"&gt;Azure&lt;/a&gt; (free tier with $200 credits)&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Verify Installation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Run the following commands in your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet &lt;span class="nt"&gt;--version&lt;/span&gt;          &lt;span class="c"&gt;# Shows installed .NET SDK version (should be 8.x.x)&lt;/span&gt;
git &lt;span class="nt"&gt;--version&lt;/span&gt;             &lt;span class="c"&gt;# Confirms Git is installed&lt;/span&gt;
docker &lt;span class="nt"&gt;--version&lt;/span&gt;          &lt;span class="c"&gt;# Confirms Docker CLI works&lt;/span&gt;
az &lt;span class="nt"&gt;--version&lt;/span&gt;              &lt;span class="c"&gt;# Shows Azure CLI version&lt;/span&gt;
kubectl version &lt;span class="nt"&gt;--client&lt;/span&gt;  &lt;span class="c"&gt;# Verifies kubectl client&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: If any fail → reinstall that tool.&lt;/p&gt;

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




&lt;p&gt;💻 &lt;strong&gt;Step 1: Create the .NET Application&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.1 Set Up Project Structure&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;weather-app-demo   &lt;span class="c"&gt;# Create root project folder&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;weather-app-demo
&lt;span class="nb"&gt;mkdir &lt;/span&gt;WeatherApp         &lt;span class="c"&gt;# Create app folder&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;WeatherApp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why? → Organizing code and infra configs in separate folders makes CI/CD pipelines easier to manage.&lt;/p&gt;

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




&lt;p&gt;&lt;strong&gt;1.2 Initialize .NET Project&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet new webapi &lt;span class="nt"&gt;-minimal&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;dotnet new&lt;/code&gt; → Creates a new project&lt;/p&gt;

&lt;p&gt;&lt;code&gt;webapi&lt;/code&gt; → Template for REST APIs&lt;/p&gt;

&lt;p&gt;&lt;code&gt;-minimal&lt;/code&gt; → Uses the simplified .NET 8 minimal API syntax (less boilerplate)&lt;/p&gt;

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




&lt;p&gt;&lt;strong&gt;1.3 Add Dependencies&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet add package Microsoft.Extensions.Diagnostics.HealthChecks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;HealthChecks&lt;/code&gt; → Adds endpoints for monitoring app health (Kubernetes probes rely on this).&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet add package Swashbuckle.AspNetCore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;Swashbuckle.AspNetCore&lt;/code&gt; → Generates Swagger/OpenAPI docs 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%2Fnarferxjwfsnd50krw0n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnarferxjwfsnd50krw0n.png" alt="Image 5" width="800" height="416"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;1.4 Application Code&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Replace the content &lt;strong&gt;Program.cs&lt;/strong&gt; with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;WebApplication&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Register services&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddHealthChecks&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;          &lt;span class="c1"&gt;// Adds /health endpoint&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddEndpointsApiExplorer&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// Enables endpoint discovery for Swagger&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddSwaggerGen&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;            &lt;span class="c1"&gt;// Generates Swagger UI&lt;/span&gt;

&lt;span class="c1"&gt;// Configure Kestrel to listen on port 8080 (important for containers)&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WebHost&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ConfigureKestrel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ListenAnyIP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// Allows traffic from any network interface&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Enable Swagger UI in Dev &amp;amp; Prod&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsDevelopment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsProduction&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseSwagger&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseSwaggerUI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; 
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SwaggerEndpoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/swagger/v1/swagger.json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Weather API v1"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RoutePrefix&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"swagger"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// URL: /swagger&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Welcome endpoint&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MapGet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Message&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Welcome to the Weather App!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Environment&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EnvironmentName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Timestamp&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UtcNow&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"GetWelcome"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithTags&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"General"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Weather forecast endpoint&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MapGet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/weather"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;summaries&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="s"&gt;"Freezing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Bracing"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Chilly"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Cool"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Mild"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
        &lt;span class="s"&gt;"Warm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Balmy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Hot"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Sweltering"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Scorching"&lt;/span&gt; 
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;forecast&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Enumerable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Date&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DateOnly&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromDateTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddDays&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="c1"&gt;// Next 5 days&lt;/span&gt;
        &lt;span class="n"&gt;TemperatureC&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Shared&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;(-&lt;/span&gt;&lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;55&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;                 &lt;span class="c1"&gt;// Random °C&lt;/span&gt;
        &lt;span class="n"&gt;TemperatureF&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;                                           &lt;span class="c1"&gt;// Placeholder&lt;/span&gt;
        &lt;span class="n"&gt;Summary&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;summaries&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;Random&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Shared&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;summaries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;temp&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TemperatureC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;TemperatureF&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;32&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="n"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TemperatureC&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;0.5556&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="c1"&gt;// Formula °C → °F&lt;/span&gt;
        &lt;span class="n"&gt;temp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Summary&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;forecast&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"GetWeatherForecast"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithTags&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Weather"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Health check endpoint (important for Kubernetes probes)&lt;/span&gt;
&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MapHealthChecks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"/health"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WithTags&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Health"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  &lt;span class="c1"&gt;// Starts the web server&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Concepts Explained:&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Minimal APIs&lt;/strong&gt; → Introduced in .NET 6, let you build APIs with fewer lines.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Swagger&lt;/strong&gt; → Auto-generates interactive API docs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Probes&lt;/strong&gt; → Kubernetes uses health endpoints to restart/retry containers when needed.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dotnet 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%2Feonkm2jpankc8spmqgg6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feonkm2jpankc8spmqgg6.png" alt="Image 5" width="800" height="239"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Test endpoints in browser or with &lt;code&gt;curl&lt;/code&gt; in the terminal:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;http://localhost:8080/&lt;/code&gt; → Welcome message&lt;/p&gt;

&lt;p&gt;&lt;code&gt;http://localhost:8080/weather&lt;/code&gt; → Forecast data&lt;/p&gt;

&lt;p&gt;&lt;code&gt;http://localhost:8080/swagger&lt;/code&gt; → Swagger docs&lt;/p&gt;

&lt;p&gt;&lt;code&gt;http://localhost:8080/health&lt;/code&gt; → Health check&lt;/p&gt;

&lt;p&gt;Below is the Weather App on a 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%2Fuoce6cz0u2eso9bxnsfm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuoce6cz0u2eso9bxnsfm.png" alt="Image z" width="800" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Stop the app with &lt;code&gt;Ctrl + C&lt;/code&gt;.&lt;/p&gt;




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

&lt;p&gt;We’ll package the .NET app into a &lt;strong&gt;Docker container&lt;/strong&gt; so it can run consistently anywhere.&lt;/p&gt;

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

&lt;p&gt;Create a file named Dockerfile inside &lt;code&gt;WeatherApp/&lt;/code&gt; directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;Dockerfile
&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%2Fjj9jookvzr5ygjtphd2n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjj9jookvzr5ygjtphd2n.png" alt="Image 6" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add the content below to the &lt;code&gt;Dockerfile&lt;/code&gt;created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# Multi-stage build for optimized image size&lt;/span&gt;

&lt;span class="c"&gt;# Runtime stage&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;mcr.microsoft.com/dotnet/aspnet:9.0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;base&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 8080&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; ASPNETCORE_URLS=http://+:8080&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; ASPNETCORE_ENVIRONMENT=Production&lt;/span&gt;

&lt;span class="c"&gt;# Build stage&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;mcr.microsoft.com/dotnet/sdk:9.0&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build&lt;/span&gt;
&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; BUILD_CONFIGURATION=Release&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /src&lt;/span&gt;

&lt;span class="c"&gt;# Copy project file and restore dependencies&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; ["WeatherApp/WeatherApp.csproj", "."]&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;dotnet restore &lt;span class="s2"&gt;"WeatherApp.csproj"&lt;/span&gt;

&lt;span class="c"&gt;# Copy source code and build&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /src&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; WeatherApp/ ./WeatherApp/&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /src/WeatherApp&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;dotnet restore &lt;span class="s2"&gt;"WeatherApp.csproj"&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;dotnet build &lt;span class="s2"&gt;"WeatherApp.csproj"&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="nv"&gt;$BUILD_CONFIGURATION&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /app/build

&lt;span class="c"&gt;# Publish stage&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;publish&lt;/span&gt;
&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; BUILD_CONFIGURATION=Release&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;dotnet publish &lt;span class="s2"&gt;"WeatherApp.csproj"&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="nv"&gt;$BUILD_CONFIGURATION&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /app/publish /p:UseAppHost&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt;

&lt;span class="c"&gt;# Final stage&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;base&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;final&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=publish /app/publish .&lt;/span&gt;
&lt;span class="k"&gt;ENTRYPOINT&lt;/span&gt;&lt;span class="s"&gt; ["dotnet", "WeatherApp.dll"]&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Concept&lt;/em&gt;: &lt;strong&gt;Multi-stage builds&lt;/strong&gt; → build and runtime environments are separate. This keeps the final image small and secure.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;2.2 Create .dockerignore&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Prevent unnecessary files from bloating your image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch&lt;/span&gt; .dockerignore

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

&lt;p&gt;Add the content below to the &lt;code&gt;Dockerfile&lt;/code&gt;created:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
# Build outputs
bin/
obj/
out/

# IDE files
.vs/
.vscode/
*.user
*.suo

# OS files
.DS_Store
Thumbs.db

# Git
.git/
.gitignore

# Docs
README.md
*.md

# Docker
Dockerfile*
.dockerignore

# Logs
*.log
logs/

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

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;2.3 Build &amp;amp; Test Container&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Build image&lt;/span&gt;
docker build &lt;span class="nt"&gt;-t&lt;/span&gt; weather-app:local &lt;span class="nb"&gt;.&lt;/span&gt;     &lt;span class="c"&gt;# Ensure your Docker Desktop is running before you run this command&lt;/span&gt;
&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%2Fxrz12y4ae6eouwj5la2b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxrz12y4ae6eouwj5la2b.png" alt="Image 8" width="800" height="488"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Below is the built WeatherApp image in Docker Desktop app:&lt;/p&gt;

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

&lt;p&gt;Now let's run the container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Run container&lt;/span&gt;
docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:8080 &lt;span class="nt"&gt;--name&lt;/span&gt; weather-test weather-app:local
&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%2Frmxw681l26zsxcncuzlr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frmxw681l26zsxcncuzlr.png" alt="Image 10" width="800" height="219"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Test the running app using &lt;code&gt;curl&lt;/code&gt; in the terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Test endpoints&lt;/span&gt;
curl http://localhost:8080/
curl http://localhost:8080/weather
&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%2Fbhbu3g9jmliwn7xdc7dr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbhbu3g9jmliwn7xdc7dr.png" alt="Image 11" width="800" height="196"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Clean up&lt;/span&gt;
docker stop weather-test
docker &lt;span class="nb"&gt;rm &lt;/span&gt;weather-test

&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%2Fifzrgtyfnc7z8s3x3yyb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fifzrgtyfnc7z8s3x3yyb.png" alt="Image 12" width="800" height="182"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Concept&lt;/em&gt;: Containers make your app portable — works the same on your laptop and in the cloud.&lt;/p&gt;




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

&lt;p&gt;We’ll use &lt;strong&gt;Azure CLI&lt;/strong&gt; to provision resources.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.1 Login to Azure&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az login  &lt;span class="c"&gt;#Opens browser for Azure sign-in.&lt;/span&gt;

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

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;3.2 Select Subscription&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az account list &lt;span class="nt"&gt;--output&lt;/span&gt; table     &lt;span class="c"&gt;# See subscriptions&lt;/span&gt;
az account &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;--subscription&lt;/span&gt; &lt;span class="s2"&gt;"Your-Subscription-Name"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;3.3 Create Resource Group&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az group create &lt;span class="nt"&gt;--name&lt;/span&gt; student-demo &lt;span class="nt"&gt;--location&lt;/span&gt; eastus
&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%2Fdg2g4lj6s910av7y48fq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdg2g4lj6s910av7y48fq.png" alt="Image 14" width="800" height="210"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Concept&lt;/em&gt;: A resource group is a logical container for all your Azure resources.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;3.4 Create Container Registry (ACR)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az acr create &lt;span class="nt"&gt;--resource-group&lt;/span&gt; student-demo &lt;span class="nt"&gt;--name&lt;/span&gt; studentdemo2042acr &lt;span class="nt"&gt;--sku&lt;/span&gt; Basic
&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%2F3umc7nty58iyn34jjia7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3umc7nty58iyn34jjia7.png" alt="Image 15" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Concept&lt;/em&gt;: ACR = private Docker Hub inside Azure.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;3.5 Build &amp;amp; Push Image&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az acr build &lt;span class="nt"&gt;--registry&lt;/span&gt; studentdemo2042acr &lt;span class="nt"&gt;--image&lt;/span&gt; weather-app:latest &lt;span class="nb"&gt;.&lt;/span&gt;
&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%2Fg9nl2aktmt3rfj7x25bc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg9nl2aktmt3rfj7x25bc.png" alt="Image 16" width="800" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Why ACR build?&lt;/em&gt; → Azure builds inside the cloud, avoiding OS/CPU compatibility issues.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;3.6 Create AKS Cluster&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az aks create &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--resource-group&lt;/span&gt; student-demo &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; student-aks-cluster &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--node-count&lt;/span&gt; 1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--node-vm-size&lt;/span&gt; Standard_B2s &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--attach-acr&lt;/span&gt; studentdemo2042acr &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--enable-managed-identity&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--generate-ssh-keys&lt;/span&gt;
&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%2Fbwro3y2ail8hd3r1v7qk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbwro3y2ail8hd3r1v7qk.png" alt="Image 17" width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📌 &lt;em&gt;Concept&lt;/em&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;AKS&lt;/strong&gt; = Azure-managed Kubernetes cluster&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;attach-acr&lt;/strong&gt; → avoids ImagePullBackOff errors by linking AKS to ACR automatically&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;3.7 Connect to Cluster&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;az aks get-credentials &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--resource-group&lt;/span&gt; student-demo &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; student-aks-cluster
&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%2Fqhx578cipzu5cae5yrkf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqhx578cipzu5cae5yrkf.png" alt="Image 18" width="800" height="204"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get nodes   &lt;span class="c"&gt;# Verify cluster connection&lt;/span&gt;
&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%2Fiziki9vt8qj38gg0txym.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiziki9vt8qj38gg0txym.png" alt="Image 19" width="800" height="204"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;☸️ &lt;strong&gt;Step 4: Deploy with Kubernetes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Kubernetes uses &lt;strong&gt;YAML manifests&lt;/strong&gt; to declare your app’s state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ..  &lt;span class="c"&gt;# Back to weather-app-demo folder&lt;/span&gt;
&lt;span class="nb"&gt;mkdir &lt;/span&gt;k8s
&lt;span class="nb"&gt;cd &lt;/span&gt;k8s
&lt;span class="nb"&gt;touch &lt;/span&gt;deployment.yaml
&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%2Fz6yws2cv1tdpfnwl2o2w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz6yws2cv1tdpfnwl2o2w.png" alt="Image 20" width="800" height="221"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Copy and paste the content below in &lt;code&gt;k8s/deployment.yaml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;
&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apps/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deployment&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;weather-app&lt;/span&gt;
  &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;weather-app&lt;/span&gt;
    &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;replicas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;  &lt;span class="c1"&gt;# Run 2 pods for high availability&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;matchLabels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;weather-app&lt;/span&gt;
  &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;weather-app&lt;/span&gt;
        &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
    &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;containers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;weather-app&lt;/span&gt;
        &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;studentdemo2024acr.azurecr.io/weather-app:latest&lt;/span&gt;
        &lt;span class="na"&gt;imagePullPolicy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Always&lt;/span&gt;
        &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;containerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8080&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ASPNETCORE_ENVIRONMENT&lt;/span&gt;
          &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Production"&lt;/span&gt;
        &lt;span class="na"&gt;resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;  &lt;span class="c1"&gt;# Resource requests &amp;amp; limits&lt;/span&gt;
          &lt;span class="na"&gt;requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;128Mi"&lt;/span&gt;
            &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;100m"&lt;/span&gt;
          &lt;span class="na"&gt;limits&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;512Mi"&lt;/span&gt;
            &lt;span class="na"&gt;cpu&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;500m"&lt;/span&gt;
        &lt;span class="c1"&gt;# Probes for self-healing&lt;/span&gt;
        &lt;span class="na"&gt;livenessProbe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;httpGet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/health&lt;/span&gt;
            &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8080&lt;/span&gt;
          &lt;span class="na"&gt;initialDelaySeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;
        &lt;span class="na"&gt;readinessProbe&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;httpGet&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/health&lt;/span&gt;
            &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8080&lt;/span&gt;
          &lt;span class="na"&gt;initialDelaySeconds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;📌 &lt;em&gt;Concepts&lt;/em&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Deployment&lt;/strong&gt; → ensures the desired # of pods run.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Probes&lt;/strong&gt; → tell Kubernetes when a pod is healthy or ready.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;4.2 Create Service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create &lt;code&gt;k8s/service.yaml&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;touch &lt;/span&gt;service.yaml 
&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%2Ftpue7bzqhfmmo7z5c7ae.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftpue7bzqhfmmo7z5c7ae.png" alt="Image 22" width="800" height="146"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy and paste the content below in &lt;code&gt;k8s/service.yaml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Service&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;weather-app-service&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;LoadBalancer&lt;/span&gt;   &lt;span class="c1"&gt;# Exposes app to internet&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;weather-app&lt;/span&gt;
  &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;           &lt;span class="c1"&gt;# External port&lt;/span&gt;
    &lt;span class="na"&gt;targetPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8080&lt;/span&gt;   &lt;span class="c1"&gt;# Maps to container&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;📌 &lt;em&gt;Concept&lt;/em&gt;: &lt;strong&gt;A Service&lt;/strong&gt; gives your pods a stable IP address + load balancing.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;4.3 Deploy&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Apply Kubernetes manifests&lt;/span&gt;

kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; deployment.yaml
kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; service.yaml
&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%2F417pb8frg1usfk2dlbjv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F417pb8frg1usfk2dlbjv.png" alt="Image 23" width="800" height="218"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check deployment status&lt;/span&gt;
kubectl get deployments
kubectl get pods
&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%2Fov8ynz44t69dxwvn03x9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fov8ynz44t69dxwvn03x9.png" alt="Image 24" width="800" height="254"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check deployment status&lt;/span&gt;
kubectl get services
&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%2Fwf9c6319jclblqhgc9ge.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwf9c6319jclblqhgc9ge.png" alt="Image 25" width="800" height="180"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;We’ll automate build → push → deploy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5.1 Init Git&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ..  &lt;span class="c"&gt;# Back to weather-app-demo folder&lt;/span&gt;

&lt;span class="c"&gt;# Initialize Git repository&lt;/span&gt;
git init
git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Initial commit: Weather App"&lt;/span&gt;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fno9tnr1v7464rv3lagep.png" alt="Image 26" width="800" height="212"&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;5.2 Create Service Principal&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Get your subscription ID&lt;/span&gt;
&lt;span class="nv"&gt;SUBSCRIPTION_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;az account show &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="nt"&gt;--output&lt;/span&gt; tsv&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Subscription ID: &lt;/span&gt;&lt;span class="nv"&gt;$SUBSCRIPTION_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# Create service principal with contributor role&lt;/span&gt;
az ad sp create-for-rbac &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"weather-app-github-sp"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--role&lt;/span&gt; contributor &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--scopes&lt;/span&gt; /subscriptions/&lt;span class="nv"&gt;$SUBSCRIPTION_ID&lt;/span&gt;/resourceGroups/student-demo &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--sdk-auth&lt;/span&gt;
&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%2Fxtnur8au7vxxd2ogc6h5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxtnur8au7vxxd2ogc6h5.png" alt="Image 27" width="800" height="279"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Save JSON output → add as GitHub Secret &lt;code&gt;AZURE_CREDENTIALS&lt;/code&gt;.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;5.3 Create GitHub Repo&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh auth login  &lt;span class="c"&gt;# Follow the prompts&lt;/span&gt;
&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%2F60bnixp2ui8137qy87w5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F60bnixp2ui8137qy87w5.png" alt="Image 28" width="800" height="243"&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%2Fseab4dbls93k6nxnxwtc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fseab4dbls93k6nxnxwtc.png" alt="Image 29" width="726" height="427"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create GitHub repository (using GitHub CLI) and Push to Repo&lt;/span&gt;
gh repo create weather-app-demo &lt;span class="nt"&gt;--public&lt;/span&gt; &lt;span class="nt"&gt;--source&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;--push&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Alternative&lt;/em&gt;: Create the repository manually on GitHub.com and push your 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%2Fsgd4fdlpbwaqzkn6dh2l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsgd4fdlpbwaqzkn6dh2l.png" alt="Image 30" width="800" height="296"&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%2Fjseuiylv3ndjazs5582i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjseuiylv3ndjazs5582i.png" alt="Image 31" width="685" height="591"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5.4 Configure GitHub Secrets&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use JSON output from step 5.2&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh secret &lt;span class="nb"&gt;set &lt;/span&gt;AZURE_CREDENTIALS &lt;span class="nt"&gt;-b&lt;/span&gt;&lt;span class="s1"&gt;'PASTE_JSON_HERE'&lt;/span&gt;
&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%2Fzxs232h8emg03zmt3voq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzxs232h8emg03zmt3voq.png" alt="Image 32" width="800" height="238"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh secret &lt;span class="nb"&gt;set &lt;/span&gt;ACR_NAME &lt;span class="nt"&gt;-b&lt;/span&gt;&lt;span class="s2"&gt;"studentdemo2042acr"&lt;/span&gt;
&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%2Fptixlwhgefpdc6og7nk4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fptixlwhgefpdc6og7nk4.png" alt="Image 33" width="800" height="150"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh secret &lt;span class="nb"&gt;set &lt;/span&gt;RESOURCE_GROUP &lt;span class="nt"&gt;-b&lt;/span&gt;&lt;span class="s2"&gt;"student-demo"&lt;/span&gt;
&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%2F1ome3altzd7o1dhx17oj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1ome3altzd7o1dhx17oj.png" alt="Image 34" width="800" height="173"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gh secret &lt;span class="nb"&gt;set &lt;/span&gt;CLUSTER_NAME &lt;span class="nt"&gt;-b&lt;/span&gt;&lt;span class="s2"&gt;"student-aks-cluster"&lt;/span&gt;
&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%2Fx9m1jb3wghps3k8yl8o3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx9m1jb3wghps3k8yl8o3.png" alt="Image 35" width="800" height="164"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5.5 Create a GitHub Workflow&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create the workflow directory and file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; .github/workflows
&lt;span class="nb"&gt;touch&lt;/span&gt; .github/workflows/deploy.yml

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

&lt;/div&gt;



&lt;p&gt;Copy and paste the content below in &lt;code&gt;.github/workflows/deploy.yml&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build and Deploy to AKS&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;main&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;main&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;IMAGE_NAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;weather-app&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build-and-deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout code&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Setup .NET&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-dotnet@v3&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;dotnet-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;9.0.x'&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Restore dependencies&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dotnet restore WeatherApp/WeatherAPP.csproj&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build application&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dotnet build WeatherApp/WeatherAPP.csproj --configuration Release --no-restore&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run tests&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dotnet test WeatherApp/WeatherAPP.csproj --no-build --verbosity normal || &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Azure Login&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;azure/login@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;creds&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.AZURE_CREDENTIALS }}&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Setup Azure CLI&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;azure/cli@v2&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;inlineScript&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;echo "Azure CLI setup complete"&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build and push Docker image to ACR&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;IMAGE_TAG=${{ secrets.ACR_NAME }}.azurecr.io/${{ env.IMAGE_NAME }}:${{ github.sha }}&lt;/span&gt;
          &lt;span class="s"&gt;az acr build \&lt;/span&gt;
            &lt;span class="s"&gt;--registry ${{ secrets.ACR_NAME }} \&lt;/span&gt;
            &lt;span class="s"&gt;--image ${{ env.IMAGE_NAME }}:${{ github.sha }} \&lt;/span&gt;
            &lt;span class="s"&gt;--file WeatherApp/Dockerfile \&lt;/span&gt;
            &lt;span class="s"&gt;.&lt;/span&gt;
          &lt;span class="s"&gt;echo "IMAGE_TAG=$IMAGE_TAG" &amp;gt;&amp;gt; $GITHUB_ENV&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to AKS&lt;/span&gt;
        &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github.ref == 'refs/heads/main'&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;echo "Checking if AKS cluster exists..."&lt;/span&gt;
          &lt;span class="s"&gt;if ! az aks show --resource-group "${{ secrets.RESOURCE_GROUP }}" --name "${{ secrets.CLUSTER_NAME }}" --output table; then&lt;/span&gt;
            &lt;span class="s"&gt;echo "ERROR: AKS cluster '${{ secrets.CLUSTER_NAME }}' not found in resource group '${{ secrets.RESOURCE_GROUP }}'"&lt;/span&gt;
            &lt;span class="s"&gt;exit 1&lt;/span&gt;
          &lt;span class="s"&gt;fi&lt;/span&gt;

          &lt;span class="s"&gt;echo "Getting AKS credentials..."&lt;/span&gt;
          &lt;span class="s"&gt;az aks get-credentials \&lt;/span&gt;
            &lt;span class="s"&gt;--resource-group ${{ secrets.RESOURCE_GROUP }} \&lt;/span&gt;
            &lt;span class="s"&gt;--name ${{ secrets.CLUSTER_NAME }} \&lt;/span&gt;
            &lt;span class="s"&gt;--overwrite-existing&lt;/span&gt;

          &lt;span class="s"&gt;echo "Testing kubectl connection..."&lt;/span&gt;
          &lt;span class="s"&gt;kubectl cluster-info&lt;/span&gt;

          &lt;span class="s"&gt;echo "Updating deployment with image: ${{ env.IMAGE_TAG }}"&lt;/span&gt;
          &lt;span class="s"&gt;kubectl set image deployment/weather-app \&lt;/span&gt;
            &lt;span class="s"&gt;weather-app=${{ env.IMAGE_TAG }}&lt;/span&gt;

          &lt;span class="s"&gt;echo "Waiting for rollout to complete..."&lt;/span&gt;
          &lt;span class="s"&gt;kubectl rollout status deployment/weather-app --timeout=600s&lt;/span&gt;

          &lt;span class="s"&gt;echo "Deployment status:"&lt;/span&gt;
          &lt;span class="s"&gt;kubectl get pods -l app=weather-app&lt;/span&gt;
          &lt;span class="s"&gt;kubectl get service weather-app-service&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;📌 &lt;em&gt;Concept&lt;/em&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;GitHub Actions&lt;/strong&gt; → automates the whole pipeline.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Every push to &lt;code&gt;main&lt;/code&gt; → build → push image → deploy to AKS.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;5.6 Deploy Your Application&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Add GitHub Actions CI/CD pipeline"&lt;/span&gt;
git push origin main
&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%2F5j66368mn2v0ry8c9msh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5j66368mn2v0ry8c9msh.png" alt="Image 35" width="800" height="258"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Monitor the deployment:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to your GitHub repository&lt;/li&gt;
&lt;li&gt;Click the Actions tab&lt;/li&gt;
&lt;li&gt;Watch your workflow run in real-time&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%2F7a4jtts4rfoe6wbgdr71.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7a4jtts4rfoe6wbgdr71.png" alt="Image 36" width="800" height="490"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;🌐 &lt;strong&gt;Step 6: Access Your Deployed App&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6.1 Get External IP Address&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check service status&lt;/span&gt;
kubectl get service weather-app-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Wait for EXTERNAL-IP (may take 2-5 minutes)&lt;/span&gt;
kubectl get service weather-app-service &lt;span class="nt"&gt;--watch&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wait until &lt;code&gt;EXTERNAL-IP&lt;/code&gt; is assigned. Then test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Test the endpoints&lt;/span&gt;
curl http://YOUR-EXTERNAL-IP/
curl http://YOUR-EXTERNAL-IP/weather
curl http://YOUR-EXTERNAL-IP/health
&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%2Fga771bhtlt7vqpn5bhjr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fga771bhtlt7vqpn5bhjr.png" alt="Image 40////" width="800" height="171"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Or open in browser&lt;/span&gt;
open http://YOUR-EXTERNAL-IP/swagger  &lt;span class="c"&gt;# macOS&lt;/span&gt;
start http://YOUR-EXTERNAL-IP/swagger  &lt;span class="c"&gt;# Windows&lt;/span&gt;
&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%2Fc73ymg8w74u4y2kudeoa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc73ymg8w74u4y2kudeoa.png" alt="Image 41" width="800" height="611"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;🔄 &lt;strong&gt;Step 7: Test Continuous Deployment&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Edit &lt;code&gt;Program.cs&lt;/code&gt; welcome message.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;app.MapGet("/", () =&amp;gt; new
{
    Message = "Welcome to the Updated Weather App! 🌤️",
    Version = "1.1.0",
    Environment = app.Environment.EnvironmentName,
    Timestamp = DateTime.UtcNow,
    DeployedBy = "GitHub Actions"
})

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Commit &amp;amp; push:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Update welcome message"&lt;/span&gt;
git push origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;GitHub Actions will rebuild &amp;amp; redeploy automatically.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ol&gt;
&lt;li&gt;Test again → you should see your new message.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://YOUR-EXTERNAL-IP/
&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%2Fgp5pg50l7jg28cj9ex22.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgp5pg50l7jg28cj9ex22.png" alt="Image 43" width="800" height="129"&gt;&lt;/a&gt;&lt;/p&gt;




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

&lt;p&gt;You’ve just taken a local &lt;strong&gt;.NET 8 Web API&lt;/strong&gt; and transformed it into a &lt;strong&gt;cloud-native application&lt;/strong&gt; running on &lt;strong&gt;Azure Kubernetes Service&lt;/strong&gt;, packaged with &lt;strong&gt;Docker&lt;/strong&gt;, and automated with a &lt;strong&gt;GitHub Actions CI/CD pipeline&lt;/strong&gt;. That’s the full lifecycle of modern cloud development — from writing code → to shipping containers → to running resilient workloads in production.&lt;/p&gt;

&lt;p&gt;The best part? You now have a &lt;strong&gt;repeatable blueprint&lt;/strong&gt; you can apply to almost any project:&lt;/p&gt;

&lt;p&gt;Swap the Weather API with your own service&lt;/p&gt;

&lt;p&gt;Reuse the Docker + Kubernetes setup&lt;/p&gt;

&lt;p&gt;Extend your GitHub workflow for tests, security scans, or staging environments&lt;/p&gt;

&lt;p&gt;This isn’t just about building an app — it’s about learning how to ship &lt;strong&gt;production-ready software at scale&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Keep experimenting: add monitoring, autoscaling, or connect a database. The cloud-native journey is iterative, but now you’ve got the foundations locked in.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>kubernetes</category>
      <category>azure</category>
      <category>githubactions</category>
    </item>
    <item>
      <title>From Code to Cloud: Seamless CI/CD with GitHub Actions and Azure Web Apps</title>
      <dc:creator>Ibrahim Bio Abubakar</dc:creator>
      <pubDate>Sat, 13 Sep 2025 21:39:02 +0000</pubDate>
      <link>https://dev.to/ibrahimbioabu/from-code-to-cloud-seamless-cicd-with-github-actions-and-azure-web-apps-3f0h</link>
      <guid>https://dev.to/ibrahimbioabu/from-code-to-cloud-seamless-cicd-with-github-actions-and-azure-web-apps-3f0h</guid>
      <description>&lt;p&gt;Have you ever built a cool Node.js app on your local machine and thought, &lt;em&gt;“Now what? How do I get this running in the cloud without manually pushing code every time?”&lt;/em&gt; That’s exactly where CI/CD (Continuous Integration and Continuous Deployment) comes to the rescue.&lt;/p&gt;

&lt;p&gt;In this article, I’ll walk you through how I took a simple Node.js application &lt;strong&gt;from code to cloud&lt;/strong&gt; using &lt;strong&gt;GitHub Actions, Docker, Kubernetes, and Azure Web App Services&lt;/strong&gt;. We’ll set up a seamless pipeline that automatically builds, tests, and deploys changes the moment you push to GitHub—no more manual deployments, no more “it works on my machine” headaches.&lt;/p&gt;

&lt;p&gt;By the end, you’ll see how easy it is to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Containerize your Node.js app with Docker 🐳&lt;/li&gt;
&lt;li&gt;Orchestrate deployments with Kubernetes ⚙️&lt;/li&gt;
&lt;li&gt;Automate CI/CD using GitHub Actions 🤖&lt;/li&gt;
&lt;li&gt;Deploy effortlessly to Azure Web Apps ☁️&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s dive in and turn your local project into a production-ready cloud app!&lt;/p&gt;




&lt;h2&gt;
  
  
  Prerequisites - Download These First!
&lt;/h2&gt;

&lt;p&gt;Before starting, you need to install these tools on your machine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Node.js (v18 or higher)&lt;/strong&gt; – &lt;a href="https://nodejs.org/" rel="noopener noreferrer"&gt;Download&lt;/a&gt; (choose LTS version 20.x)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   node &lt;span class="nt"&gt;--version&lt;/span&gt;
   npm &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Git&lt;/strong&gt; – &lt;a href="https://git-scm.com/downloads" rel="noopener noreferrer"&gt;Download&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Docker Desktop&lt;/strong&gt; – &lt;a href="https://www.docker.com/products/docker-desktop/" rel="noopener noreferrer"&gt;Download&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   docker &lt;span class="nt"&gt;--version&lt;/span&gt;
   docker-compose &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub Account&lt;/strong&gt; – &lt;a href="https://github.com" rel="noopener noreferrer"&gt;Sign up here&lt;/a&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%2Fr77px5u4hroe40x8vnoq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr77px5u4hroe40x8vnoq.png" alt="Image 1" width="800" height="279"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Code Editor (optional, recommended)&lt;/strong&gt; – &lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;VS Code&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 1: Set Up Git for Version Control
&lt;/h2&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git config &lt;span class="nt"&gt;--global&lt;/span&gt; user.name &lt;span class="s2"&gt;"Your Name"&lt;/span&gt;
git config &lt;span class="nt"&gt;--global&lt;/span&gt; user.email &lt;span class="s2"&gt;"you@example.com"&lt;/span&gt;
git config &lt;span class="nt"&gt;--global&lt;/span&gt; init.defaultBranch main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output of command in VScode terminal:&lt;/p&gt;

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

&lt;p&gt;Initialize your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;my-devops-project
&lt;span class="nb"&gt;cd &lt;/span&gt;my-devops-project
git init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output of command in VScode terminal:&lt;/p&gt;

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




&lt;h2&gt;
  
  
  Step 2: Build a Node.js Web App
&lt;/h2&gt;

&lt;p&gt;Initialize project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create package.json with default settings&lt;/span&gt;
npm init &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output of command in VScode terminal:&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%2Fz3wosz8o4m5krml97k28.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz3wosz8o4m5krml97k28.png" alt="Image 4" width="800" height="281"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Update &lt;strong&gt;package.json&lt;/strong&gt; with scripts, metadata, and dev tools (&lt;code&gt;Jest&lt;/code&gt;, &lt;code&gt;ESLint&lt;/code&gt;, &lt;code&gt;Supertest&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"name"&lt;/span&gt;: &lt;span class="s2"&gt;"my-devops-project"&lt;/span&gt;,
  &lt;span class="s2"&gt;"version"&lt;/span&gt;: &lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;,
  &lt;span class="s2"&gt;"description"&lt;/span&gt;: &lt;span class="s2"&gt;"DevOps learning project with Node.js"&lt;/span&gt;,
  &lt;span class="s2"&gt;"main"&lt;/span&gt;: &lt;span class="s2"&gt;"app.js"&lt;/span&gt;,
  &lt;span class="s2"&gt;"scripts"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"start"&lt;/span&gt;: &lt;span class="s2"&gt;"node app.js"&lt;/span&gt;,
    &lt;span class="s2"&gt;"test"&lt;/span&gt;: &lt;span class="s2"&gt;"jest"&lt;/span&gt;,
    &lt;span class="s2"&gt;"dev"&lt;/span&gt;: &lt;span class="s2"&gt;"node app.js"&lt;/span&gt;,
    &lt;span class="s2"&gt;"lint"&lt;/span&gt;: &lt;span class="s2"&gt;"eslint ."&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;,
  &lt;span class="s2"&gt;"keywords"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"devops"&lt;/span&gt;, &lt;span class="s2"&gt;"nodejs"&lt;/span&gt;, &lt;span class="s2"&gt;"docker"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
  &lt;span class="s2"&gt;"author"&lt;/span&gt;: &lt;span class="s2"&gt;"Your Name"&lt;/span&gt;,
  &lt;span class="s2"&gt;"license"&lt;/span&gt;: &lt;span class="s2"&gt;"MIT"&lt;/span&gt;,
  &lt;span class="s2"&gt;"engines"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"node"&lt;/span&gt;: &lt;span class="s2"&gt;"&amp;gt;=18.0.0"&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;,
  &lt;span class="s2"&gt;"devDependencies"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"jest"&lt;/span&gt;: &lt;span class="s2"&gt;"^29.7.0"&lt;/span&gt;,
    &lt;span class="s2"&gt;"eslint"&lt;/span&gt;: &lt;span class="s2"&gt;"^8.57.0"&lt;/span&gt;,
    &lt;span class="s2"&gt;"supertest"&lt;/span&gt;: &lt;span class="s2"&gt;"^7.1.4"&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Then create &lt;code&gt;app.js&lt;/code&gt; with routes for &lt;code&gt;/&lt;/code&gt;, &lt;code&gt;/health&lt;/code&gt;, &lt;code&gt;/info&lt;/code&gt;, &lt;code&gt;/metrics&lt;/code&gt;, and graceful shutdown logic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Creates file&lt;/span&gt;

&lt;span class="nb"&gt;touch &lt;/span&gt;app.js

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

&lt;/div&gt;



&lt;p&gt;Copy and paste this into &lt;code&gt;app.js&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;// core modules
const http &lt;span class="o"&gt;=&lt;/span&gt; require&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"http"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
const url &lt;span class="o"&gt;=&lt;/span&gt; require&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"url"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

// environment configuration
const PORT &lt;span class="o"&gt;=&lt;/span&gt; process.env.PORT &lt;span class="o"&gt;||&lt;/span&gt; 3000&lt;span class="p"&gt;;&lt;/span&gt;
const ENVIRONMENT &lt;span class="o"&gt;=&lt;/span&gt; process.env.NODE_ENV &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s2"&gt;"development"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nb"&gt;let &lt;/span&gt;requestCount &lt;span class="o"&gt;=&lt;/span&gt; 0&lt;span class="p"&gt;;&lt;/span&gt;

// helper: send JSON responses
&lt;span class="k"&gt;function &lt;/span&gt;sendJSON&lt;span class="o"&gt;(&lt;/span&gt;res, statusCode, data&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  res.statusCode &lt;span class="o"&gt;=&lt;/span&gt; statusCode&lt;span class="p"&gt;;&lt;/span&gt;
  res.setHeader&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Content-Type"&lt;/span&gt;, &lt;span class="s2"&gt;"application/json"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  res.end&lt;span class="o"&gt;(&lt;/span&gt;JSON.stringify&lt;span class="o"&gt;(&lt;/span&gt;data, null, 2&lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

// helper: send HTML responses
&lt;span class="k"&gt;function &lt;/span&gt;sendHTML&lt;span class="o"&gt;(&lt;/span&gt;res, statusCode, content&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  res.statusCode &lt;span class="o"&gt;=&lt;/span&gt; statusCode&lt;span class="p"&gt;;&lt;/span&gt;
  res.setHeader&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Content-Type"&lt;/span&gt;, &lt;span class="s2"&gt;"text/html"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  res.end&lt;span class="o"&gt;(&lt;/span&gt;content&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

// helper: send Prometheus metrics
&lt;span class="k"&gt;function &lt;/span&gt;sendMetrics&lt;span class="o"&gt;(&lt;/span&gt;res&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  const mem &lt;span class="o"&gt;=&lt;/span&gt; process.memoryUsage&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  const metrics &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sb"&gt;`&lt;/span&gt;
&lt;span class="c"&gt;# HELP http_requests_total Total HTTP requests&lt;/span&gt;
&lt;span class="c"&gt;# TYPE http_requests_total counter&lt;/span&gt;
http_requests_total &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;requestCount&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# HELP app_uptime_seconds Application uptime in seconds&lt;/span&gt;
&lt;span class="c"&gt;# TYPE app_uptime_seconds gauge&lt;/span&gt;
app_uptime_seconds &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.uptime()&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# HELP nodejs_memory_usage_bytes Node.js memory usage&lt;/span&gt;
&lt;span class="c"&gt;# TYPE nodejs_memory_usage_bytes gauge&lt;/span&gt;
nodejs_memory_usage_bytes&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"rss"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;.rss&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
nodejs_memory_usage_bytes&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"heapUsed"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;.heapUsed&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
nodejs_memory_usage_bytes&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"heapTotal"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;.heapTotal&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
nodejs_memory_usage_bytes&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"external"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;mem&lt;/span&gt;&lt;span class="p"&gt;.external&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  res.statusCode &lt;span class="o"&gt;=&lt;/span&gt; 200&lt;span class="p"&gt;;&lt;/span&gt;
  res.setHeader&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Content-Type"&lt;/span&gt;, &lt;span class="s2"&gt;"text/plain"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  res.end&lt;span class="o"&gt;(&lt;/span&gt;metrics&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

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

  // logging
  console.log&lt;span class="o"&gt;(&lt;/span&gt;
    &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;timestamp&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; - &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.method&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;pathname&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; - &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;
      req.headers[&lt;/span&gt;&lt;span class="s2"&gt;"user-agent"&lt;/span&gt;&lt;span class="p"&gt;] || &lt;/span&gt;&lt;span class="s2"&gt;"Unknown"&lt;/span&gt;&lt;span class="p"&gt;
    &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;
  &lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  // CORS headers
  res.setHeader&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Access-Control-Allow-Origin"&lt;/span&gt;, &lt;span class="s2"&gt;"*"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  res.setHeader&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Access-Control-Allow-Methods"&lt;/span&gt;, &lt;span class="s2"&gt;"GET, POST, PUT, DELETE"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  res.setHeader&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Access-Control-Allow-Headers"&lt;/span&gt;, &lt;span class="s2"&gt;"Content-Type"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  // security headers
  res.setHeader&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"X-Content-Type-Options"&lt;/span&gt;, &lt;span class="s2"&gt;"nosniff"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  res.setHeader&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"X-Frame-Options"&lt;/span&gt;, &lt;span class="s2"&gt;"DENY"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  res.setHeader&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"X-XSS-Protection"&lt;/span&gt;, &lt;span class="s2"&gt;"1; mode=block"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  // route handling
  switch &lt;span class="o"&gt;(&lt;/span&gt;pathname&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s2"&gt;"/"&lt;/span&gt;:
      sendHTML&lt;span class="o"&gt;(&lt;/span&gt;
        res,
        200,
        &lt;span class="sb"&gt;`&lt;/span&gt;
&amp;lt;&lt;span class="o"&gt;!&lt;/span&gt;DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;&lt;span class="nb"&gt;head&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &amp;lt;title&amp;gt;DevOps Lab 2025&amp;lt;/title&amp;gt;
  &amp;lt;style&amp;gt;
    body &lt;span class="o"&gt;{&lt;/span&gt; font-family: Arial, sans-serif&lt;span class="p"&gt;;&lt;/span&gt; max-width: 800px&lt;span class="p"&gt;;&lt;/span&gt; margin: 50px auto&lt;span class="p"&gt;;&lt;/span&gt; padding: 20px&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
    .header &lt;span class="o"&gt;{&lt;/span&gt; background: linear-gradient&lt;span class="o"&gt;(&lt;/span&gt;135deg, &lt;span class="c"&gt;#667eea 0%, #764ba2 100%); color: white; padding: 20px; border-radius: 8px; }&lt;/span&gt;
    .endpoint &lt;span class="o"&gt;{&lt;/span&gt; background: &lt;span class="c"&gt;#f8f9fa; padding: 15px; margin: 10px 0; border-radius: 5px; border-left: 4px solid #007bff; }&lt;/span&gt;
  &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
  &amp;lt;div &lt;span class="nv"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"header"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &amp;lt;h1&amp;gt;Fullstack 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;p&amp;gt;Version: 1.0.0&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 &lt;span class="nv"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"endpoint"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;lt;strong&amp;gt;GET /&amp;lt;/strong&amp;gt; - This welcome page&amp;lt;/div&amp;gt;
  &amp;lt;div &lt;span class="nv"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"endpoint"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;lt;strong&amp;gt;GET /health&amp;lt;/strong&amp;gt; - Health check &lt;span class="o"&gt;(&lt;/span&gt;JSON&lt;span class="o"&gt;)&lt;/span&gt;&amp;lt;/div&amp;gt;
  &amp;lt;div &lt;span class="nv"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"endpoint"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;lt;strong&amp;gt;GET /info&amp;lt;/strong&amp;gt; - System information&amp;lt;/div&amp;gt;
  &amp;lt;div &lt;span class="nv"&gt;class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"endpoint"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&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;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ENVIRONMENT&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;
  &amp;lt;p&amp;gt;Server &lt;span class="nb"&gt;time&lt;/span&gt;: &amp;lt;strong&amp;gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;timestamp&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;
  &amp;lt;p&amp;gt;Requests served: &amp;lt;strong&amp;gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;requestCount&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;&lt;span class="sb"&gt;`&lt;/span&gt;
      &lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nb"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s2"&gt;"/health"&lt;/span&gt;:
      sendJSON&lt;span class="o"&gt;(&lt;/span&gt;res, 200, &lt;span class="o"&gt;{&lt;/span&gt;
        status: &lt;span class="s2"&gt;"healthy"&lt;/span&gt;,
        timestamp,
        &lt;span class="nb"&gt;uptime&lt;/span&gt;: process.uptime&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;,
        environment: ENVIRONMENT,
        version: &lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;,
        node_version: process.version,
        requests_served: requestCount,
      &lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nb"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s2"&gt;"/info"&lt;/span&gt;:
      sendJSON&lt;span class="o"&gt;(&lt;/span&gt;res, 200, &lt;span class="o"&gt;{&lt;/span&gt;
        platform: process.platform,
        architecture: process.arch,
        node_version: process.version,
        memory_usage: process.memoryUsage&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;,
        environment: ENVIRONMENT,
        pid: process.pid,
        &lt;span class="nb"&gt;uptime&lt;/span&gt;: process.uptime&lt;span class="o"&gt;()&lt;/span&gt;,
      &lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nb"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s2"&gt;"/metrics"&lt;/span&gt;:
      sendMetrics&lt;span class="o"&gt;(&lt;/span&gt;res&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="nb"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    default:
      sendJSON&lt;span class="o"&gt;(&lt;/span&gt;res, 404, &lt;span class="o"&gt;{&lt;/span&gt;
        error: &lt;span class="s2"&gt;"Not Found"&lt;/span&gt;,
        message: &lt;span class="sb"&gt;`&lt;/span&gt;Route &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;pathname&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; not found&lt;span class="sb"&gt;`&lt;/span&gt;,
        timestamp,
      &lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

// graceful shutdown
&lt;span class="k"&gt;function &lt;/span&gt;shutdown&lt;span class="o"&gt;(&lt;/span&gt;signal&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  console.log&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;Received &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;signal&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;, shutting down gracefully...&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  server.close&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    console.log&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Server closed"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    process.exit&lt;span class="o"&gt;(&lt;/span&gt;0&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
process.on&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"SIGTERM"&lt;/span&gt;, &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; shutdown&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"SIGTERM"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
process.on&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"SIGINT"&lt;/span&gt;, &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; shutdown&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"SIGINT"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

// start server
server.listen&lt;span class="o"&gt;(&lt;/span&gt;PORT, &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  console.log&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;🚀 Server running at http://localhost:&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;PORT&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;/&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  console.log&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;Environment: &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ENVIRONMENT&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  console.log&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;Node.js version: &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.version&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

// &lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="k"&gt;for &lt;/span&gt;testing
module.exports &lt;span class="o"&gt;=&lt;/span&gt; server&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install testing and dev tools&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; jest eslint supertest

&lt;span class="c"&gt;# Install all dependencies&lt;/span&gt;

npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output of command in VScode terminal:&lt;/p&gt;

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

&lt;p&gt;Output of command in VScode terminal:&lt;/p&gt;

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




&lt;h2&gt;
  
  
  Step 3: Create Proper Tests
&lt;/h2&gt;

&lt;p&gt;We are going to setup an automated testing that verify the application works correctly everytime a change is made. &lt;/p&gt;

&lt;p&gt;Create a test directory and a test file &lt;code&gt;tests/app.test.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create a folder for your tests&lt;/span&gt;
&lt;span class="nb"&gt;mkdir &lt;/span&gt;tests

&lt;span class="c"&gt;# Create the main test file&lt;/span&gt;
&lt;span class="nb"&gt;touch &lt;/span&gt;tests/app.test.js

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

&lt;/div&gt;



&lt;p&gt;Output of command in VScode terminal:&lt;/p&gt;

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

&lt;p&gt;Copy and paste the code below into &lt;code&gt;tests/app.test.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
const request &lt;span class="o"&gt;=&lt;/span&gt; require&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'supertest'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
const server &lt;span class="o"&gt;=&lt;/span&gt; require&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'../app'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

describe&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'App Endpoints'&lt;/span&gt;, &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  afterAll&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    server.close&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

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

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

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

  &lt;span class="nb"&gt;test&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'GET /nonexistent should return 404'&lt;/span&gt;, async &lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    const response &lt;span class="o"&gt;=&lt;/span&gt; await request&lt;span class="o"&gt;(&lt;/span&gt;server&lt;span class="o"&gt;)&lt;/span&gt;.get&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/nonexistent'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    expect&lt;span class="o"&gt;(&lt;/span&gt;response.status&lt;span class="o"&gt;)&lt;/span&gt;.toBe&lt;span class="o"&gt;(&lt;/span&gt;404&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    expect&lt;span class="o"&gt;(&lt;/span&gt;response.body.error&lt;span class="o"&gt;)&lt;/span&gt;.toBe&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Not Found'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;})&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;



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

&lt;p&gt;Jest is a JavaScript testing framework developed by Facebook (now Meta). It’s widely used in Node.js and React projects for testing code.&lt;/p&gt;

&lt;p&gt;Create a &lt;code&gt;jest.config.js&lt;/code&gt; file in the root folder  for configuration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="nb"&gt;touch &lt;/span&gt;jest.config.js

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

&lt;/div&gt;



&lt;p&gt;Output of command in VScode terminal:&lt;/p&gt;

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

&lt;p&gt;Copy and paste the code below in the &lt;code&gt;jest.config.js&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
module.exports &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  testEnvironment: &lt;span class="s1"&gt;'node'&lt;/span&gt;,
  collectCoverage: &lt;span class="nb"&gt;true&lt;/span&gt;,
  coverageDirectory: &lt;span class="s1"&gt;'coverage'&lt;/span&gt;,
  testMatch: &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'**/tests/**/*.test.js'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;,
  verbose: &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

&lt;/div&gt;






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

&lt;p&gt;This creates an automated pipeline that runs tests and builds Docker images every time you push code to GitHub.&lt;/p&gt;

&lt;p&gt;Create &lt;code&gt;.github/workflows/ci.yml&lt;/code&gt; to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run tests and linting&lt;/li&gt;
&lt;li&gt;Build &amp;amp; push Docker images to GitHub Container Registry&lt;/li&gt;
&lt;li&gt;Run vulnerability scans&lt;/li&gt;
&lt;li&gt;Deploy to staging/production based on branch
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create the GitHub Actions directory structure&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; .github/workflows

&lt;span class="c"&gt;# Create a ci.yml in .github/workflows directory&lt;/span&gt;
&lt;span class="nb"&gt;touch&lt;/span&gt; .github/workflows/ci.yml

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

&lt;/div&gt;



&lt;p&gt;Output of command in VScode terminal:&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;name: CI Pipeline

on:
  push:
    branches: &lt;span class="o"&gt;[&lt;/span&gt; main, develop &lt;span class="o"&gt;]&lt;/span&gt;
  pull_request:
    branches: &lt;span class="o"&gt;[&lt;/span&gt; main &lt;span class="o"&gt;]&lt;/span&gt;

&lt;span class="nb"&gt;env&lt;/span&gt;:
  NODE_VERSION: &lt;span class="s1"&gt;'20'&lt;/span&gt;
  REGISTRY: ghcr.io
  IMAGE_NAME: &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;{ github.repository &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="nb"&gt;jobs&lt;/span&gt;:
  &lt;span class="nb"&gt;test&lt;/span&gt;:
    name: Run Tests
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: &lt;span class="o"&gt;[&lt;/span&gt;18, 20]

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

      - name: Setup Node.js &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;{ matrix.node-version &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
        uses: actions/setup-node@v4
        with:
          node-version: &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;{ matrix.node-version &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
          cache: &lt;span class="s1"&gt;'npm'&lt;/span&gt;

      - name: Install dependencies
        run: npm ci

      - name: Run linting
        run: npx eslint &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;--ext&lt;/span&gt; .js &lt;span class="nt"&gt;--ignore-pattern&lt;/span&gt; node_modules/
        &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="nt"&gt;-on-error&lt;/span&gt;: &lt;span class="nb"&gt;true&lt;/span&gt;

      - name: Run tests
        run: npm &lt;span class="nb"&gt;test&lt;/span&gt;

      - name: Run security audit
        run: npm audit &lt;span class="nt"&gt;--audit-level&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;moderate &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;true

  &lt;/span&gt;build:
    name: Build Docker Image
    runs-on: ubuntu-latest
    needs: &lt;span class="nb"&gt;test
    &lt;/span&gt;&lt;span class="k"&gt;if&lt;/span&gt;: github.event_name &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'push'&lt;/span&gt;

    permissions:
      contents: &lt;span class="nb"&gt;read
      &lt;/span&gt;packages: write

    outputs:
      image-digest: &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;{ steps.build.outputs.digest &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
      image-tag: &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;{ steps.meta.outputs.tags &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;

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

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Log &lt;span class="k"&gt;in &lt;/span&gt;to Container Registry
        uses: docker/login-action@v3
        with:
          registry: &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;{ env.REGISTRY &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
          username: &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;{ github.actor &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
          password: &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;{ secrets.GITHUB_TOKEN &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;

      - name: Extract metadata
        &lt;span class="nb"&gt;id&lt;/span&gt;: meta
        uses: docker/metadata-action@v5
        with:
          images: &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;{ env.REGISTRY &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;/&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;{ env.IMAGE_NAME &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
          tags: |
            &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ref,event&lt;span class="o"&gt;=&lt;/span&gt;branch
            &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;sha,prefix&lt;span class="o"&gt;={{&lt;/span&gt;branch&lt;span class="o"&gt;}}&lt;/span&gt;-
            &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;raw,value&lt;span class="o"&gt;=&lt;/span&gt;latest,enable&lt;span class="o"&gt;={{&lt;/span&gt;is_default_branch&lt;span class="o"&gt;}}&lt;/span&gt;

      - name: Build and push Docker image
        &lt;span class="nb"&gt;id&lt;/span&gt;: build
        uses: docker/build-push-action@v5
        with:
          context: &lt;span class="nb"&gt;.&lt;/span&gt;
          platforms: linux/amd64,linux/arm64
          push: &lt;span class="nb"&gt;true
          &lt;/span&gt;tags: &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;{ steps.meta.outputs.tags &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
          labels: &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;{ steps.meta.outputs.labels &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
          cache-from: &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;gha
          cache-to: &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;gha,mode&lt;span class="o"&gt;=&lt;/span&gt;max

  deploy-staging:
    name: Deploy to Staging
    runs-on: ubuntu-latest
    needs: build
    &lt;span class="k"&gt;if&lt;/span&gt;: github.ref &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'refs/heads/develop'&lt;/span&gt;
    environment: staging

    steps:
      - name: Deploy to staging
        run: |
          &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"🚀 Deploying to staging environment..."&lt;/span&gt;
          &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Image: &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;{ needs.build.outputs.image-tag &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;}"&lt;/span&gt;
          &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Would deploy to staging server here"&lt;/span&gt;
          &lt;span class="c"&gt;# In real scenario, you'd use:&lt;/span&gt;
          &lt;span class="c"&gt;# - kubectl apply -f k8s/staging/&lt;/span&gt;
          &lt;span class="c"&gt;# - docker-compose -f docker-compose.staging.yml up -d&lt;/span&gt;
          &lt;span class="c"&gt;# - ssh staging-server "docker pull $IMAGE &amp;amp;&amp;amp; docker-compose up -d"&lt;/span&gt;

  deploy-production:
    name: Deploy to Production
    runs-on: ubuntu-latest
    needs: build
    &lt;span class="k"&gt;if&lt;/span&gt;: github.ref &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'refs/heads/main'&lt;/span&gt;
    environment: production

    steps:
      - name: Deploy to production
        run: |
          &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"🎯 Deploying to production environment..."&lt;/span&gt;
          &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Image: &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;{ needs.build.outputs.image-tag &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;}"&lt;/span&gt;
          &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Image digest: &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;{ needs.build.outputs.image-digest &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;}"&lt;/span&gt;
          &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Would deploy to production server here"&lt;/span&gt;
          &lt;span class="c"&gt;# In real scenario, you'd use:&lt;/span&gt;
          &lt;span class="c"&gt;# - kubectl apply -f k8s/production/&lt;/span&gt;
          &lt;span class="c"&gt;# - terraform apply&lt;/span&gt;
          &lt;span class="c"&gt;# - ansible-playbook deploy.yml&lt;/span&gt;

  security-scan:
    name: Security Scan
    runs-on: ubuntu-latest
    needs: build
    &lt;span class="k"&gt;if&lt;/span&gt;: github.event_name &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'push'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; github.ref &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'refs/heads/main'&lt;/span&gt;

    steps:
      - name: Run Trivy vulnerability scanner
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: &lt;span class="s1"&gt;'ghcr.io/YOU_GITHUB_USERNAME/my-devops-project:latest'&lt;/span&gt;  &lt;span class="c"&gt;#All in lower case.  &lt;/span&gt;
          format: &lt;span class="s1"&gt;'sarif'&lt;/span&gt;
          output: &lt;span class="s1"&gt;'trivy-results.sarif'&lt;/span&gt;
    &lt;span class="c"&gt;# env:&lt;/span&gt;
    &lt;span class="c"&gt;#   TRIVY_USERNAME: ${{ github.actor }}&lt;/span&gt;
    &lt;span class="c"&gt;#   TRIVY_PASSWORD: ${{ secrets.GITHUB_TOKEN }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: You'll need to replace &lt;code&gt;YOU_GITHUB_USERNAME&lt;/code&gt; with your &lt;strong&gt;GitHub username&lt;/strong&gt;.  &lt;/p&gt;




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

&lt;p&gt;This creates instructions for Docker to build a container image of your application that can run on any machine.&lt;/p&gt;

&lt;p&gt;Create a &lt;strong&gt;multi-stage Dockerfile&lt;/strong&gt; that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Installs dependencies&lt;/li&gt;
&lt;li&gt;Uses non-root user for security&lt;/li&gt;
&lt;li&gt;Adds health checks&lt;/li&gt;
&lt;li&gt;Exposes port 3000
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#Create a Dockerfile&lt;/span&gt;

&lt;span class="nb"&gt;touch &lt;/span&gt;Dockerfile

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

&lt;/div&gt;



&lt;p&gt;Copy and paste the codes below into &lt;code&gt;Dockerfile&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Multi-stage build for optimized image&lt;/span&gt;
FROM node:20-alpine AS dependencies

&lt;span class="c"&gt;# Update packages for security&lt;/span&gt;
RUN apk update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apk upgrade &lt;span class="nt"&gt;--no-cache&lt;/span&gt;

WORKDIR /app

&lt;span class="c"&gt;# Copy package files first for better caching&lt;/span&gt;
COPY package&lt;span class="k"&gt;*&lt;/span&gt;.json ./

&lt;span class="c"&gt;# Install only production dependencies&lt;/span&gt;
RUN npm ci &lt;span class="nt"&gt;--only&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm cache clean &lt;span class="nt"&gt;--force&lt;/span&gt;

&lt;span class="c"&gt;# Production stage  &lt;/span&gt;
FROM node:20-alpine AS production

&lt;span class="c"&gt;# Update packages and install necessary tools&lt;/span&gt;
RUN apk update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apk upgrade &lt;span class="nt"&gt;--no-cache&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    apk add &lt;span class="nt"&gt;--no-cache&lt;/span&gt; curl dumb-init &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /var/cache/apk/&lt;span class="k"&gt;*&lt;/span&gt;

&lt;span class="c"&gt;# Create non-root user with proper permissions&lt;/span&gt;
RUN addgroup &lt;span class="nt"&gt;-g&lt;/span&gt; 1001 &lt;span class="nt"&gt;-S&lt;/span&gt; nodejs &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    adduser &lt;span class="nt"&gt;-S&lt;/span&gt; nodeuser &lt;span class="nt"&gt;-u&lt;/span&gt; 1001 &lt;span class="nt"&gt;-G&lt;/span&gt; nodejs

WORKDIR /app

&lt;span class="c"&gt;# Copy dependencies from previous stage with proper ownership&lt;/span&gt;
COPY &lt;span class="nt"&gt;--from&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;dependencies &lt;span class="nt"&gt;--chown&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;nodeuser:nodejs /app/node_modules ./node_modules

&lt;span class="c"&gt;# Copy application code with proper ownership&lt;/span&gt;
COPY &lt;span class="nt"&gt;--chown&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;nodeuser:nodejs package&lt;span class="k"&gt;*&lt;/span&gt;.json ./
COPY &lt;span class="nt"&gt;--chown&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;nodeuser:nodejs app.js ./

&lt;span class="c"&gt;# Switch to non-root user&lt;/span&gt;
USER nodeuser

&lt;span class="c"&gt;# Expose port&lt;/span&gt;
EXPOSE 3000

&lt;span class="c"&gt;# Health check with proper timing for Node.js startup&lt;/span&gt;
HEALTHCHECK &lt;span class="nt"&gt;--interval&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;30s &lt;span class="nt"&gt;--timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;10s &lt;span class="nt"&gt;--start-period&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;15s &lt;span class="nt"&gt;--retries&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3 &lt;span class="se"&gt;\&lt;/span&gt;
  CMD curl &lt;span class="nt"&gt;-f&lt;/span&gt; http://localhost:3000/health &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;exit &lt;/span&gt;1

&lt;span class="c"&gt;# Use dumb-init for proper signal handling in containers&lt;/span&gt;
ENTRYPOINT &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"dumb-init"&lt;/span&gt;, &lt;span class="s2"&gt;"--"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;

&lt;span class="c"&gt;# Start application&lt;/span&gt;
CMD &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"npm"&lt;/span&gt;, &lt;span class="s2"&gt;"start"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;

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

&lt;/div&gt;






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

&lt;p&gt;Lets 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 the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.dockerignore&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.gitignore&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.env.example&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.eslintrc.js&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Output of command in VScode terminal:&lt;/p&gt;

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

&lt;p&gt;Create &lt;code&gt;.dockerignore&lt;/code&gt;, copy and paste the code below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
node_modules 
npm-debug
.log&lt;span class="k"&gt;*&lt;/span&gt; 
.git 
.github 
.env 
.env.local 
.env.&lt;span class="k"&gt;*&lt;/span&gt;.local 
logs 
&lt;span class="k"&gt;*&lt;/span&gt;.log 
coverage 
.nyc_output 
.vscode 
.idea 
&lt;span class="k"&gt;*&lt;/span&gt;.swp 
&lt;span class="k"&gt;*&lt;/span&gt;.swo 
.DS_Store 
Thumbs.db 
README.md 
tests/ 
jest.config.js 
.eslintrc&lt;span class="k"&gt;*&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Create &lt;code&gt;.gitignore&lt;/code&gt;, copy and paste the code below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Dependencies&lt;/span&gt;
node_modules/
npm-debug.log&lt;span class="k"&gt;*&lt;/span&gt;

&lt;span class="c"&gt;# Runtime data&lt;/span&gt;
pids
&lt;span class="k"&gt;*&lt;/span&gt;.pid
&lt;span class="k"&gt;*&lt;/span&gt;.seed
&lt;span class="k"&gt;*&lt;/span&gt;.pid.lock

&lt;span class="c"&gt;# Coverage&lt;/span&gt;
coverage/
.nyc_output

&lt;span class="c"&gt;# Environment variables&lt;/span&gt;
.env
.env.local
.env.&lt;span class="k"&gt;*&lt;/span&gt;.local

&lt;span class="c"&gt;# Logs&lt;/span&gt;
logs
&lt;span class="k"&gt;*&lt;/span&gt;.log

&lt;span class="c"&gt;# IDE&lt;/span&gt;
.vscode/
.idea/
&lt;span class="k"&gt;*&lt;/span&gt;.swp
&lt;span class="k"&gt;*&lt;/span&gt;.swo

&lt;span class="c"&gt;# OS&lt;/span&gt;
.DS_Store
Thumbs.db

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

&lt;/div&gt;



&lt;p&gt;Create &lt;code&gt;.env.example&lt;/code&gt;, copy and paste the code below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="c"&gt;# Server &lt;/span&gt;
Configuration &lt;span class="nv"&gt;PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3000 
&lt;span class="nv"&gt;NODE_ENV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;production  
&lt;span class="c"&gt;# Logging &lt;/span&gt;
&lt;span class="nv"&gt;LOG_LEVEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;info

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

&lt;/div&gt;



&lt;p&gt;Create &lt;code&gt;.eslintrc.js&lt;/code&gt;, copy and paste the code below:&lt;br&gt;
&lt;/p&gt;

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

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

&lt;/div&gt;






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

&lt;p&gt;Now let's create a Docker Compose file that makes it easy to run your application and any supporting services with a single command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create a docker-compose.yml file &lt;/span&gt;

&lt;span class="nb"&gt;touch &lt;/span&gt;docker-compose.yml

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

&lt;/div&gt;



&lt;p&gt;Create &lt;code&gt;docker-compose.yml&lt;/code&gt; to run the app with, copy and paste the code below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;
&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3.8'&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3000:3000"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;NODE_ENV=development&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PORT=3000&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;healthcheck&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CMD"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;curl"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-f"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:3000/health"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;30s&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;10s&lt;/span&gt;
      &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
      &lt;span class="na"&gt;start_period&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;10s&lt;/span&gt;

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

&lt;/div&gt;






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

&lt;p&gt;This demonstrates how to run and test your application locally before deploying it.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Run your test suite to make sure everything works&lt;/span&gt;
npm &lt;span class="nb"&gt;test&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Output of command in VScode terminal:&lt;/p&gt;

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

&lt;p&gt;You should see all 5 tests pass 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%2F0odfug3jqi3jk8iar0ip.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0odfug3jqi3jk8iar0ip.png" alt="Image 14b" width="800" height="342"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This starts the app in your local environment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Start the application server&lt;/span&gt;
npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;Server starts running at &lt;a href="http://localhost:3000/" rel="noopener noreferrer"&gt;http://localhost:3000/&lt;/a&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%2Fp7ct39xopos2qicg51yg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp7ct39xopos2qicg51yg.png" alt="Image 15a" width="800" height="265"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Your browser should give this 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%2Fxsfd3vfx48rokncip0k2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxsfd3vfx48rokncip0k2.png" alt="Image 15b" width="800" height="492"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test endpoints (using terminal windows)&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;
---

curl http://localhost:3000/         # Homepage
curl http://localhost:3000/health   # Health check JSON
curl http://localhost:3000/info     # System info JSON  
curl http://localhost:3000/metrics  # Prometheus metrics

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

&lt;/div&gt;






&lt;h2&gt;
  
  
  Docker Commands:
&lt;/h2&gt;

&lt;p&gt;Before running the Docker commands, ensure you've launched your Docker Desktop application. &lt;/p&gt;

&lt;p&gt;This command builds the Docker image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="c"&gt;# Build image&lt;/span&gt;
docker build &lt;span class="nt"&gt;-t&lt;/span&gt; my-devops-app:latest &lt;span class="nb"&gt;.&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Output of command in VScode terminal:&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%2Fo2cqgxg0g1goz7w2wpqm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo2cqgxg0g1goz7w2wpqm.png" alt="Image 16a" width="800" height="200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This shows the newly built container image &lt;strong&gt;my-devops-app:latest&lt;/strong&gt; in Docker Desktop:&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Run container&lt;/span&gt;

docker run  &lt;span class="nt"&gt;--name&lt;/span&gt; my-devops-container &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; 3000:3000 &lt;span class="nt"&gt;--restart&lt;/span&gt; unless-stopped my-devops-app:latest

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

&lt;/div&gt;



&lt;p&gt;Output of command in VScode terminal:&lt;/p&gt;

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

&lt;p&gt;This shows the running container &lt;strong&gt;(my-devops-container)&lt;/strong&gt; on Docker Desktop: &lt;/p&gt;

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

&lt;p&gt;From your browser (&lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;), you should see this:  &lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check container status&lt;/span&gt;
docker ps

&lt;span class="c"&gt;# Test health check in terminal&lt;/span&gt;
curl http://localhost:3000/health

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

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Stop container&lt;/span&gt;

docker stop my-devops-container

&lt;span class="c"&gt;# Delete Container&lt;/span&gt;
docker &lt;span class="nb"&gt;rm &lt;/span&gt;my-devops-container

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

&lt;/div&gt;



&lt;p&gt;Output of command in VScode terminal:&lt;/p&gt;

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




&lt;h2&gt;
  
  
  Docker Compose Commands
&lt;/h2&gt;

&lt;p&gt;Run with Docker Compose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="c"&gt;# Start all services defined in docker-compose.yml&lt;/span&gt;
docker-compose up &lt;span class="nt"&gt;-d&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Output of command in VScode terminal:&lt;/p&gt;

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

&lt;p&gt;After running the above syntax, it also runs the application and  displays it in the browser via &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Stop all services and clean up&lt;/span&gt;
docker-compose down

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

&lt;/div&gt;



&lt;p&gt;Output of command in VScode terminal:&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%2Fy510j3p13kcwoaa763gv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy510j3p13kcwoaa763gv.png" alt="Image 20" width="800" height="186"&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Step 9: Deploy to GitHub
&lt;/h2&gt;

&lt;p&gt;We'll now commit the code and push it to GitHub, allowing the automated CI pipeline to begin processing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
 &lt;span class="c"&gt;# Add all files to Git staging area&lt;/span&gt;
git add &lt;span class="nb"&gt;.&lt;/span&gt;

&lt;span class="c"&gt;# Create your first commit with a descriptive message&lt;/span&gt;

git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Initial commit: Complete DevOps setup with working CI"&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Output of command in VScode terminal:&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;IMPORTANT&lt;/strong&gt;: Before running these commands:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to GitHub.com and create a new repository, give it a name of your choice. I called mine &lt;strong&gt;"my-devops-project"&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DO NOT&lt;/strong&gt; 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 &lt;strong&gt;YOUR_GITHUB_USERNAME&lt;/strong&gt; below with your actual GitHub username
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="c"&gt;# Set main as the default branch&lt;/span&gt;
git branch &lt;span class="nt"&gt;-M&lt;/span&gt; main

&lt;span class="c"&gt;# Connect to your GitHub repository (UPDATE THIS URL!)&lt;/span&gt;
git remote add origin https://github.com/YOUR_GITHUB_USERNAME/my-devops-project.git

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

&lt;/div&gt;



&lt;p&gt;Output of command in VScode terminal:&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="c"&gt;# Push your code to GitHub for the first time&lt;/span&gt;
git push &lt;span class="nt"&gt;-u&lt;/span&gt; origin main

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

&lt;/div&gt;



&lt;p&gt;Output of command in VScode terminal:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv2a2r5ripe57kiv10lqs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv2a2r5ripe57kiv10lqs.png" alt="Image 24" width="800" height="248"&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%2Fs7323ymyyg6toqf0k2vh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs7323ymyyg6toqf0k2vh.png" alt="Image 25" width="800" height="523"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 10: Deploy to Azure Web Apps via Azure Portal
&lt;/h2&gt;

&lt;p&gt;We’ve built our Node.js app, containerized it with Docker, and set up GitHub Actions for CI/CD. Now it’s time to take it live by deploying to Azure Web Apps, a fully managed Platform-as-a-Service (PaaS) that runs your app in the cloud without you managing servers or clusters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why Azure Web Apps?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Zero server management → Microsoft handles scaling, updates, and runtime.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;CI/CD ready → GitHub Actions can publish new versions automatically.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Scalable → Apps scale up or out based on load.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Secure &amp;amp; monitored → Logs, metrics, and diagnostics included by default.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Steps in the Azure Portal&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Log in to Azure Portal&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Go to &lt;a href="https://portal.azure.com" rel="noopener noreferrer"&gt;Azure Portal&lt;/a&gt; and sign in with your Azure account.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Create a Resource Group&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In the left-hand menu, search for Resource Groups.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click Create → provide a name (e.g., my-devops-app-rg) and select a region (preferably one close to you).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Create an App Service&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;From the menu, search for App Services → click Create and select web app.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Resource Group: my-devops-app-rg&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;App Name: my-devops-lab-app (must be unique)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Publish: Code&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Operating System: Linux&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Region: Choose the same as your resource group&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pricing Plan: Start with B1 (Basic) for testing&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%2Fc6rqny8fnv6tb3yu5y5n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc6rqny8fnv6tb3yu5y5n.png" alt="Image 34" width="800" height="805"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Configure Deployment&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In the Deployment tab, enable:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Option: Continuous deployment&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select Authorize and connect your GitHub account with the Azure App Service to enable access to your repository.&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%2F585wqcyq3d5w8km2hpr2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F585wqcyq3d5w8km2hpr2.png" alt="Image 38" width="800" height="487"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select the following details: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Organization: your GitHub account username&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Repository: your repository name&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Branch: your branch main (e.g main or master)&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%2F8uf62nwe8zn9ayh45nss.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8uf62nwe8zn9ayh45nss.png" alt="Image 39" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Review + Create&lt;/p&gt;

&lt;p&gt;Click Review + Create and wait for Azure to provision the service.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;CI/CD Integration from Portal&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Azure Portal can automatically create a GitHub Actions workflow for you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Azure will generate a workflow file in .github/workflows/&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This workflow builds your app and redeploys automatically whenever you push to GitHub&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Select &lt;strong&gt;Actions&lt;/strong&gt; to see the pipeline running:&lt;/p&gt;

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

&lt;p&gt;Below depicts the &lt;strong&gt;Continuous Integration (CI)&lt;/strong&gt; pipeline phase: &lt;/p&gt;

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

&lt;p&gt;This depicts the &lt;strong&gt;Continuous Deployment (CD)&lt;/strong&gt; pipeline phase:&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Access Your App&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This indicates our web app service has been successfully deployed. Select &lt;strong&gt;Go to Resource&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%2F27bro68cgwo5hl52vh8k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F27bro68cgwo5hl52vh8k.png" alt="Image 42" width="800" height="370"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Select &lt;strong&gt;Browse&lt;/strong&gt; to access the application in your browser&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%2Fb6kewu1ufrlv7zoukg0e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb6kewu1ufrlv7zoukg0e.png" alt="Image 44" width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the application live in the 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%2Fjmy3i5dlqq3284o5sz5q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjmy3i5dlqq3284o5sz5q.png" alt="Image 43" width="800" height="531"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;You just built a complete &lt;strong&gt;CI/CD pipeline&lt;/strong&gt; for a Node.js application:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automated builds &amp;amp; tests with &lt;strong&gt;GitHub Actions&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Containerization with &lt;strong&gt;Docker&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Local orchestration with &lt;strong&gt;Docker Compose&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Cloud hosting on &lt;strong&gt;Azure Web Apps&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This workflow eliminates manual deployments, ensures code quality, and makes your app production-ready. 🚀&lt;/p&gt;

</description>
      <category>node</category>
      <category>cicd</category>
      <category>githubactions</category>
      <category>azure</category>
    </item>
    <item>
      <title>How to Deploy a Windows Server 2022 Domain Controller with VirtualBox Manager</title>
      <dc:creator>Ibrahim Bio Abubakar</dc:creator>
      <pubDate>Thu, 10 Jul 2025 16:54:49 +0000</pubDate>
      <link>https://dev.to/ibrahimbioabu/how-to-deploy-a-windows-server-2022-domain-controller-with-virtualbox-manager-5dpn</link>
      <guid>https://dev.to/ibrahimbioabu/how-to-deploy-a-windows-server-2022-domain-controller-with-virtualbox-manager-5dpn</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In this lab exercise, we will use &lt;a href="https://www.virtualbox.org/wiki/Downloads" rel="noopener noreferrer"&gt;VirtualBox&lt;/a&gt; Manager as our virtualization tool. It is one of the many available virtualization platforms.&lt;/p&gt;

&lt;p&gt;A Windows Server Domain Controller is a server that runs a Windows Server operating system and is responsible for managing &lt;strong&gt;security and access to resources&lt;/strong&gt; within a Windows domain.&lt;/p&gt;

&lt;p&gt;Key functions of a Domain Controller include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Authentication&lt;/strong&gt;: Validates users’ usernames and passwords when they log in.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authorization&lt;/strong&gt;: Controls what users can access (files, folders, applications).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Centralized Management&lt;/strong&gt;: Enables administrators to manage users, computers, and policies in one place.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Active Directory (AD)&lt;/strong&gt;: Stores and organizes information about network resources (users, groups, computers, etc.).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Group Policy Management&lt;/strong&gt;: Enforces settings and restrictions across users and computers in the domain.&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;Ensure the following before starting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your computer (Windows or macOS) has at least &lt;strong&gt;16 GB of RAM&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.virtualbox.org/wiki/Downloads" rel="noopener noreferrer"&gt;VirtualBox&lt;/a&gt; is downloaded and installed.&lt;/li&gt;
&lt;li&gt;The ISO for &lt;a href="https://www.microsoft.com/en-us/evalcenter/evaluate-windows-server-2022" rel="noopener noreferrer"&gt;Windows Server 2022&lt;/a&gt; is downloaded.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 1: Launch and Mount Windows Server 2022 in VirtualBox Manager
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Click &lt;strong&gt;New&lt;/strong&gt; to create and configure your virtual machine (VM).&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%2Fvc5ke7jt9b4l8h81d2ax.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvc5ke7jt9b4l8h81d2ax.png" alt="Image1" width="800" height="529"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enter a unique name for your Windows Server. I used “Server” for this lab.&lt;/li&gt;
&lt;li&gt;For the ISO image, browse your computer and select the downloaded Windows Server 2022 ISO file: &lt;strong&gt;SERVER_EVAL_x64FRE_en-us.iso&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Skip Unattended Installation&lt;/strong&gt; to manually configure the VM’s settings, including hardware specifications and OS installation details.&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%2Fiq09spoi4n1cfd1x8ycy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiq09spoi4n1cfd1x8ycy.png" alt="Image2" width="800" height="316"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Expand the &lt;strong&gt;Hardware&lt;/strong&gt; dropdown, increase the &lt;strong&gt;Base Memory&lt;/strong&gt; to at least &lt;strong&gt;4096 MB&lt;/strong&gt;, and set the &lt;strong&gt;Processor&lt;/strong&gt; to &lt;strong&gt;2 CPUs&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%2Ftvjfp5pjwcuej45nb1tc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftvjfp5pjwcuej45nb1tc.png" alt="Image3" width="800" height="243"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Leave the &lt;strong&gt;Hard Disk&lt;/strong&gt; at the default size of &lt;strong&gt;50 GB&lt;/strong&gt;. Then select &lt;strong&gt;Finish&lt;/strong&gt; to add the VM to the VirtualBox Manager.&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%2F0552rto38ezsln0e8sye.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0552rto38ezsln0e8sye.png" alt="Image4" width="800" height="317"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The newly created VM ("Server") should now appear in the VirtualBox interface.&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%2Fz6tp2nwhc60as1i4umj7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz6tp2nwhc60as1i4umj7.png" alt="Image4" width="800" height="514"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: Launch and Configure the Windows Server 2022 Virtual Machine
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Ensure the &lt;strong&gt;Server&lt;/strong&gt; VM is selected, then click &lt;strong&gt;Start&lt;/strong&gt; in VirtualBox Manager.&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%2Fbd1a3v6xdk8qbtxtyjwp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbd1a3v6xdk8qbtxtyjwp.png" alt="Image4" width="800" height="521"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select &lt;strong&gt;Next&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%2Fjyg3rf5gw9y0u1cgmuhg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjyg3rf5gw9y0u1cgmuhg.png" alt="Image5" width="800" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click &lt;strong&gt;Install now&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%2F7kaeh0g7394n58gmq3qu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7kaeh0g7394n58gmq3qu.png" alt="Image6" width="800" height="588"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Choose &lt;strong&gt;Windows Server 2022 Standard Evaluation (Desktop Experience)&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Accept the Microsoft Software License Terms and click &lt;strong&gt;Next&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%2Fwp9d5g6ys8w1j5uohiyp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwp9d5g6ys8w1j5uohiyp.png" alt="Image6" width="800" height="557"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select &lt;strong&gt;Custom: Install Microsoft Server Operating System&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%2Fs3h1090rjur8sudmoqe3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs3h1090rjur8sudmoqe3.png" alt="Image7" width="800" height="561"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click &lt;strong&gt;Next&lt;/strong&gt; to install.&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%2Fhx1rgdesu9jkk7yvqdet.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhx1rgdesu9jkk7yvqdet.png" alt="Image8" width="800" height="574"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The installation will begin. Wait until it completes.&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%2Fveoib34l2zuuks9948g3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fveoib34l2zuuks9948g3.png" alt="Image9" width="800" height="593"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a password for the &lt;strong&gt;Administrator&lt;/strong&gt; account and click &lt;strong&gt;Finish&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%2Fh87xp1ro83cma7qm2g7y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh87xp1ro83cma7qm2g7y.png" alt="Image10" width="800" height="527"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Well done! Windows Server 2022 is now successfully installed and ready for use.&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%2Fuqqwzu5bxvncup04rzxw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuqqwzu5bxvncup04rzxw.png" alt="Image11" width="800" height="554"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Rename the PC (Recommended)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Right-click the Windows Menu and select &lt;strong&gt;Settings&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%2Fdhx9pi25ua3uuf6i9pg4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdhx9pi25ua3uuf6i9pg4.png" alt="ImageA" width="800" height="711"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click &lt;strong&gt;Rename this PC&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%2Fr8wiq8wqj1bfl7wtrh8k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr8wiq8wqj1bfl7wtrh8k.png" alt="ImageA" width="800" height="631"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Enter the same name you used earlier in VirtualBox (e.g., &lt;em&gt;Server&lt;/em&gt;), then click &lt;strong&gt;Next&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%2F44b25iemtimha2q5znfo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F44b25iemtimha2q5znfo.png" alt="ImageB" width="800" height="552"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click &lt;strong&gt;Restart now&lt;/strong&gt; to apply the changes.&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%2Fxtahfp5k3usxy5f12h0o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxtahfp5k3usxy5f12h0o.png" alt="ImageC" width="800" height="515"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: Create a Domain Controller Using Server Manager
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;When the VM starts, Server Manager should open automatically.&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%2Fcifzs3owjsycmqlewc24.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcifzs3owjsycmqlewc24.png" alt="Image12" width="800" height="640"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If not, click the &lt;strong&gt;Windows Menu&lt;/strong&gt;, search for "Server Manager," and launch it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;In Server Manager, select &lt;strong&gt;Manage&lt;/strong&gt; &amp;gt; &lt;strong&gt;Add Roles and Features&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%2Fme3c7tqs76kc8vi0qytm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fme3c7tqs76kc8vi0qytm.png" alt="Image13" width="800" height="568"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On the &lt;strong&gt;Before You Begin&lt;/strong&gt; page, click &lt;strong&gt;Next&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%2Frjltjkxb2jzv42up7cyj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frjltjkxb2jzv42up7cyj.png" alt="Image14" width="800" height="573"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On the &lt;strong&gt;Installation Type&lt;/strong&gt; page, select &lt;strong&gt;Role-based or feature-based installation&lt;/strong&gt;, then click &lt;strong&gt;Next&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%2Fr2gb9avxobqcsqihuxca.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr2gb9avxobqcsqihuxca.png" alt="Image15" width="800" height="584"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On the &lt;strong&gt;Destination Server&lt;/strong&gt; page, ensure your server is selected, then click &lt;strong&gt;Next&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%2Fkcrhgletf79pdz8bqcbp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkcrhgletf79pdz8bqcbp.png" alt="Image16" width="800" height="557"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On the &lt;strong&gt;Server Roles&lt;/strong&gt; page, check &lt;strong&gt;Active Directory Domain Services&lt;/strong&gt;. A pop-up will appear.&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%2Fpoibiqkg3tbxrt3richr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpoibiqkg3tbxrt3richr.png" alt="Image17" width="800" height="555"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click &lt;strong&gt;Add Features&lt;/strong&gt;, then &lt;strong&gt;Next&lt;/strong&gt; through the next few steps.&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%2Fog74dkz0l2f0kfyozth0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fog74dkz0l2f0kfyozth0.png" alt="Image18" width="800" height="552"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On the &lt;strong&gt;Confirmation&lt;/strong&gt; page, click &lt;strong&gt;Install&lt;/strong&gt;. Installation may take a few minutes.&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%2Fzs5w0iezf72oj54v70u7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzs5w0iezf72oj54v70u7.png" alt="Image19" width="800" height="556"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Once completed, click the notification flag icon in Server Manager and select &lt;strong&gt;Promote this server to a domain controller&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%2Fq7ejga387hcf3ubw8ttx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq7ejga387hcf3ubw8ttx.png" alt="Image20" width="579" height="214"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe5he0qd0giv1q33u5fwj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe5he0qd0giv1q33u5fwj.png" alt="Image21" width="800" height="521"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On the &lt;strong&gt;Deployment Configuration&lt;/strong&gt; page, choose &lt;strong&gt;Add a new forest&lt;/strong&gt;, and enter a root domain name (e.g., &lt;code&gt;koraconsult.com&lt;/code&gt;), then click &lt;strong&gt;Next&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%2F6e2pxpqa35esg5tn7ns2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6e2pxpqa35esg5tn7ns2.png" alt="Imagq" width="800" height="562"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;On the &lt;strong&gt;Domain Controller Options&lt;/strong&gt; page, accept the defaults and set a &lt;strong&gt;DSRM password&lt;/strong&gt; (used for recovery). Click &lt;strong&gt;Next&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%2Fxejw5psiljjx2bzb1c83.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxejw5psiljjx2bzb1c83.png" alt="Image22" width="800" height="580"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Proceed through the &lt;strong&gt;DNS Options&lt;/strong&gt;, &lt;strong&gt;Additional Options&lt;/strong&gt;, &lt;strong&gt;Paths&lt;/strong&gt;, and &lt;strong&gt;Review Options&lt;/strong&gt; pages by clicking &lt;strong&gt;Next&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;On the &lt;strong&gt;Prerequisites Check&lt;/strong&gt; page, click &lt;strong&gt;Install&lt;/strong&gt;. This process may take several minutes and the VM will restart when done.&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%2Fhh96vjnnys1v97u4y83x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhh96vjnnys1v97u4y83x.png" alt="Image23" width="800" height="594"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After restarting, log in using your domain credentials, e.g., &lt;code&gt;KORACONSULT\Administrator&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%2Fbylvv9jz8tfyszn80eae.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbylvv9jz8tfyszn80eae.png" alt="Image24" width="800" height="557"&gt;&lt;/a&gt;&lt;/p&gt;




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

&lt;p&gt;You've successfully configured a Windows Server 2022 virtual machine and promoted it to a Domain Controller using VirtualBox—all from scratch. This hands-on lab not only strengthens your virtualization skills but also lays the foundation for deeper exploration into Active Directory, Group Policies, and enterprise IT environments.&lt;/p&gt;

&lt;p&gt;Keep experimenting—and remember to &lt;strong&gt;snapshot your VM&lt;/strong&gt; before making major changes. Happy virtualizing!&lt;/p&gt;

</description>
      <category>windowsserver</category>
      <category>networking</category>
      <category>infosec</category>
      <category>devops</category>
    </item>
    <item>
      <title>How to Set Up Hyper-V for a Windows Server Environment: A Series on Active Directory Domain Services</title>
      <dc:creator>Ibrahim Bio Abubakar</dc:creator>
      <pubDate>Wed, 11 Jun 2025 15:26:12 +0000</pubDate>
      <link>https://dev.to/ibrahimbioabu/how-to-set-up-hyper-v-for-a-windows-server-environment-a-series-on-active-directory-domain-services-4glo</link>
      <guid>https://dev.to/ibrahimbioabu/how-to-set-up-hyper-v-for-a-windows-server-environment-a-series-on-active-directory-domain-services-4glo</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Virtualization is a powerful tool that enables developers, IT professionals, and enthusiasts to run multiple operating systems on a single machine. Windows 11 comes with a native virtualization platform called Hyper-V, which is free, robust, and easy to set up — if you know where to look.&lt;/p&gt;

&lt;p&gt;In this guide, I'll walk you through setting up Hyper-V on Windows 11 in a step-by-step manner. Whether you’re looking to test a Linux distro, experiment with Windows Server, or sandbox a dev environment, this post is for you.&lt;/p&gt;




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

&lt;p&gt;Before we dive in, make sure your system meets the following requirements:&lt;/p&gt;

&lt;p&gt;✅ Windows 11 Pro, Enterprise, or Education&lt;br&gt;
❌ Hyper-V is not available on Windows 11 Home (but there’s a workaround—see the bonus section below)&lt;/p&gt;

&lt;p&gt;✅ CPU with virtualization support (Intel VT-x or AMD-V)&lt;br&gt;
✅ At least 8 GB of RAM (16 GB recommended)&lt;/p&gt;



&lt;p&gt;The following steps serve as a guide to install Hyper-V on a Windows 11 Computer, where we shall install Hyper-V and configure a NAT Switch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1&lt;/strong&gt;: Sign in to the Windows 11 computer with an account that has local Administrator privileges.&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt; On the Windows 11 Computer click &lt;strong&gt;Start&lt;/strong&gt;, select &lt;strong&gt;Settings&lt;/strong&gt; and on the Settings page select &lt;strong&gt;System.&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%2Fkjytucy8bsfxjeuijnw0.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkjytucy8bsfxjeuijnw0.jpeg" alt="System" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;Step 3&lt;/strong&gt;: On the System page of settings, scroll down until you locate Optional Features. Select &lt;strong&gt;Optional Features&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%2F7pmjako0zg9fsv8ogj7k.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7pmjako0zg9fsv8ogj7k.jpeg" alt="Optional features" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;Step 4&lt;/strong&gt;: On the Optional Features Page, you can find the &lt;strong&gt;More Windows Features&lt;/strong&gt; option at the top right corner under Related 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%2Fxba52co1hm1e3gdj52fp.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxba52co1hm1e3gdj52fp.jpeg" alt="More Windows Features" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;Step 5&lt;/strong&gt;: On the Windows Feature page, select the checkbox next to Hyper-V and click &lt;strong&gt;OK&lt;/strong&gt; as shown below.&lt;/p&gt;

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



&lt;p&gt;&lt;strong&gt;Step 6&lt;/strong&gt;: When the installation completes, on the Windows Features page, click &lt;strong&gt;Restart Now&lt;/strong&gt;.&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;Step 7&lt;/strong&gt;: After the computer restarts, sign in again using the same account that has local Administrative privileges.&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;Step 8&lt;/strong&gt; Click &lt;strong&gt;Start&lt;/strong&gt; and search for &lt;strong&gt;Hyper-V Manager&lt;/strong&gt;. Pin Hyper-V Manager to the Taskbar.&lt;/p&gt;

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



&lt;p&gt;&lt;strong&gt;Step 9&lt;/strong&gt;: Open Hyper-V Manager, right click on the local Computer, and select &lt;strong&gt;Hyper-V Settings&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%2Fnvqxewuq9fui32lup0pp.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnvqxewuq9fui32lup0pp.jpeg" alt="HVO" width="800" height="580"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;&lt;strong&gt;Step 10&lt;/strong&gt;: On the &lt;strong&gt;Hyper-V settings&lt;/strong&gt; dialog box, under Server, select &lt;strong&gt;Virtual Machines&lt;/strong&gt;. Set the location of the Virtual Machine to C:\VirtualMachines&lt;/p&gt;

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



&lt;p&gt;&lt;strong&gt;Step 11&lt;/strong&gt;: Under the Hyper-V settings dialog box, under Server, select &lt;strong&gt;Virtual Machine Hard Disks&lt;/strong&gt;. Set the location of the Virtual Machine Hard Disks to C:\VirtualMachines\VHDs. Click &lt;strong&gt;OK&lt;/strong&gt; to close the &lt;strong&gt;Hyper-V Settings&lt;/strong&gt; dialog box.&lt;/p&gt;

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



&lt;p&gt;&lt;strong&gt;Step 12&lt;/strong&gt;:  Open PowerShell with Administrator access and run the following commands to create a NAT Network.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;New-VMSwitch -SwitchName “NATSwitch” -SwitchType Internal
New-NetIPAddress -IPAddress 10.10.10.1 -PrefixLength 24 -InterfaceAlias “vEthernet (NATSwitch)”
New-NetNat -Name “NATNetwork” –InternalIPInterfaceAddressPrefix “10.10.10.0/24”

&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%2Flwg7yh4z4a6dpcp80ngd.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flwg7yh4z4a6dpcp80ngd.jpeg" alt="Image9" width="800" height="660"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Then close PowerShell.&lt;/p&gt;

&lt;p&gt;To continue this series on Active Directory Domain Services, my next post will be on &lt;em&gt;&lt;strong&gt;"How to Create Windows Domain Controller Virtual Machine"&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;




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

&lt;p&gt;Hyper-V turns your Windows 11 machine into a powerful lab for testing, developing, or safely running multiple OSes. While it might not have the most modern UI compared to VirtualBox or VMware Workstation, it’s tightly integrated into Windows and incredibly stable.&lt;/p&gt;

&lt;p&gt;Whether you’re building microservices, testing a new OS, or trying containers with Docker (which also uses Hyper-V behind the scenes), mastering Hyper-V is a valuable skill in your toolkit.&lt;/p&gt;

&lt;p&gt;Have questions or tips? Drop them in the comments below!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Create and Configure Virtual Networks Using Microsoft Azure</title>
      <dc:creator>Ibrahim Bio Abubakar</dc:creator>
      <pubDate>Mon, 19 May 2025 11:35:35 +0000</pubDate>
      <link>https://dev.to/ibrahimbioabu/how-to-create-and-configure-virtual-networks-in-microsoft-azure-13p9</link>
      <guid>https://dev.to/ibrahimbioabu/how-to-create-and-configure-virtual-networks-in-microsoft-azure-13p9</guid>
      <description>&lt;p&gt;This article on virtual networking (VN) is going to be shared in the form of a series, where we shall cover several hands-on exercises to appreciate the idea of virtual networks in Microsoft Azure.  &lt;/p&gt;

&lt;p&gt;This series will include the following exercises on: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;How to create and configure virtual networks (which we shall cover in this article).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to create and configure a network security group&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to create and configure Azure Firewall&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to configure network routing&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to create DNS Zones and configure DNS settings&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The steps applied in this article are from &lt;a href="https://microsoftlearning.github.io/Configure-secure-access-to-workloads-with-Azure-virtual-networking-services/Instructions/Labs/LAB_01_virtual_networks.html" rel="noopener noreferrer"&gt;Microsoft learn &lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's swing into action by learning how to create and configure virtual networks.&lt;/p&gt;

&lt;p&gt;Let's assume your organization is migrating a web-based application to Azure, and you've been tasked to put in place the virtual networks and subnets, followed by securely peering the virtual networks.&lt;/p&gt;

&lt;p&gt;Outline of Tasks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a virtual network.&lt;/li&gt;
&lt;li&gt;Create a subnet.&lt;/li&gt;
&lt;li&gt;Configure VNet peering.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 1.&lt;/strong&gt; Sign in to the &lt;a href="https://portal.azure.com" rel="noopener noreferrer"&gt;Azure Portal&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2.&lt;/strong&gt; Search for and select &lt;code&gt;virtual networks&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%2Fcxln723kg4p2rjinhagk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcxln723kg4p2rjinhagk.png" alt="Image - 1" width="800" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3.&lt;/strong&gt; Select &lt;strong&gt;+ Create&lt;/strong&gt; and complete the configuration of the VN&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Resource Group(RG)&lt;/strong&gt;: Create a resource with a name of your choice and ensure you select it. I'm using &lt;code&gt;DemoRG&lt;/code&gt; as my RG for this exercise.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Virtual network name&lt;/strong&gt;: enter &lt;code&gt;app-vnet&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Region&lt;/strong&gt;: Select a region closer to you in the drop-down menu. I'm using (Europe)UK South for mine. &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%2Fowbr6j3eqa2acu7vdk1c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fowbr6j3eqa2acu7vdk1c.png" alt="Image - 3" width="800" height="815"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4.&lt;/strong&gt; Select next to be at the &lt;strong&gt;IP Address&lt;/strong&gt; page, then select &lt;strong&gt;Add IPv4 address space&lt;/strong&gt;, and ensure the IP address range is configure to &lt;code&gt;10.1.0.0&lt;/code&gt; and the size is &lt;code&gt;16&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%2Fed51mk5dedpq6ho5ucj2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fed51mk5dedpq6ho5ucj2.png" alt="5" width="800" height="841"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Delete the &lt;code&gt;default address space&lt;/code&gt; as shown in step 2 above, then select &lt;strong&gt;Add a subnet&lt;/strong&gt; to create a subnet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5.&lt;/strong&gt; In the &lt;code&gt;Add a subnet&lt;/code&gt; page, enter the following details&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name&lt;/strong&gt;: &lt;code&gt;frontend&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IPv4 address range&lt;/strong&gt;: the one we added above (in step 4) from the drop-down menu  &lt;code&gt;10.1.0.0/16&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Starting address&lt;/strong&gt;: &lt;code&gt;10.1.0.0&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Size&lt;/strong&gt;: &lt;code&gt;24&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Select &lt;strong&gt;Add&lt;/strong&gt; to add the frontend subnet to our VN.&lt;/p&gt;

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

&lt;p&gt;We need to repeat the same process above to create another subnet called &lt;code&gt;backend&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;However, ensure the &lt;strong&gt;Starting address&lt;/strong&gt; is &lt;code&gt;10.1.1.0&lt;/code&gt; and the &lt;strong&gt;Size&lt;/strong&gt; is &lt;code&gt;24&lt;/code&gt; as shown below. Leave all other settings as default, then select &lt;strong&gt;Add&lt;/strong&gt; to add the backend subnet in the VN.  &lt;/p&gt;

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

&lt;p&gt;Now select &lt;strong&gt;Review + create&lt;/strong&gt; to create the &lt;code&gt;app-vnet&lt;/code&gt; virtual network.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Step 6.&lt;/strong&gt; We need to create another VN called &lt;code&gt;hub-vnet&lt;/code&gt;, which requires only a subnet for the firewall. &lt;/p&gt;

&lt;p&gt;We'll repeat the same process from &lt;strong&gt;Step 3&lt;/strong&gt; to create the second VN. &lt;/p&gt;

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

&lt;p&gt;However, at the &lt;strong&gt;IP address&lt;/strong&gt; page, use the default &lt;strong&gt;IPv4 address space&lt;/strong&gt; and proceed to &lt;strong&gt;add a subnet&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%2Fnfv80g37ncppy2x9ghou.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnfv80g37ncppy2x9ghou.png" alt="Image - 10" width="800" height="720"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the subnet, select &lt;code&gt;Azure Firewall&lt;/code&gt; as the &lt;strong&gt;Subnet purpose&lt;/strong&gt;, then ensure the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;IPv4 address range&lt;/strong&gt;: select the default address space with the range &lt;code&gt;10.0.0.0/16&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Starting address&lt;/strong&gt;: &lt;code&gt;10.0.1.0&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Size&lt;/strong&gt;: &lt;code&gt;26&lt;/code&gt; is selected by default.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Leave other configurations as default and select &lt;strong&gt;Add&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%2Fg5pczp3igu91ujya6ywe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg5pczp3igu91ujya6ywe.png" alt="Image - 11" width="800" height="1282"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next step is to select &lt;strong&gt;Review + create&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%2Fsmtqiqbsyblgckl23shn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsmtqiqbsyblgckl23shn.png" alt="Image 12" width="800" height="882"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 7.&lt;/strong&gt; Since our &lt;strong&gt;app-vnet&lt;/strong&gt; and &lt;strong&gt;hub-vnet&lt;/strong&gt; virtual networks are now ready with their respective configurations, we can peer them using the following steps.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Search for and select the &lt;code&gt;app-vnet&lt;/code&gt; virtual networks.&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Settings&lt;/strong&gt; blade, select &lt;strong&gt;Peerings&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;+ Add&lt;/strong&gt; a peering between the two virtual networks. 

&lt;ul&gt;
&lt;li&gt;Remote peering link name: &lt;code&gt;api-vnet-to-hub&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Select your subscription&lt;/li&gt;
&lt;li&gt;Virtual network: select &lt;code&gt;hub-vnet&lt;/code&gt; here.&lt;/li&gt;
&lt;li&gt;Local peering link name: use &lt;code&gt;hub-to-app-vnet&lt;/code&gt;. &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Leave other settings as their defaults. Select &lt;strong&gt;Add&lt;/strong&gt; to create the virtual network peering. &lt;/p&gt;

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

&lt;p&gt;Finally, once the deployment completes, verify the &lt;strong&gt;Peering status&lt;/strong&gt; is &lt;strong&gt;Connected&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%2Fr5ahbg8anzgvpvn8mxl4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fr5ahbg8anzgvpvn8mxl4.png" alt="Image - 14" width="800" height="315"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Congratulations, we've completed this phase of the virtual network series. The next exercise will be "creating and configuring network security groups". &lt;/p&gt;

</description>
    </item>
    <item>
      <title>A Step-by-Step Guid on How to Set Up and Deploy a LAMP Stack on a Linux Server</title>
      <dc:creator>Ibrahim Bio Abubakar</dc:creator>
      <pubDate>Sat, 29 Mar 2025 13:51:52 +0000</pubDate>
      <link>https://dev.to/ibrahimbioabu/a-step-by-step-guid-on-how-to-set-up-and-deploy-a-lamp-stack-on-a-linux-server-19jh</link>
      <guid>https://dev.to/ibrahimbioabu/a-step-by-step-guid-on-how-to-set-up-and-deploy-a-lamp-stack-on-a-linux-server-19jh</guid>
      <description>&lt;h1&gt;
  
  
  How to Deploy a LAMP Stack in Linux
&lt;/h1&gt;

&lt;p&gt;The LAMP stack (Linux, Apache, MySQL, PHP) is a popular open-source web development platform used to host dynamic websites and applications. This guide will walk you through setting up a LAMP stack on a Linux server.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;A Linux-based server (Ubuntu, Debian, CentOS, or any other Linux distribution)&lt;/li&gt;
&lt;li&gt;A user account with sudo privileges&lt;/li&gt;
&lt;li&gt;Basic knowledge of the Linux command line&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1: Update Your System
&lt;/h2&gt;

&lt;p&gt;Before installing any software, update the package repository to ensure you get the latest versions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;apt upgrade &lt;span class="nt"&gt;-y&lt;/span&gt;   &lt;span class="c"&gt;# For Uduntu/Debian-based systems&lt;/span&gt;

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

&lt;h2&gt;
  
  
  Step 2: Install Apache Web Server
&lt;/h2&gt;

&lt;p&gt;Apache is the most widely used web server for hosting websites.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install Apache
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;apache2 &lt;span class="nt"&gt;-y&lt;/span&gt;   &lt;span class="c"&gt;# Ubuntu/Debian&lt;/span&gt;
&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%2F4nnewurg3pa7qvokfu63.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4nnewurg3pa7qvokfu63.png" alt="apache2" width="800" height="355"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Start and Enable Apache
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start apache2   &lt;span class="c"&gt;# Ubuntu/Debian&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;apache2  &lt;span class="c"&gt;# Enable on boot&lt;/span&gt;
&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%2Fawb5ud0k1b7rt6rcx3qx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawb5ud0k1b7rt6rcx3qx.png" alt="start and enable apache" width="800" height="110"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Verify Apache Installation
&lt;/h3&gt;

&lt;p&gt;Open a web browser and navigate to your server's IP address:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://your-server-ip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;-Use &lt;code&gt;ip addr show&lt;/code&gt; to check the IP address of your server. &lt;/p&gt;

&lt;p&gt;If Apache is running, you should see the default Apache welcome 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%2F5ovwmxcndbuyy2yl8m95.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5ovwmxcndbuyy2yl8m95.png" alt="apache is running" width="800" height="593"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Install MySQL Database Server
&lt;/h2&gt;

&lt;p&gt;MySQL is the database component of the LAMP stack.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install MySQL
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;mysql-server &lt;span class="nt"&gt;-y&lt;/span&gt;   &lt;span class="c"&gt;# Ubuntu/Debian&lt;/span&gt;

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

&lt;h3&gt;
  
  
  Secure MySQL Installation
&lt;/h3&gt;



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

&lt;/div&gt;



&lt;p&gt;Follow the prompts to set a root password and remove unnecessary settings for security.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Install PHP
&lt;/h2&gt;

&lt;p&gt;PHP is the scripting language that processes dynamic content.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install PHP and Required Modules
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;php libapache2-mod-php php-mysql php-cli php-curl php-json &lt;span class="nt"&gt;-y&lt;/span&gt;    &lt;span class="c"&gt;# Ubuntu/Debian&lt;/span&gt;

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

&lt;h3&gt;
  
  
  Restart Apache to Apply Changes
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl restart apache2   &lt;span class="c"&gt;# Ubuntu/Debian&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  Test PHP Installation
&lt;/h3&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;?php phpinfo(); ?&amp;gt;"&lt;/span&gt; | &lt;span class="nb"&gt;sudo tee&lt;/span&gt; /var/www/html/info.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then access it in a browser:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://your-server-ip/info.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If PHP is installed correctly, you will see the PHP info 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%2F2ty0d4h06kof8ft1wgd0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2ty0d4h06kof8ft1wgd0.png" alt="php" width="800" height="364"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Configure Firewall (If Necessary)
&lt;/h2&gt;

&lt;p&gt;To allow web traffic, open the necessary ports:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow 80/tcp   &lt;span class="c"&gt;# Ubuntu/Debian&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow 443/tcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;You have successfully deployed a LAMP stack on your Linux server! You can now start developing and hosting your websites using Apache, MySQL, and PHP.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Set Up VS Code for C# Development to Build a Console and Web App</title>
      <dc:creator>Ibrahim Bio Abubakar</dc:creator>
      <pubDate>Sun, 23 Mar 2025 13:55:32 +0000</pubDate>
      <link>https://dev.to/ibrahimbioabu/how-to-set-up-vs-code-for-c-development-to-build-a-console-and-web-app-7l5</link>
      <guid>https://dev.to/ibrahimbioabu/how-to-set-up-vs-code-for-c-development-to-build-a-console-and-web-app-7l5</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Visual Studio Code (VS Code) is a lightweight yet powerful code editor that supports C# development with ease. Whether you're building a simple console application or a basic web app, correctly setting up your development environment is essential. This guide will walk you through setting up VS Code to create a simple C# console app and a minimal web app (a number guessing game) using ASP.NET Core.&lt;/p&gt;




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

&lt;p&gt;Before you start, ensure you have the following installed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://code.visualstudio.com/" rel="noopener noreferrer"&gt;Visual Studio Code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dotnet.microsoft.com/en-us/download" rel="noopener noreferrer"&gt;NET SDK&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csharp" rel="noopener noreferrer"&gt;C# Extension for VS Code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once these are installed, open VS Code and install the C# extension if you haven’t already. This extension provides IntelliSense, debugging, and other essential tools for C# development.&lt;/p&gt;




&lt;h2&gt;
  
  
  Setting Up a C# Console Application
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create a New Project&lt;/strong&gt;
Open a terminal in VS Code and run:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   dotnet new console &lt;span class="nt"&gt;-o&lt;/span&gt; MyConsoleApp
   &lt;span class="nb"&gt;cd &lt;/span&gt;MyConsoleApp
   code &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a new console application and opens it in VS Code.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Write Code&lt;/strong&gt;
Open &lt;code&gt;Program.cs&lt;/code&gt; and modify the &lt;code&gt;Main&lt;/code&gt; method to print a message:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;   &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

   &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Program&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
       &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello, VS Code with C# is fun :)!"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
       &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Run the Application&lt;/strong&gt;
In the terminal, execute:
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;/div&gt;



&lt;p&gt;You should see &lt;code&gt;Hello, VS Code with C# is fun :)!&lt;/code&gt; printed in the console.&lt;/p&gt;

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




&lt;h2&gt;
  
  
  Setting Up a Simple Web App with ASP.NET Core
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create a Web App&lt;/strong&gt;
Run the following command to create a new web project:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   dotnet new web &lt;span class="nt"&gt;-o&lt;/span&gt; MyWebApp
   &lt;span class="nb"&gt;cd &lt;/span&gt;MyWebApp
   code &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Modify the Web App&lt;/strong&gt;
Open &lt;code&gt;Program.cs&lt;/code&gt; and update it as follows:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;

namespace NumberGuessGame
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =&amp;gt;
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =&amp;gt;
                {
                    webBuilder.UseStartup&amp;lt;Startup&amp;gt;();
                });
    }

    public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDistributedMemoryCache();
            services.AddSession();
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseSession();
            app.UseRouting();

            app.UseEndpoints(endpoints =&amp;gt;
            {
                endpoints.MapGet("/", async context =&amp;gt;
                {
                    int secretNumber = new Random().Next(1, 101);
                    context.Session.SetInt32("SecretNumber", secretNumber);
                    await context.Response.WriteAsync($"&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;");
                    await context.Response.WriteAsync("&amp;lt;h1&amp;gt;Number Guessing Game&amp;lt;/h1&amp;gt;");
                    await context.Response.WriteAsync("&amp;lt;form method='post' action='/guess'&amp;gt;");
                    await context.Response.WriteAsync("Enter your guess: &amp;lt;input type='number' name='guess' required&amp;gt; ");
                    await context.Response.WriteAsync("&amp;lt;input type='submit' value='Submit'&amp;gt;");
                    await context.Response.WriteAsync("&amp;lt;/form&amp;gt;");
                    await context.Response.WriteAsync("&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;");
                });

                endpoints.MapPost("/guess", async context =&amp;gt;
                {
                    var form = await context.Request.ReadFormAsync();
                    int userGuess = int.Parse(form["guess"]);
                    int secretNumber = context.Session.GetInt32("SecretNumber") ?? new Random().Next(1, 101);

                    string message;
                    if (userGuess &amp;lt; secretNumber)
                        message = "Too low! Try again.";
                    else if (userGuess &amp;gt; secretNumber)
                        message = "Too high! Try again.";
                    else
                    {
                        message = "Congratulations! You guessed the right number!";
                        secretNumber = new Random().Next(1, 101); // Reset number after a correct guess
                        context.Session.SetInt32("SecretNumber", secretNumber);
                    }

                    await context.Response.WriteAsync($"&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;");
                    await context.Response.WriteAsync($"&amp;lt;h1&amp;gt;{message}&amp;lt;/h1&amp;gt;");
                    await context.Response.WriteAsync("&amp;lt;a href='/'&amp;gt;Try Again&amp;lt;/a&amp;gt;");
                    await context.Response.WriteAsync("&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;");
                });
            });
        }
    }
}


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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Run the Web App&lt;/strong&gt;
Execute:
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;/div&gt;



&lt;p&gt;The app will start on &lt;code&gt;http://localhost:5230&lt;/code&gt;. Open a browser and visit the URL to see your message.&lt;/p&gt;

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




&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
Setting up VS Code for C# development is straightforward. By installing the .NET SDK and the C# extension, you can quickly create and run both console and web applications. This setup provides a lightweight yet practical development environment for C# programmers. &lt;/p&gt;

</description>
    </item>
    <item>
      <title>Essential Linux Commands for Beginners</title>
      <dc:creator>Ibrahim Bio Abubakar</dc:creator>
      <pubDate>Wed, 19 Mar 2025 21:38:14 +0000</pubDate>
      <link>https://dev.to/ibrahimbioabu/essential-linux-commands-for-beginners-3ejk</link>
      <guid>https://dev.to/ibrahimbioabu/essential-linux-commands-for-beginners-3ejk</guid>
      <description>&lt;p&gt;Linux is a powerful and flexible operating system used by developers, system administrators, and enthusiasts worldwide. If you're new to Linux, learning basic commands is essential to navigating a system efficiently. This guide covers fundamental Linux commands that will help you manage files, processes, users, and more. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Basic Commands&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pwd&lt;/code&gt; - Print working directory (show the current directory).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ls&lt;/code&gt; - List files and directories in the current directory.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cd &amp;lt;directory&amp;gt;&lt;/code&gt; - Change directory.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Example: &lt;code&gt;cd Documents&lt;/code&gt; - moves into the Documents directory.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;mkdir &amp;lt;directory&amp;gt;&lt;/code&gt; - Create a new directory.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;rmdir &amp;lt;directory&amp;gt;&lt;/code&gt; - Remove an empty directory.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;rm &amp;lt;file&amp;gt;&lt;/code&gt; - Remove a file.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;rm -r &amp;lt;directory&amp;gt;&lt;/code&gt; - Remove a directory and its contents.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cp &amp;lt;source&amp;gt; &amp;lt;destination&amp;gt;&lt;/code&gt;  - Copy files or directories.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Example: &lt;code&gt;cp file.txt /home/users/Documents&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;mv &amp;lt;source&amp;gt; &amp;lt;destination&amp;gt;&lt;/code&gt; - Move or rename files.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Example: &lt;code&gt;mv oldname.txt newname.txt&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;touch &amp;lt;filename&amp;gt;&lt;/code&gt; - Create a new empty file.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;2. File Viewing Commands&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cat &amp;lt;file&amp;gt;&lt;/code&gt; - Displays the content of a file.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;less &amp;lt;file&amp;gt;&lt;/code&gt; - View a file one page at a time.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;head &amp;lt;file&amp;gt;&lt;/code&gt; - Show the first 10 lines of a file.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;tail &amp;lt;file&amp;gt;&lt;/code&gt; - Show the last 10 lines of a file.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;tail -f &amp;lt;file&amp;gt;&lt;/code&gt; - Monitor a file in real-time(useful for logs).&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;3. File Permissions &amp;amp; Ownership&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ls -l&lt;/code&gt;  - List files with details including permissions.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;4. Process Management&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ps&lt;/code&gt;  - Show running processes.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;top&lt;/code&gt;  - Display real-time system resource usage.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;5. Disk &amp;amp; Storage&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;df -h&lt;/code&gt; - Show disk usage in a human-readable format.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;6. User Management&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;id&lt;/code&gt;  - Show user and group IDs&lt;/p&gt;

&lt;p&gt;&lt;code&gt;adduser &amp;lt;username&amp;gt;&lt;/code&gt;  - Add a new user&lt;/p&gt;

&lt;p&gt;&lt;code&gt;passwd &amp;lt;username&amp;gt;&lt;/code&gt;  - Change a user's password&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;7. Package Management&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;apt update&lt;/code&gt;  - Update package lists.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;apt upgrade&lt;/code&gt;  - Upgrade all installed packages.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;apt install &amp;lt;package&amp;gt;&lt;/code&gt; - Install a package&lt;/p&gt;

&lt;p&gt;&lt;code&gt;apt remove &amp;lt;package&amp;gt;&lt;/code&gt; - Remove a package.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;8. Searching content in a File&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;grep "text" &amp;lt;file&amp;gt;&lt;/code&gt; - Search for text in a file.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;9. Detailed Files Viewing Commands&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ls -a&lt;/code&gt;  - Displays hidden files&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ls -lh&lt;/code&gt;  - List files and their sizes in a human-readable format.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;10. Other Useful Commands&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;echo "Hello World!"&lt;/code&gt; - Print text to the terminal.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;history&lt;/code&gt; - Show command history&lt;/p&gt;

&lt;p&gt;&lt;code&gt;clear&lt;/code&gt;  - Clear the terminal screen.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;man &amp;lt;command&amp;gt;&lt;/code&gt;  - Show the manual for a command.&lt;/p&gt;




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

&lt;p&gt;Mastering these basic Linux commands will help you navigate and manage your system more efficiently. As you become more comfortable, you can explore more advanced commands and scripting techniques to automate tasks. Keep practicing, and soon, working with Linux will become second nature. Happy coding!&lt;/p&gt;

</description>
      <category>linux</category>
      <category>cloudcomputing</category>
      <category>devops</category>
      <category>beginners</category>
    </item>
    <item>
      <title>A Guide on How to Provide Storage for an IT Department Testing and Training using Microsoft Azure</title>
      <dc:creator>Ibrahim Bio Abubakar</dc:creator>
      <pubDate>Sat, 15 Mar 2025 14:21:52 +0000</pubDate>
      <link>https://dev.to/ibrahimbioabu/a-guide-on-how-to-provide-storage-for-an-it-department-testing-and-training-using-microsoft-azure-1jnj</link>
      <guid>https://dev.to/ibrahimbioabu/a-guide-on-how-to-provide-storage-for-an-it-department-testing-and-training-using-microsoft-azure-1jnj</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's assume the IT Department where you work needs to prototype different storage scenarios to train new personnel, and you've been tasked with providing storage where the content is not important enough to be backed up and doesn't need to be restored if the data is overwritten or removed.&lt;/p&gt;

&lt;p&gt;In this guide, you'll learn how to create and configure an Azure storage account that meets these requirements. We'll walk through setting up a resource group, deploying a storage account, and applying basic security and networking settings to ensure efficient and cost-effective storage management.&lt;/p&gt;

&lt;p&gt;By the end of this tutorial, you'll have a functional storage environment that can be used for training and testing, without unnecessary overhead or long-term commitments. Let’s get started!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Create a resource group and a storage account.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Create and deploy a resource group to hold all the project resources&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Login to the &lt;a href="https://portal.azure.com" rel="noopener noreferrer"&gt;Azure Portal&lt;/a&gt; and search for and select &lt;code&gt;Resource groups&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%2F8iqnrku204p8qk2x4qgi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8iqnrku204p8qk2x4qgi.png" alt="search RG" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;Select &lt;strong&gt;+ Create&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%2Fb5peo3moh45ny19o8vip.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb5peo3moh45ny19o8vip.png" alt="select cre8 RG" width="800" height="390"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;Give your resource group a &lt;strong&gt;name&lt;/strong&gt;. For example, &lt;code&gt;storagerg&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select a &lt;strong&gt;region&lt;/strong&gt;. Your choice of region should be used throughout the project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select &lt;strong&gt;Review and create&lt;/strong&gt; to validate the resource group. &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%2Fe0z30z7achlamcj279nc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe0z30z7achlamcj279nc.png" alt="fill" width="800" height="805"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;Select &lt;strong&gt;Create&lt;/strong&gt; to deploy the resource group. &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%2Fxjbd5hfpm8x3pax0f2cb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxjbd5hfpm8x3pax0f2cb.png" alt="create RG " width="800" height="827"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Step 2: Create and deploy a storage account to support testing and training&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the Azure portal, search for and select &lt;code&gt;Storage account&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%2Fka8qmqmxmi8zb44fpawr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fka8qmqmxmi8zb44fpawr.png" alt="SA" width="800" height="261"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;Select &lt;strong&gt;+ Create&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%2Fxwezz4ali93k48xs4gpe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxwezz4ali93k48xs4gpe.png" alt="Select cre8" width="800" height="378"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;On the &lt;strong&gt;Basics&lt;/strong&gt; tab, select your &lt;strong&gt;Resource group&lt;/strong&gt;. &lt;/li&gt;
&lt;li&gt;Provide a storage account name.  The storage account name must be unique in Azure.&lt;/li&gt;
&lt;li&gt;Set the &lt;strong&gt;Performance&lt;/strong&gt; to &lt;strong&gt;Standard&lt;/strong&gt;.
-Select &lt;strong&gt;Review&lt;/strong&gt;, and then &lt;strong&gt;create&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%2Fd1as6rixqli3788w3pws.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd1as6rixqli3788w3pws.png" alt="Basics" width="800" height="684"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;Finally, wait for the storage account to deploy and then &lt;strong&gt;Go to resource&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%2Fsbrq7h2p1t0v6x5pi829.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsbrq7h2p1t0v6x5pi829.png" alt="Go to R" width="800" height="522"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Configure simple settings in the storage account&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Recall that the data in this storage doesn't require high availability or durability. A lowest-cost storage solution is desired.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Configure the Data Redundancy of the Storage Account&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In your storage account, in the &lt;strong&gt;Data Management&lt;/strong&gt; section, select the &lt;strong&gt;Redundancy&lt;/strong&gt; blade.&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%2F3t2gi38prpwjiucncqqp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3t2gi38prpwjiucncqqp.png" alt="Redundancy blade" width="800" height="608"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Select &lt;strong&gt;Locally-redundant storage (LRS)&lt;/strong&gt; in the &lt;strong&gt;Redundancy&lt;/strong&gt; drop-down. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Don't forget to &lt;em&gt;Save&lt;/em&gt; your changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, refresh the page and notice the content only exists in the primary location.&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%2Fwnof72qenmrnb380ts9v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwnof72qenmrnb380ts9v.png" alt="LSR" width="800" height="441"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;We also need to ensure the storage account only accepts requests from secure connections and uses at least a Transfer Layer Security (TLS) version 1.2. &lt;/p&gt;

&lt;p&gt;Until the storage is needed again, disable requests to the storage account.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Enable a Secure Transfer in Storage Account&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the &lt;strong&gt;Settings&lt;/strong&gt; section, select the &lt;strong&gt;Configuration&lt;/strong&gt; blade.&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%2Fnwz3ry6zwr8sp6su2vn3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnwz3ry6zwr8sp6su2vn3.png" alt="Secure transfer" width="800" height="601"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Ensure &lt;strong&gt;Secure transfer required&lt;/strong&gt; is enabled.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ensure the &lt;strong&gt;Minimal TLS version&lt;/strong&gt; is set to &lt;strong&gt;Version 1.2&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, ensure the &lt;strong&gt;Allow storage account key access&lt;/strong&gt; is &lt;strong&gt;Disabled&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%2Fruoaldva8fe6n1l1urp9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fruoaldva8fe6n1l1urp9.png" alt="TLS" width="800" height="507"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Step 5: Allow the Storage Account to have public Access from all Networks&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the &lt;strong&gt;Security + networking&lt;/strong&gt; section, select the &lt;strong&gt;Networking&lt;/strong&gt; blade.&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%2Fqg3qijahpoz0mjmkt80q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqg3qijahpoz0mjmkt80q.png" alt="Network" width="800" height="625"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;ul&gt;
&lt;li&gt;Ensure &lt;strong&gt;Public network access&lt;/strong&gt; is set to &lt;strong&gt;Enabled from all networks&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%2Fbk38p6kiph3e2ip5phxk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbk38p6kiph3e2ip5phxk.png" alt="enabled" width="800" height="574"&gt;&lt;/a&gt;&lt;/p&gt;




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

&lt;p&gt;By following these steps, you've successfully set up a cost-effective Azure storage solution tailored for training and testing scenarios. This storage account is optimized for minimal redundancy, secure data transfers, and public accessibility, making it ideal for non-critical data that doesn't require backup or restoration.  &lt;/p&gt;

&lt;p&gt;This setup allows your IT team to experiment with different storage configurations without incurring unnecessary costs or complexity. As your needs evolve, you can further refine security, networking, and access policies to align with future projects.  &lt;/p&gt;

&lt;p&gt;Now that your storage account is ready, you can start using it for training exercises, prototyping, or even exploring additional Azure storage features. Happy testing!  &lt;/p&gt;

</description>
      <category>azure</category>
      <category>cloudstorage</category>
      <category>ittraining</category>
      <category>cloudcomputing</category>
    </item>
    <item>
      <title>Managing Azure On-the-Go: A Guide to the Azure Mobile App</title>
      <dc:creator>Ibrahim Bio Abubakar</dc:creator>
      <pubDate>Wed, 12 Mar 2025 13:41:53 +0000</pubDate>
      <link>https://dev.to/ibrahimbioabu/managing-azure-on-the-go-a-guide-to-the-azure-mobile-app-52i</link>
      <guid>https://dev.to/ibrahimbioabu/managing-azure-on-the-go-a-guide-to-the-azure-mobile-app-52i</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Azure mobile app is a powerful tool that enables users to manage their Azure resources on-the-go. Available for both iOS and Android platforms, the app provides a range of features designed to help users monitor and control their cloud infrastructure from their mobile devices.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Resource Monitoring:&lt;/strong&gt; Users can view the status and health of their Azure resources, including virtual machines, web apps, and databases. This allows for real-time monitoring and quick identification of any issues.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Alerts and Notifications:&lt;/strong&gt; The app provides push notifications for important alerts, ensuring that users are immediately informed of critical events or changes in their resources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Resource Management:&lt;/strong&gt; Users can start, stop, and restart virtual machines and web apps directly from the app, providing flexibility and control over their services without the need for a desktop interface.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Cloud Shell Integration:&lt;/strong&gt; The app integrates with Azure Cloud Shell, allowing users to run scripts and manage resources using the command line interface from their mobile devices.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Secure Access:&lt;/strong&gt; The app supports multi-factor authentication and integrates with Microsoft Entra ID, ensuring secure access to resources.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Getting Started:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Download the App:&lt;/strong&gt; The Azure mobile app is available for download on the &lt;a href="https://apps.apple.com/app/azure-app/id123456789" rel="noopener noreferrer"&gt;Apple App Store&lt;/a&gt; and &lt;a href="https://play.google.com/store/apps/details?id=com.microsoft.azure" rel="noopener noreferrer"&gt;Google Play Store&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Sign In:&lt;/strong&gt; After installation, sign in with your Azure account credentials. Ensure that your account has the necessary permissions to access and manage resources.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Explore Resources:&lt;/strong&gt; Once signed in, you can browse through your subscriptions and resources. The intuitive interface allows for easy navigation and management.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Set Up Notifications:&lt;/strong&gt; Configure alerts and notifications to stay informed about the status of your resources. Customize the settings to receive notifications for specific events or thresholds.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Use Cases:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;On-Call Administrators:&lt;/strong&gt; System administrators can respond to critical alerts and perform necessary actions, such as restarting services, without the need for a computer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Developers:&lt;/strong&gt; Developers can monitor the performance of their applications and make adjustments as needed, ensuring optimal performance and reliability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;IT Managers:&lt;/strong&gt; IT managers can keep track of resource utilization and costs, making informed decisions about scaling and resource allocation.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;The Azure mobile app is an essential tool for anyone managing Azure resources. Its comprehensive features and user-friendly interface make it easier to monitor and control cloud services from anywhere, ensuring that your infrastructure remains robust and responsive.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: &lt;em&gt;Always ensure that your mobile device is secured and that you follow best practices for account security to protect your Azure resources.&lt;/em&gt;&lt;/em&gt; &lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Deploy Your Resume using an Azure Web App via the Azure Portal</title>
      <dc:creator>Ibrahim Bio Abubakar</dc:creator>
      <pubDate>Sat, 08 Mar 2025 21:47:55 +0000</pubDate>
      <link>https://dev.to/ibrahimbioabu/how-to-deploy-your-resume-using-an-azure-web-app-via-azure-portal-352o</link>
      <guid>https://dev.to/ibrahimbioabu/how-to-deploy-your-resume-using-an-azure-web-app-via-azure-portal-352o</guid>
      <description>&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Deploying a web application to Azure is a crucial skill for any cloud engineer. In this guide, I will walk through the step-by-step process of deploying a simple HTML web app resume, on Microsoft Azure using the Azure Portal. By the end of this tutorial, you will have your web app hosted on Azure App Service, making it accessible from anywhere.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Step 1: Create an Azure Account&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you don’t have an Azure account yet, you can create a free one at &lt;a href="https://portal.azure.com" rel="noopener noreferrer"&gt;Azure Portal&lt;/a&gt;. Azure offers a free tier with credits that allow you to test and deploy small applications.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Step 2: Create a Resource Group&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Log in to the &lt;a href="https://portal.azure.com" rel="noopener noreferrer"&gt;Azure Portal&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Click on &lt;strong&gt;Resource Groups&lt;/strong&gt; in the left-hand menu.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create&lt;/strong&gt; and enter:

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;Resource Group Name&lt;/strong&gt; (e.g., &lt;code&gt;MyResourceGroup&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;Region&lt;/strong&gt; (e.g., &lt;code&gt;North Europe&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Review + Create&lt;/strong&gt;, then &lt;strong&gt;Create&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I will be using a Resource Group created for this lab exercise called &lt;code&gt;SheroGlobalRG&lt;/code&gt;.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Step 3: Create a Web App&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In the Azure Portal, search for &lt;strong&gt;App Services&lt;/strong&gt; and click &lt;strong&gt;Create&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Fill in the details on the Basics page:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name&lt;/strong&gt;: A unique web app name (e.g., &lt;code&gt;ahmadkuraishiresume&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Resource Group&lt;/strong&gt;: Select &lt;code&gt;MyResourceGroup&lt;/code&gt; (the one you created in step 1). Mine is &lt;code&gt;SheroGlobalRG&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Publish&lt;/strong&gt;: Choose &lt;strong&gt;Code&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Runtime Stack&lt;/strong&gt;: Select &lt;strong&gt;HTML&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operating System&lt;/strong&gt;: Choose &lt;strong&gt;Windows&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Region&lt;/strong&gt;: Select the same region as your resource group. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;App Service Plan&lt;/strong&gt;: You can create a new one or use the default service plan.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Review + Create&lt;/strong&gt;, then &lt;strong&gt;Create&lt;/strong&gt;. Leaving every other tab in the 
default setting.&lt;/li&gt;
&lt;/ol&gt;

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




&lt;ol&gt;
&lt;li&gt;After deploying the web app, select &lt;strong&gt;Go to Resource&lt;/strong&gt; to access it. &lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;&lt;strong&gt;Step 5: Use the Advance Tool to Deploy Web Content&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Search for the &lt;strong&gt;Advance Tool&lt;/strong&gt; on the left-hand menu, launch the tool, and select &lt;strong&gt;Go&lt;/strong&gt; to access the &lt;strong&gt;Kudu+&lt;/strong&gt; web page.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7s14u121fujgyy4bd56z.png" alt="advance tool" width="800" height="398"&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Click on &lt;strong&gt;Debug Console&lt;/strong&gt; and select &lt;strong&gt;CMD&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

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




&lt;ol&gt;
&lt;li&gt;Select &lt;strong&gt;Site&lt;/strong&gt;, followed by &lt;strong&gt;wwwroot&lt;/strong&gt; in the next page.&lt;/li&gt;
&lt;/ol&gt;

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




&lt;ol&gt;
&lt;li&gt;Click on the edit or pen icon shown below to paste the content of your HTML file. &lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Note: You can easily generate a HTML simple resume of your choice using ChatGPT if you're not familiar with 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%2Fpgdne5vmfqovrw8lhwr5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpgdne5vmfqovrw8lhwr5.png" alt="edit" width="800" height="502"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;ol&gt;
&lt;li&gt;Paste your HTML code here and select &lt;strong&gt;Save&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;

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




&lt;p&gt;&lt;strong&gt;Step 6: Access Your Web App&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After saving your code on &lt;strong&gt;Kudu+&lt;/strong&gt;, head back to the web app resource created earlier and copy the default domain, and lunch it on a browser of your choice. &lt;/p&gt;

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




&lt;p&gt;This is the outcome you should expect in yours:  &lt;/p&gt;

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




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

&lt;p&gt;Congratulations! You have successfully deployed a simple HTML resume web app to Azure using the Azure Portal. This guide covered creating a resource group, setting up an App Service Plan, and deploying your code through the Azure Portal. Happy coding!&lt;/p&gt;

&lt;p&gt;If you found this guide helpful, feel free to share your thoughts in the comments below.&lt;/p&gt;

</description>
      <category>microsoft</category>
      <category>azure</category>
      <category>appservices</category>
      <category>cloudcomputing</category>
    </item>
  </channel>
</rss>
