<?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: Whuatorhe Tejiri</title>
    <description>The latest articles on DEV Community by Whuatorhe Tejiri (@tejirih).</description>
    <link>https://dev.to/tejirih</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%2F2659553%2F9dd01051-891e-4399-92fa-0fcd5e50b761.png</url>
      <title>DEV Community: Whuatorhe Tejiri</title>
      <link>https://dev.to/tejirih</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tejirih"/>
    <language>en</language>
    <item>
      <title>RideShare Pro Production-Grade Microservices Deployment on Azure Kubernetes Service (AKS)</title>
      <dc:creator>Whuatorhe Tejiri</dc:creator>
      <pubDate>Mon, 14 Jul 2025 13:00:16 +0000</pubDate>
      <link>https://dev.to/tejirih/rideshare-proproduction-grade-microservices-deployment-on-azure-kubernetes-service-aks-3nmh</link>
      <guid>https://dev.to/tejirih/rideshare-proproduction-grade-microservices-deployment-on-azure-kubernetes-service-aks-3nmh</guid>
      <description>&lt;h2&gt;
  
  
  Project Overview
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;RideShare Pro&lt;/strong&gt; is a microservices-based ride-sharing platform designed for scalability, fault tolerance, and high availability on Azure Kubernetes Service (AKS). This project simulates a real-world DevOps scenario for a fast-growing African ride-sharing startup.&lt;/p&gt;




&lt;h2&gt;
  
  
  Architecture Overview
&lt;/h2&gt;

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

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

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Service Name&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;User Service&lt;/td&gt;
&lt;td&gt;Handles registration, authentication, profiles&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ride Matching&lt;/td&gt;
&lt;td&gt;Matches riders with available drivers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Payment Service&lt;/td&gt;
&lt;td&gt;Processes payments and manages billing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Notification Service&lt;/td&gt;
&lt;td&gt;Sends SMS, push, and email notifications&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Supporting Infrastructure
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;PostgreSQL (StatefulSet)&lt;/strong&gt; – Primary + Replica with persistent volumes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redis (StatefulSet)&lt;/strong&gt; – Clustered for caching, session, and pub/sub&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nginx Ingress Controller&lt;/strong&gt; – API Gateway for external routing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Azure Container Registry (ACR)&lt;/strong&gt; – Private container registry&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AKS Cluster&lt;/strong&gt; – Orchestrator with autoscaling enabled&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Tools &amp;amp; Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Azure CLI&lt;/li&gt;
&lt;li&gt;kubectl&lt;/li&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;li&gt;Git&lt;/li&gt;
&lt;li&gt;Azure Subscription (with Contributor access)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Clone the Repositories
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;git clone &lt;a href="https://github.com/YOUR_USERNAME/rideshare-user-service.git" rel="noopener noreferrer"&gt;https://github.com/YOUR_USERNAME/rideshare-user-service.git&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;git clone &lt;a href="https://github.com/YOUR_USERNAME/rideshare-ride-matching-service.git" rel="noopener noreferrer"&gt;https://github.com/YOUR_USERNAME/rideshare-ride-matching-service.git&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;git clone &lt;a href="https://github.com/YOUR_USERNAME/rideshare-payment-service.git" rel="noopener noreferrer"&gt;https://github.com/YOUR_USERNAME/rideshare-payment-service.git&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;git clone &lt;a href="https://github.com/YOUR_USERNAME/rideshare-notification-service.git" rel="noopener noreferrer"&gt;https://github.com/YOUR_USERNAME/rideshare-notification-service.git&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;git clone &lt;a href="https://github.com/YOUR_USERNAME/rideshare-infrastructure.git" rel="noopener noreferrer"&gt;https://github.com/YOUR_USERNAME/rideshare-infrastructure.git&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Provision Infrastructure
&lt;/h3&gt;

&lt;p&gt;Create Resource Group&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;RESOURCE_GROUP="teleios-tejiri-rg"&lt;br&gt;
 LOCATION="centralus"&lt;br&gt;
 az group create --name $RESOURCE_GROUP --location $LOCATION&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Create ACR&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ACR_NAME="teleiostejiriacr"&lt;/p&gt;

&lt;p&gt;az acr create --resource-group $RESOURCE_GROUP --name $ACR_NAME --sku Standard&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Authenticate with Azure &amp;amp; Configure CLI
&lt;/h3&gt;

&lt;p&gt;Log in to Azure:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;az login&lt;br&gt;
This will open a browser for authentication.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Set your desired subscription (if you have multiple):&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;az account set --subscription "YOUR_SUBSCRIPTION_NAME"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Create AKS Cluster
&lt;/h4&gt;

&lt;p&gt;CLUSTER_NAME="rideshare-aks"&lt;/p&gt;

&lt;p&gt;&lt;code&gt;az aks create \&lt;br&gt;
  --resource-group $RESOURCE_GROUP \&lt;br&gt;
  --name $CLUSTER_NAME \&lt;br&gt;
  --node-count 2 \&lt;br&gt;
  --node-vm-size Standard_B2ls_v2 \&lt;br&gt;
  --enable-cluster-autoscaler \&lt;br&gt;
  --min-count 2 \&lt;br&gt;
  --max-count 6 \&lt;br&gt;
  --generate-ssh-keys \&lt;br&gt;
  --attach-acr $ACR_NAME \&lt;br&gt;
  --location $LOCATION&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Get AKS Credentials and Set kubectl Context
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;az aks get-credentials --resource-group $RESOURCE_GROUP --name $CLUSTER_NAME&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Verify current context:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;kubectl config current-context&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Data Layer Deployment
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Redis StatefulSet
&lt;/h4&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create the following files and apply them kubectl apply -f .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;redis-statefulset.yaml&lt;/li&gt;
&lt;li&gt;redis-headless-service.yaml&lt;/li&gt;
&lt;li&gt;redis-configmap.yaml&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Validate:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;kubectl get statefulset redis-cluster&lt;/li&gt;
&lt;li&gt;kubectl get pods -l app=redis-cluster&lt;/li&gt;
&lt;li&gt;kubectl get pvc&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  PostgreSQL StatefulSet
&lt;/h4&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create the following files and apply them with kubectl apply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;postgresql-primary-statefulset.yaml&lt;/li&gt;
&lt;li&gt;postgresql-replica-statefulset.yaml&lt;/li&gt;
&lt;li&gt;postgresql-headless-service.yaml&lt;/li&gt;
&lt;li&gt;postgresql-secret.yaml&lt;/li&gt;
&lt;li&gt;postgresql-config-map.yaml&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Validate:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;kubectl get statefulset&lt;/li&gt;
&lt;li&gt;kubectl exec -it postgres-primary-0 -- psql -U postgres -c "\l"&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Microservices Deployment
&lt;/h3&gt;

&lt;p&gt;Build and Push Docker Images&lt;/p&gt;

&lt;h4&gt;
  
  
  Example for User Service
&lt;/h4&gt;

&lt;p&gt;cd rideshare-user-service&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;docker build -t $ACR_NAME.azurecr.io/user-service:v1.0 .&lt;/li&gt;
&lt;li&gt;docker push $ACR_NAME.azurecr.io/user-service:v1.0&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Repeat for all services.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deploy Kubernetes Manifests
&lt;/h3&gt;

&lt;p&gt;Create namespace e.g "microservices" and create the following files for each service:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;deployment.yaml&lt;/li&gt;
&lt;li&gt;service.yaml&lt;/li&gt;
&lt;li&gt;secret.yaml&lt;/li&gt;
&lt;li&gt;hpa.yaml&lt;/li&gt;
&lt;li&gt;pdb.yaml&lt;/li&gt;
&lt;/ul&gt;

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

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;kubectl apply -f ./k8s/deployment.yaml&lt;/li&gt;
&lt;li&gt;kubectl apply -f ./k8s/service.yaml&lt;/li&gt;
&lt;li&gt;kubectl apply -f ./k8s/hpa.yaml&lt;/li&gt;
&lt;li&gt;kubectl apply -f ./k8s/pdb.yaml&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Validate:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Kubectl get pods -n microservices&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Install NGINX Ingress Controller
&lt;/h3&gt;

&lt;p&gt;Apply the official NGINX Ingress manifests:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;kubectl apply -f &lt;a href="https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.9.6/deploy/static/provider/cloud/deploy.yaml" rel="noopener noreferrer"&gt;https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.9.6/deploy/static/provider/cloud/deploy.yaml&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This deploys everything: the ingress controller, service, RBAC, etc.&lt;/p&gt;

&lt;p&gt;Wait for the pods to be ready:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;kubectl get pods -n ingress-nginx&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Once ready, you can get the external IP:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;kubectl get service ingress-nginx-controller -n ingress-nginx&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We mapped the ingress loadbalancer ip to azure dns to enable persistency when we connect to our dns against changing ip address.&lt;/p&gt;

&lt;p&gt;We write our ingress rule based on what path the services are expecting, some services expects &lt;code&gt;/api/payments/*&lt;/code&gt; while some just need &lt;code&gt;/*&lt;/code&gt;, so we have two ingress rule files that does a rewrite by striping the request sent by the browser from /api/service/* to just / and then a service that do not rewrite but just sends the request directly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Install cert-manager (manually)
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;kubectl apply -f &lt;a href="https://github.com/cert-manager/cert-manager/releases/download/v1.14.4/cert-manager.yaml" rel="noopener noreferrer"&gt;https://github.com/cert-manager/cert-manager/releases/download/v1.14.4/cert-manager.yaml&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Wait for the pods:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;kubectl get pods --namespace cert-manager&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;ul&gt;
&lt;li&gt;cert-manager&lt;/li&gt;
&lt;li&gt;cert-manager-cainjector&lt;/li&gt;
&lt;li&gt;cert-manager-webhook&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Create Let's Encrypt Issuer
&lt;/h4&gt;

&lt;p&gt;Create a ClusterIssuer (for all namespaces):&lt;br&gt;
Apply it&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;kubectl apply -f letsencrypt-clusterissuer.yaml&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Add TLS + Certificate to Ingress rule
&lt;/h4&gt;

&lt;p&gt;Apply the Ingress rules&lt;/p&gt;

&lt;p&gt;Wait for TLS Certificate&lt;br&gt;
Check the certificate status:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;kubectl describe certificate notification-tls -n microservices&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You should see Ready=True once it's provisioned.&lt;/p&gt;

&lt;p&gt;Run the following commands &lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;kubectl get certificates -n microservices&lt;/li&gt;
&lt;li&gt;kubectl get secrets -n microservices&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;You’ll see a secret used by the Ingress for HTTPS.&lt;/p&gt;

&lt;p&gt;Test your dns using Https to confirm if it has worked.&lt;br&gt;
&lt;a href="https://your-dns-name/api/notifications/docs" rel="noopener noreferrer"&gt;https://your-dns-name/api/notifications/docs&lt;/a&gt; which leads to the swagger ui.&lt;/p&gt;

&lt;h3&gt;
  
  
  CI/CD Pipeline (GitHub Actions)
&lt;/h3&gt;

&lt;p&gt;Each repo contains .github/workflows/deploy.yml&lt;/p&gt;

&lt;p&gt;Stages:&lt;/p&gt;

&lt;p&gt;Checkout code&lt;/p&gt;

&lt;p&gt;Build Docker image&lt;/p&gt;

&lt;p&gt;Push to ACR&lt;/p&gt;

&lt;p&gt;Deploy to AKS (main/release only)&lt;/p&gt;

&lt;p&gt;Triggers:&lt;/p&gt;

&lt;p&gt;Push to any branch&lt;/p&gt;

&lt;p&gt;Pull request creation&lt;/p&gt;

&lt;p&gt;Manual workflow trigger&lt;/p&gt;

&lt;p&gt;Access Microservice&lt;/p&gt;

&lt;p&gt;Links to the individual repos having all our /k8s folders are attached with all files &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/TejiriH/rideshare-user-service" rel="noopener noreferrer"&gt;https://github.com/TejiriH/rideshare-user-service&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/TejiriH/rideshare-ride-matching-service" rel="noopener noreferrer"&gt;https://github.com/TejiriH/rideshare-ride-matching-service&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/TejiriH/rideshare-payment-service" rel="noopener noreferrer"&gt;https://github.com/TejiriH/rideshare-payment-service&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/TejiriH/rideshare-notification-service" rel="noopener noreferrer"&gt;https://github.com/TejiriH/rideshare-notification-service&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/TejiriH/rideshare-infrastructure" rel="noopener noreferrer"&gt;https://github.com/TejiriH/rideshare-infrastructure&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Deploying Nginx on AWS: A Beginner-Friendly Guide(HNG DevOps Stage 0)</title>
      <dc:creator>Whuatorhe Tejiri</dc:creator>
      <pubDate>Wed, 29 Jan 2025 14:50:28 +0000</pubDate>
      <link>https://dev.to/tejirih/deploying-nginx-on-aws-a-beginner-friendly-guidehng-devops-stage-0-2ach</link>
      <guid>https://dev.to/tejirih/deploying-nginx-on-aws-a-beginner-friendly-guidehng-devops-stage-0-2ach</guid>
      <description>&lt;h1&gt;
  
  
  &lt;strong&gt;Introduction&lt;/strong&gt;
&lt;/h1&gt;

&lt;p&gt;Configuring an Nginx web server on AWS is a fundamental skill for anyone diving into cloud computing and DevOps. This project focuses on setting up an Ubuntu-based EC2 instance to host a simple HTML page using Nginx. Through this process, I gained practical experience in server provisioning, web server configuration, and basic networking.&lt;/p&gt;

&lt;p&gt;In this blog, I’ll walk you through the steps I took to achieve this, the challenges encountered, and key takeaways.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Goal
&lt;/h2&gt;

&lt;p&gt;The objective of this project was to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Launch an Ubuntu EC2 instance on AWS.&lt;/li&gt;
&lt;li&gt;Install and configure Nginx to serve a custom HTML page.&lt;/li&gt;
&lt;li&gt;Ensure accessibility via a public IP address.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step-by-Step Implementation
&lt;/h2&gt;

&lt;h4&gt;
  
  
  1. Launching an EC2 Instance
&lt;/h4&gt;

&lt;p&gt;I started by launching an Ubuntu EC2 t3.micro instance, which falls under the AWS free tier. While setting up the instance, I allocated 8GB of EBS storage and attached a pre-configured security group allowing traffic on port 80 (HTTP). Additionally, I deployed the instance in a public subnet and ensured my existing key pair was attached for SSH access.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Connecting to the Instance
&lt;/h4&gt;

&lt;p&gt;Once the instance was running, I connected to it using SSH:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ssh -i "my-key.pem" ubuntu@&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After successfully logging in, I updated the package lists to ensure my system had the latest software packages:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;sudo apt update&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  3. Installing and Configuring Nginx
&lt;/h4&gt;

&lt;p&gt;Next, I installed Nginx, started the service, and ensured it would automatically start on boot:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;sudo apt install nginx -y&lt;br&gt;
sudo systemctl start nginx&lt;br&gt;
sudo systemctl enable nginx&lt;br&gt;
sudo systemctl status nginx&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;At this point, Nginx was running, and I could confirm this by visiting the public IP address of my EC2 instance in a web 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%2Fej8vgpcwo6wisapi3xm6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fej8vgpcwo6wisapi3xm6.png" alt="nginx running" width="800" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Deploying a Custom HTML Page
&lt;/h4&gt;

&lt;p&gt;To serve a personalized webpage, I created a new index.html file with custom HTML and CSS content:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;sudo vim /var/www/html/index.html&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I then added a simple HTML page with basic styling, saved the file, and exited the editor.&lt;/p&gt;

&lt;h4&gt;
  
  
  5. Restarting Nginx and Testing the Deployment
&lt;/h4&gt;

&lt;p&gt;After modifying the index.html file, I restarted Nginx to apply the changes:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;sudo systemctl restart nginx&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Finally, I accessed my public IP address in a browser, and my custom webpage loaded 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%2Fxp2y1tuopkbf22zolio5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxp2y1tuopkbf22zolio5.png" alt="nginx-webserver" width="800" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenges and Solutions
&lt;/h2&gt;

&lt;p&gt;While this was a straightforward task, I encountered a few minor challenges:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Security Group and NACL Configuration&lt;/strong&gt;: Initially, I couldn’t access the webpage. After troubleshooting, I realized I had to allow inbound HTTP traffic on port 80 in both the Security Group and Network ACL settings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Permission Issues&lt;/strong&gt;: While editing the index.html file, I encountered permission errors. Using sudo resolved the issue, ensuring I had the necessary privileges.&lt;/p&gt;

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

&lt;p&gt;This task served as a great refresher on AWS EC2, security configurations, and web server deployment. Some key lessons learned include:&lt;/p&gt;

&lt;p&gt;Always ensure security group rules and NACL settings permit required traffic.&lt;/p&gt;

&lt;p&gt;Using systemctl enable nginx ensures the service starts automatically after a reboot.&lt;/p&gt;

&lt;p&gt;Proper file permissions are crucial when modifying files in /var/www/html/.&lt;/p&gt;

&lt;p&gt;For beginners, this exercise provides a solid foundation in cloud computing and DevOps practices.&lt;/p&gt;

&lt;p&gt;Further Resources&lt;/p&gt;

&lt;p&gt;Looking for professional DevOps and Cloud Engineers? Check out:&lt;/p&gt;

&lt;p&gt;DevOps Engineers - &lt;a href="https://hng.tech/hire/devops-engineers" rel="noopener noreferrer"&gt;https://hng.tech/hire/devops-engineers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cloud Engineers -  &lt;a href="https://hng.tech/hire/cloud-engineers" rel="noopener noreferrer"&gt;https://hng.tech/hire/cloud-engineers&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Deploying a basic Nginx server on AWS is a simple yet essential skill in cloud computing. Whether you're learning DevOps or just starting your cloud journey, practicing such hands-on projects will help reinforce your knowledge.&lt;/p&gt;

&lt;p&gt;Feel free to drop any questions in the comments or share your own experience with setting up Nginx on AWS!&lt;/p&gt;

&lt;p&gt;🚀 Happy Coding!&lt;/p&gt;

</description>
      <category>nginx</category>
      <category>devops</category>
      <category>aws</category>
      <category>hng</category>
    </item>
  </channel>
</rss>
