<?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: Folashade Oluwaseun Oroge</title>
    <description>The latest articles on DEV Community by Folashade Oluwaseun Oroge (@folashadeoluwaseun).</description>
    <link>https://dev.to/folashadeoluwaseun</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2791317%2F70497ad4-3209-45a9-afe3-d7876d44ef87.jpg</url>
      <title>DEV Community: Folashade Oluwaseun Oroge</title>
      <link>https://dev.to/folashadeoluwaseun</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/folashadeoluwaseun"/>
    <language>en</language>
    <item>
      <title>Automating Kubernetes Image Updates with FluxCD, Amazon ECR, and GitHub</title>
      <dc:creator>Folashade Oluwaseun Oroge</dc:creator>
      <pubDate>Wed, 17 Jun 2026 16:59:30 +0000</pubDate>
      <link>https://dev.to/folashadeoluwaseun/automating-kubernetes-image-updates-with-fluxcd-amazon-ecr-and-github-10kg</link>
      <guid>https://dev.to/folashadeoluwaseun/automating-kubernetes-image-updates-with-fluxcd-amazon-ecr-and-github-10kg</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Learn how to automatically deploy new container images to Kubernetes using FluxCD Image Automation, Amazon ECR, GitHub Apps, and GitOps principles.&lt;/p&gt;
&lt;/blockquote&gt;




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

&lt;p&gt;One of the challenges platform engineers face in Kubernetes environments is keeping application deployments synchronized with newly built container images.&lt;/p&gt;

&lt;p&gt;In many organizations, the deployment process looks something like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A developer merges code.&lt;/li&gt;
&lt;li&gt;A CI/CD pipeline builds a Docker image.&lt;/li&gt;
&lt;li&gt;The image is pushed to a container registry.&lt;/li&gt;
&lt;li&gt;Someone manually updates the image tag in Kubernetes manifests.&lt;/li&gt;
&lt;li&gt;The changes are committed and deployed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;While this works, it introduces unnecessary manual effort and increases the risk of deploying the wrong image version.&lt;/p&gt;

&lt;p&gt;FluxCD's Image Automation Toolkit solves this problem by automatically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Detecting newly published container images&lt;/li&gt;
&lt;li&gt;Selecting the correct image based on defined policies&lt;/li&gt;
&lt;li&gt;Updating Kubernetes manifests in Git&lt;/li&gt;
&lt;li&gt;Committing the changes back to the repository&lt;/li&gt;
&lt;li&gt;Allowing Flux to reconcile and deploy the new version&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This creates a fully automated GitOps workflow where Git remains the single source of truth.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem We're Solving
&lt;/h2&gt;

&lt;p&gt;Imagine your CI/CD pipeline generates image tags like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;branch-dev-1715555000-a12b34c
branch-dev-1715556000-b45d67e
branch-dev-1715557000-f12a34b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without automation, someone must:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Identify the latest image&lt;/li&gt;
&lt;li&gt;Update deployment manifests&lt;/li&gt;
&lt;li&gt;Create a pull request&lt;/li&gt;
&lt;li&gt;Merge the change&lt;/li&gt;
&lt;li&gt;Wait for deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As the number of applications grows, this quickly becomes difficult to manage.&lt;/p&gt;

&lt;p&gt;Flux Image Automation removes this operational overhead entirely.&lt;/p&gt;




&lt;h2&gt;
  
  
  Solution Architecture
&lt;/h2&gt;

&lt;p&gt;The deployment workflow looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────────────┐
│ Developer Pushes Code│
└──────────┬───────────┘
           │
           ▼
┌──────────────────────┐
│ CI/CD Pipeline       │
│ Builds Docker Image  │
└──────────┬───────────┘
           │
           ▼
┌──────────────────────┐
│ Amazon ECR           │
│ Stores New Image     │
└──────────┬───────────┘
           │
           ▼
┌──────────────────────┐
│ Flux ImageRepository │
│ Scans Registry       │
└──────────┬───────────┘
           │
           ▼
┌──────────────────────┐
│ Flux ImagePolicy     │
│ Selects Latest Tag   │
└──────────┬───────────┘
           │
           ▼
┌──────────────────────┐
│ ImageUpdateAutomation│
│ Updates Git          │
└──────────┬───────────┘
           │
           ▼
┌──────────────────────┐
│ Git Repository       │
│ Receives Commit      │
└──────────┬───────────┘
           │
           ▼
┌──────────────────────┐
│ Flux Reconciliation  │
│ Deploys New Version  │
└──────────────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






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

&lt;p&gt;Before implementing this solution, ensure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Kubernetes cluster&lt;/li&gt;
&lt;li&gt;FluxCD installed&lt;/li&gt;
&lt;li&gt;GitOps repository containing Kubernetes manifests&lt;/li&gt;
&lt;li&gt;Amazon ECR repository&lt;/li&gt;
&lt;li&gt;GitHub repository&lt;/li&gt;
&lt;li&gt;GitHub App configured for write access&lt;/li&gt;
&lt;li&gt;AWS permissions configured for Flux&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Required Flux controllers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;source-controller&lt;/li&gt;
&lt;li&gt;helm-controller&lt;/li&gt;
&lt;li&gt;image-reflector-controller&lt;/li&gt;
&lt;li&gt;image-automation-controller&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Verify Flux installation:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;► checking prerequisites
✔ Kubernetes 1.29.0 &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt;1.28.0
✔ prerequisites checks passed

► checking controllers
✔ source-controller
✔ helm-controller
✔ image-reflector-controller
✔ image-automation-controller
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 1: Create a Write-Capable Git Repository
&lt;/h2&gt;

&lt;p&gt;Unlike a standard Flux GitRepository resource, Image Automation requires write access because Flux must commit updated image tags back to Git.&lt;/p&gt;

&lt;p&gt;Create a dedicated repository source:&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;source.toolkit.fluxcd.io/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;GitRepository&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;flux-system-write&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;flux-system&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;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1m&lt;/span&gt;
  &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;github&lt;/span&gt;

  &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dev&lt;/span&gt;

  &lt;span class="na"&gt;secretRef&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;flux-system-write&lt;/span&gt;

  &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://github.com/&amp;lt;organization&amp;gt;/&amp;lt;repository&amp;gt;.git&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What This Resource Does
&lt;/h3&gt;

&lt;p&gt;This repository allows Flux to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clone the repository&lt;/li&gt;
&lt;li&gt;Modify files&lt;/li&gt;
&lt;li&gt;Create commits&lt;/li&gt;
&lt;li&gt;Push updates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without write access, Image Automation cannot function.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: Configure GitHub App Authentication
&lt;/h2&gt;

&lt;p&gt;Flux recommends using GitHub Apps instead of Personal Access Tokens (PATs).&lt;/p&gt;

&lt;p&gt;Create the authentication secret:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flux create secret githubapp flux-system-write &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--app-id&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;app-id&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--app-installation-owner&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;organization&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--app-private-key&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;path-to-private-key.pem&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The GitHub App should have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Repository Permissions

Contents: Read &amp;amp; Write
Metadata: Read
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Benefits of GitHub Apps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More secure than PATs&lt;/li&gt;
&lt;li&gt;Easier rotation&lt;/li&gt;
&lt;li&gt;Granular permissions&lt;/li&gt;
&lt;li&gt;Better auditing&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 3: Configure an Image Repository
&lt;/h2&gt;

&lt;p&gt;The ImageRepository resource tells Flux where images are stored.&lt;/p&gt;

&lt;p&gt;Example using Amazon ECR:&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;image.toolkit.fluxcd.io/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;ImageRepository&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;testservice&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;flux-system&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;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;account-id&amp;gt;.dkr.ecr.us-east-1.amazonaws.com/testservice&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;5m&lt;/span&gt;
  &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  What Happens Behind the Scenes?
&lt;/h2&gt;

&lt;p&gt;Every five minutes Flux:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Authenticates to AWS&lt;/li&gt;
&lt;li&gt;Queries the ECR repository&lt;/li&gt;
&lt;li&gt;Retrieves available tags&lt;/li&gt;
&lt;li&gt;Stores the results internally&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Check the repository status:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flux get image repository
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NAME          LAST SCAN              READY
testservice   2025-05-23T14:20:00Z  True
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 4: Create an Image Policy
&lt;/h2&gt;

&lt;p&gt;An Image Policy determines which image Flux should deploy.&lt;/p&gt;

&lt;p&gt;Example:&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;image.toolkit.fluxcd.io/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;ImagePolicy&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;testservice&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;flux-system&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;imageRepositoryRef&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;testservice&lt;/span&gt;

  &lt;span class="na"&gt;filterTags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;pattern&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;^branch-dev-(?P&amp;lt;ts&amp;gt;[0-9]+)-[0-9a-f]+$"&lt;/span&gt;
    &lt;span class="na"&gt;extract&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;$ts"&lt;/span&gt;

  &lt;span class="na"&gt;policy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;numerical&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;order&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;asc&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Understanding the Tag Strategy
&lt;/h2&gt;

&lt;p&gt;Suppose ECR contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;branch-dev-1715555000-a12b34c
branch-dev-1715556000-b45d67e
branch-dev-1715557000-f12a34b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The regex:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;^branch-dev-(?P&amp;lt;ts&amp;gt;[0-9]+)-[0-9a-f]+$
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;breaks down as:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;branch-dev&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Environment identifier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;(?P&amp;lt;ts&amp;gt;[0-9]+)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Captures timestamp&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;[0-9a-f]+&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Commit SHA&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;$&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;End of tag&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;branch-dev-1715557000-f12a34b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Flux extracts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1715557000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and uses it for comparison.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Use Numerical Policies?
&lt;/h2&gt;

&lt;p&gt;Numerical policies are ideal when image tags contain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build numbers&lt;/li&gt;
&lt;li&gt;Unix timestamps&lt;/li&gt;
&lt;li&gt;Sequential releases&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This allows Flux to determine the newest image without relying on semantic versioning.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 5: Configure Image Update Automation
&lt;/h2&gt;

&lt;p&gt;Now we tell Flux how to update Git.&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;image.toolkit.fluxcd.io/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;ImageUpdateAutomation&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;dev&lt;/span&gt;
  &lt;span class="na"&gt;namespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;flux-system&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;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;5m&lt;/span&gt;

  &lt;span class="na"&gt;sourceRef&lt;/span&gt;&lt;span class="pi"&gt;:&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;GitRepository&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;flux-system-write&lt;/span&gt;

  &lt;span class="na"&gt;git&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;checkout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;branch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dev&lt;/span&gt;

    &lt;span class="na"&gt;commit&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;author&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;FluxBot&lt;/span&gt;
        &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;flux@example.com&lt;/span&gt;

      &lt;span class="na"&gt;messageTemplate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;Automated image update&lt;/span&gt;

        &lt;span class="s"&gt;Automation name: {{ .AutomationObject }}&lt;/span&gt;

        &lt;span class="s"&gt;Files:&lt;/span&gt;
        &lt;span class="s"&gt;{{ range $filename, $_ := .Changed.FileChanges -}}&lt;/span&gt;
        &lt;span class="s"&gt;- {{ $filename }}&lt;/span&gt;
        &lt;span class="s"&gt;{{ end -}}&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;branch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;image-update-dev&lt;/span&gt;

  &lt;span class="na"&gt;update&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;./apps/dev&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  How Image Update Automation Works
&lt;/h2&gt;

&lt;p&gt;Every five minutes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Clone repository&lt;/li&gt;
&lt;li&gt;Scan manifests under &lt;code&gt;./apps/dev&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Locate image policy markers&lt;/li&gt;
&lt;li&gt;Update image tags&lt;/li&gt;
&lt;li&gt;Commit changes&lt;/li&gt;
&lt;li&gt;Push changes to GitHub&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This completely removes the need for manual image version updates.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 6: Configure HelmRelease for Automation
&lt;/h2&gt;

&lt;p&gt;Flux requires a marker showing where image updates should occur.&lt;/p&gt;

&lt;p&gt;Example:&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;helm.toolkit.fluxcd.io/v2&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;HelmRelease&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;core&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;values&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

    &lt;span class="na"&gt;testservice&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;tag&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;branch-dev&lt;/span&gt; &lt;span class="c1"&gt;# {"$imagepolicy": "flux-system:testservice:tag"}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The comment is critical:&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="c1"&gt;# {"$imagepolicy": "flux-system:testservice:tag"}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tells Flux:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Update this value whenever the ImagePolicy selects a newer tag."&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  What Happens During an Update?
&lt;/h2&gt;

&lt;p&gt;Current manifest:&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;tag&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;branch-dev-1715555000-a12b34c&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;New image pushed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;branch-dev-1715557000-f12a34b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Flux updates the file automatically:&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;tag&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;branch-dev-1715557000-f12a34b&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and commits the change.&lt;/p&gt;




&lt;h2&gt;
  
  
  Real-World Deployment Example
&lt;/h2&gt;

&lt;p&gt;Let's walk through a deployment.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1
&lt;/h3&gt;

&lt;p&gt;Developer merges code into the development branch.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2
&lt;/h3&gt;

&lt;p&gt;CI/CD builds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;branch-dev-1715557000-f12a34b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3
&lt;/h3&gt;

&lt;p&gt;Image is pushed to ECR.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4
&lt;/h3&gt;

&lt;p&gt;ImageRepository detects the new tag.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5
&lt;/h3&gt;

&lt;p&gt;ImagePolicy determines it is the newest valid image.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 6
&lt;/h3&gt;

&lt;p&gt;ImageUpdateAutomation updates Git.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 7
&lt;/h3&gt;

&lt;p&gt;Flux detects the Git commit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 8
&lt;/h3&gt;

&lt;p&gt;HelmRelease deploys the updated image.&lt;/p&gt;

&lt;p&gt;The application is now running the latest version without any engineer modifying a deployment manifest.&lt;/p&gt;




&lt;h2&gt;
  
  
  Multi-Environment Strategy
&lt;/h2&gt;

&lt;p&gt;One of the biggest advantages of Flux Image Automation is environment separation.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Development
branch-dev-*

Staging
branch-staging-*

Production
release-*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can create separate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ImageRepositories&lt;/li&gt;
&lt;li&gt;ImagePolicies&lt;/li&gt;
&lt;li&gt;ImageUpdateAutomations&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;for each environment.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Developers to deploy rapidly in Development&lt;/li&gt;
&lt;li&gt;QA teams to validate releases in Staging&lt;/li&gt;
&lt;li&gt;Production deployments to remain tightly controlled&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Monitoring and Troubleshooting
&lt;/h2&gt;

&lt;h2&gt;
  
  
  View Image Repositories
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flux get image repository
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  View Image Policies
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flux get image policy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NAME          LATEST IMAGE
testservice   branch-dev-1715557000-f12a34b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  View Image Automations
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flux get image update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Force a Repository Scan
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flux reconcile image repository testservice
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Force Image Automation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;flux reconcile image update core-us-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Check Automation Logs
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl logs &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-n&lt;/span&gt; flux-system &lt;span class="se"&gt;\&lt;/span&gt;
deployment/image-automation-controller
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Benefits of Flux Image Automation
&lt;/h2&gt;

&lt;h2&gt;
  
  
  GitOps Compliant
&lt;/h2&gt;

&lt;p&gt;All deployment changes remain in Git.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fully Auditable
&lt;/h2&gt;

&lt;p&gt;Every image promotion becomes a commit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reduced Operational Overhead
&lt;/h3&gt;

&lt;p&gt;No more manual image tag updates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Faster Deployments
&lt;/h2&gt;

&lt;p&gt;New images reach Kubernetes automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  Environment Control
&lt;/h2&gt;

&lt;p&gt;Different environments can follow different promotion strategies.&lt;/p&gt;




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

&lt;p&gt;FluxCD Image Automation provides a powerful GitOps-native approach to continuous deployment. By combining Amazon ECR, GitHub Apps, ImageRepository, ImagePolicy, ImageUpdateAutomation, and HelmRelease resources, teams can automatically promote container images while keeping Git as the single source of truth.&lt;/p&gt;

&lt;p&gt;The result is a deployment workflow that is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automated&lt;/li&gt;
&lt;li&gt;Auditable&lt;/li&gt;
&lt;li&gt;Scalable&lt;/li&gt;
&lt;li&gt;Secure&lt;/li&gt;
&lt;li&gt;GitOps compliant&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For organizations running multiple Kubernetes environments, this pattern significantly reduces operational effort while improving deployment consistency and reliability.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>fluxcd</category>
      <category>github</category>
      <category>devops</category>
    </item>
    <item>
      <title>DevOps vs SRE vs Platform Engineering: What’s the Difference?</title>
      <dc:creator>Folashade Oluwaseun Oroge</dc:creator>
      <pubDate>Mon, 26 Jan 2026 08:15:27 +0000</pubDate>
      <link>https://dev.to/folashadeoluwaseun/devops-vs-sre-vs-platform-engineering-whats-the-difference-fbp</link>
      <guid>https://dev.to/folashadeoluwaseun/devops-vs-sre-vs-platform-engineering-whats-the-difference-fbp</guid>
      <description>&lt;p&gt;In this guide, I will walk you through the distinctions among DevOps, Site Reliability Engineering (SRE), and Platform Engineering.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fki31kh7k1mvv6fd54zg4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fki31kh7k1mvv6fd54zg4.png" alt="An infograhic description of DevOps,SRE and Platform Engineering" width="800" height="336"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As the software systems to be worked on get bigger, the teams will have to deliver faster and still be able to maintain the system's stability. Each of the DevOps, SRE, and Platform Engineering will have its unique way of solving this issue.&lt;/p&gt;

&lt;h2&gt;
  
  
  DevOps
&lt;/h2&gt;

&lt;p&gt;DevOps can be considered as a culture and a collection of methods that are directed to improving the compatibility between the development and operations teams.&lt;br&gt;
It puts a major emphasis on automation, continuous integration and continuous delivery pipelines, infrastructure as code, and monitoring as it helps the teams to ship software faster and more reliably.&lt;br&gt;
👉 DevOps is all about speed and teamwork.&lt;/p&gt;

&lt;h2&gt;
  
  
  Site Reliability Engineering (SRE)
&lt;/h2&gt;

&lt;p&gt;SRE entails the application of software engineering principles to operations with a strong focus on reliability.&lt;br&gt;
SRE, through activities such as monitoring, incident management, SLIs, SLOs, and error budgets to keep the systems stable, allowing the teams to work fast.&lt;br&gt;
👉 SRE is concerned with reliability and system stability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Platform Engineering
&lt;/h2&gt;

&lt;p&gt;Platform Engineering is about the creation of internal platforms that make the developer's job of building, deploying, and operating software easier.&lt;br&gt;
Continuous self-service tools and the provision of standardized infrastructure by the platform teams lead to the reduction of complexity and the simultaneous improvement of developer experience at scale.&lt;br&gt;
👉 Platform Engineering mainly targets developer experience and scalability.&lt;/p&gt;

&lt;h2&gt;
  
  
  Differences at the Core
&lt;/h2&gt;

&lt;p&gt;The main difference between the three approaches is that each one of them has its own priority.&lt;/p&gt;

&lt;p&gt;DevOps is concerned with the removal of barriers and speeding up the delivery process through cooperation and automation.&lt;br&gt;
SRE does the opposite by securing production through the specification and enforcement of reliability targets.&lt;br&gt;
Platform Engineering goes the long road of building reusable platforms that give the teams the onward march of speed without the headache of infrastructure management.&lt;/p&gt;

&lt;p&gt;To put it simply:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DevOps is the one that inquires, “How can we give out the product faster?”&lt;/li&gt;
&lt;li&gt;SRE is the one that inquires, “What is the level of reliability of the system?”&lt;/li&gt;
&lt;li&gt;Platform Engineering is the one that inquires, “How friendly is this for developers?”&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;DevOps provides the benefit of speed.&lt;br&gt;
SRE maintains the drawback of being able to produce only stable versions.&lt;br&gt;
Platform Engineering overlays both processes with the proper infrastructure.&lt;/p&gt;

&lt;p&gt;They are the best when they are collaborating and not when they are working separately. The real benefit comes from understanding when and how to use each approach as your systems and teams grow.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>sre</category>
      <category>platformeng</category>
      <category>software</category>
    </item>
    <item>
      <title>How I Deployed WordPress on an Azure VM with Nginx and PHP – With a Custom Welcome Page</title>
      <dc:creator>Folashade Oluwaseun Oroge</dc:creator>
      <pubDate>Sat, 17 May 2025 01:21:09 +0000</pubDate>
      <link>https://dev.to/folashadeoluwaseun/setting-up-wordpress-with-nginx-on-ubuntu-with-a-custom-welcome-page-3pad</link>
      <guid>https://dev.to/folashadeoluwaseun/setting-up-wordpress-with-nginx-on-ubuntu-with-a-custom-welcome-page-3pad</guid>
      <description>&lt;p&gt;In this guide, I’ll walk you through how I set up &lt;strong&gt;WordPress&lt;/strong&gt; on an &lt;strong&gt;Ubuntu&lt;/strong&gt; server on &lt;strong&gt;Azure&lt;/strong&gt; using &lt;strong&gt;Nginx&lt;/strong&gt; and added a &lt;strong&gt;custom&lt;/strong&gt; welcome page to make the site more personal.&lt;/p&gt;




&lt;h3&gt;
  
  
  Architectural Diagram
&lt;/h3&gt;

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

&lt;h3&gt;
  
  
  Below are the steps I Took:
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Installed Nginx, PHP, and MySQL
&lt;/h4&gt;

&lt;p&gt;I installed the core components needed to serve WordPress:&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="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;nginx php php-mysql mysql-server &lt;span class="nt"&gt;-y&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. Downloaded and Set Up WordPress
&lt;/h4&gt;

&lt;p&gt;I downloaded WordPress and extracted it into /var/www/html:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;wget https://wordpress.org/latest.tar.gz
tar -xvzf latest.tar.gz
sudo mv wordpress/* /var/www/html/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Configured Nginx
&lt;/h4&gt;

&lt;p&gt;I edited the Nginx default configuration to support PHP and WordPress:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo nano /etc/nginx/sites-available/default
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I made sure to set the index directive like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;index index.html index.htm index.php;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures my custom index.html is shown before WordPress’s index.php&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Created a Custom Welcome Page
&lt;/h4&gt;

&lt;p&gt;Inside &lt;code&gt;/var/www/html/&lt;/code&gt;, I created an &lt;code&gt;index.html&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset="UTF-8"&amp;gt;
    &amp;lt;title&amp;gt;Welcome&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body style="text-align: center; font-family: sans-serif; padding: 50px;"&amp;gt;
    &amp;lt;h1&amp;gt;Welcome to Folashade's Core Dev Test!&amp;lt;/h1&amp;gt;
    &amp;lt;p&amp;gt;This is a personal test environment where WordPress is installed.&amp;lt;/p&amp;gt;
    &amp;lt;a href="/wp-login.php" style="display: inline-block; padding: 10px 20px; background: #0073aa; color: white; text-decoration: none; border-radius: 5px;"&amp;gt;Login to WordPress&amp;lt;/a&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;

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

&lt;/div&gt;



&lt;h4&gt;
  
  
  5. Restarted Nginx
&lt;/h4&gt;

&lt;p&gt;To apply the changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl restart nginx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then I go to &lt;code&gt;http://&amp;lt;server-ip&amp;gt;&lt;/code&gt; , I see a clean, welcoming landing page.&lt;/p&gt;

&lt;p&gt;Clicking the link takes me to the full WordPress setup.&lt;/p&gt;

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

&lt;p&gt;This setup gives me a simple branded homepage while keeping full access to WordPress in the background.&lt;/p&gt;

</description>
      <category>nginx</category>
      <category>wordpress</category>
      <category>devops</category>
      <category>beginners</category>
    </item>
    <item>
      <title>From FastAPI to Render: Building a Number Classification API with Docker.</title>
      <dc:creator>Folashade Oluwaseun Oroge</dc:creator>
      <pubDate>Sat, 08 Feb 2025 00:04:32 +0000</pubDate>
      <link>https://dev.to/folashadeoluwaseun/from-fastapi-to-render-building-a-number-classification-api-with-docker-19na</link>
      <guid>https://dev.to/folashadeoluwaseun/from-fastapi-to-render-building-a-number-classification-api-with-docker-19na</guid>
      <description>&lt;p&gt;In this article, I'll show you how to build a &lt;strong&gt;Number Classification API&lt;/strong&gt; using &lt;strong&gt;FastAPI&lt;/strong&gt;, &lt;strong&gt;Docker&lt;/strong&gt;, and &lt;strong&gt;Render&lt;/strong&gt;. The API classifies numbers based on mathematical properties (prime, perfect, Armstrong, odd/even) and fetches fun facts from the &lt;strong&gt;Numbers API&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%2F8zyw6uhd7pg6c21jakca.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8zyw6uhd7pg6c21jakca.gif" alt="API Workflow" width="760" height="570"&gt;&lt;/a&gt;&lt;br&gt;
GIF by &lt;a href="https://dribbble.com/augustux" rel="noopener noreferrer"&gt;Augustus&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Tools Used
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;FastAPI&lt;/strong&gt; – for building the API.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docker&lt;/strong&gt; – for containerization.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Render&lt;/strong&gt; – for deployment.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Step 1: Setting Up the Project
&lt;/h2&gt;

&lt;p&gt;Clone the project and 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;git clone https://github.com/Fola-Git/number-classification-api.git
&lt;span class="nb"&gt;cd &lt;/span&gt;number-classification-api
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Building the API with FastApi
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Create the API Endpoint
&lt;/h3&gt;

&lt;p&gt;The core of our API is a single route &lt;code&gt;/api/classify-number?number=&amp;lt;num&amp;gt;&lt;/code&gt; that checks whether a number is prime, perfect, Armstrong, or odd/even. Additionally, it fetches a fun fact about the number from the Numbers API.&lt;/p&gt;

&lt;p&gt;Here’s the core logic in &lt;code&gt;app.py&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nd"&gt;@app.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/classify-number&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;classify_number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;number&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;classification&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;classify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;fact&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fetch_number_fact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&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;result&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;classify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Determine if a number is prime, perfect, Armstrong, and odd/even.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;is_prime&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;is_prime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;is_perfect&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;is_perfect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;is_armstrong&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;is_armstrong&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;is_even&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;fetch_number_fact&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://numbersapi.com/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&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;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;No fact found.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# Helper functions (is_prime, is_perfect, is_armstrong) defined in the repo
&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Dockerizing the Application
&lt;/h2&gt;

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

&lt;p&gt;We will containerize the application to ensure it runs in a consistent environment.&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="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; python:3.10&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; requirements.txt .&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 8000&lt;/span&gt;

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"]&lt;/span&gt;

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

&lt;/div&gt;



&lt;h3&gt;
  
  
  🔄 Creating &lt;code&gt;docker-compose.yml&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;To manage the container easily, we use Docker Compose:&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'&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;web&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;8000:8000"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To build and run the container, use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker-compose up --build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🚀 Step 4: Deploying with Render
&lt;/h3&gt;

&lt;p&gt;📌 Push Your Code to GitHub&lt;/p&gt;

&lt;p&gt;Run the following commands to commit and push 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;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"&lt;/span&gt;
git push origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🚀 Deploy on Render
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Sign in to &lt;a href="https://render.com" rel="noopener noreferrer"&gt;Render&lt;/a&gt;.
&lt;/li&gt;
&lt;li&gt;Create a &lt;strong&gt;New Web Service&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Connect your &lt;strong&gt;GitHub repository&lt;/strong&gt;.
&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;FastAPI&lt;/strong&gt; as the framework.
&lt;/li&gt;
&lt;li&gt;Set the start command:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  uvicorn app:app &lt;span class="nt"&gt;--host&lt;/span&gt; 0.0.0.0 &lt;span class="nt"&gt;--port&lt;/span&gt; 8000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Click Deploy and Your API will be live!.&lt;/p&gt;

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

&lt;p&gt;In this guide, we built a &lt;strong&gt;FastAPI Number Classification API&lt;/strong&gt;, containerized it with &lt;strong&gt;Docker&lt;/strong&gt;, and deployed it on &lt;strong&gt;Render&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Feel free to explore and enhance the project with additional features. Check out my repository for the full structure: &lt;a href="https://github.com/Fola-Git/number-classification-api" rel="noopener noreferrer"&gt;Fola-Git&lt;/a&gt;.  &lt;/p&gt;

&lt;p&gt;You can also modify online templates to improve the design and functionality. Happy coding! &lt;/p&gt;

</description>
      <category>docker</category>
      <category>devops</category>
      <category>api</category>
      <category>github</category>
    </item>
    <item>
      <title>How I Configured NGINX to Serve My Custom HTML Page: A First-Timer's Guide</title>
      <dc:creator>Folashade Oluwaseun Oroge</dc:creator>
      <pubDate>Fri, 31 Jan 2025 14:02:31 +0000</pubDate>
      <link>https://dev.to/folashadeoluwaseun/how-i-configured-nginx-to-serve-my-custom-html-page-a-first-timers-guide-2aje</link>
      <guid>https://dev.to/folashadeoluwaseun/how-i-configured-nginx-to-serve-my-custom-html-page-a-first-timers-guide-2aje</guid>
      <description>&lt;p&gt;Configuring NGINX to serve applications is a fundamental skill for anyone starting their &lt;strong&gt;DevOps journey&lt;/strong&gt;. Whether you're setting up a web server for a personal project or diving into Cloud Infrastructure, it's a rewarding challenge. Recently, I decided to &lt;strong&gt;deploy a custom HTML page&lt;/strong&gt; on an &lt;strong&gt;Ubuntu VM&lt;/strong&gt; in &lt;strong&gt;Azure&lt;/strong&gt; using NGINX. To keep things smooth and effortless, I tweaked a template online to give my site a personalized touch. In this article, I’ll take you through my setup process, the obstacles I encountered, and the valuable lessons I learned along the way.&lt;/p&gt;




&lt;p&gt;My first step was to search online for free templates, and I came across &lt;strong&gt;&lt;a href="https://www.free-css.com/" rel="noopener noreferrer"&gt;FreeCSS&lt;/a&gt;&lt;/strong&gt;. After browsing through the options, I found one that I liked—&lt;strong&gt;&lt;a href="https://www.free-css.com/free-css-templates/page296/browny" rel="noopener noreferrer"&gt;Browny&lt;/a&gt;&lt;/strong&gt;. You can check it out too!  &lt;/p&gt;

&lt;p&gt;I then modified the code to suit my taste, updating the content and styling to match my vision. It was a fun way to personalize the site without starting from scratch! 🚀&lt;/p&gt;

&lt;p&gt;Next, I created a new &lt;strong&gt;Ubuntu VM&lt;/strong&gt; on &lt;strong&gt;Azure&lt;/strong&gt;, but feel free to choose any cloud platform you prefer. During the setup, I customized the settings to suit my needs and ensured that &lt;strong&gt;port 80&lt;/strong&gt; was enabled to allow web traffic, as this was a test environment and not for production. For a production setup, I would recommend implementing additional security measures.&lt;/p&gt;

&lt;p&gt;Once the VM was up and running, I ssh to it using &lt;strong&gt;MobaXterm&lt;/strong&gt; to access the terminal. You can also use &lt;strong&gt;SSH&lt;/strong&gt; or any other terminal tool of your choice.&lt;/p&gt;




&lt;h3&gt;
  
  
  Installing NGINX on Ubuntu
&lt;/h3&gt;

&lt;p&gt;With the VM up and running, I first ran an update on it before installing &lt;strong&gt;NGINX&lt;/strong&gt;, a powerful and lightweight web server that can handle traffic loads efficiently. Here's how you do it:&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="c"&gt;# Updates the package list to ensure you're installing the latest versions of Ubuntu&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;nginx &lt;span class="nt"&gt;-y&lt;/span&gt;   &lt;span class="c"&gt;# Installs NGINX and automatically confirms the installation without further prompts&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status nginx &lt;span class="c"&gt;#To confirm if NGINX is running&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;h2&gt;
  
  
  File Structure Overview
&lt;/h2&gt;

&lt;p&gt;Below is the file structure of the application I used to better understand how everything fits together:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/var/www/html/Folashade_HNG0/
│── index.html
│── assets/
│   ├── css/
│   ├── js/
│   ├── images/
│   ├── fonts/
│   ├── download/
│   ├── logo/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, I navigated to the directory where my application files are stored using the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /var/www/html/Folashade_HNG0  &lt;span class="c"&gt;# Moves to this directory&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;nano index.html             &lt;span class="c"&gt;# Where to place your `index.html` code&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To save the changes, I pressed &lt;strong&gt;Ctrl + O&lt;/strong&gt; (to write the changes), then &lt;strong&gt;Enter&lt;/strong&gt; to confirm. Finally, I exited by pressing &lt;strong&gt;Ctrl + X&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring NGINX to Serve My Custom Page
&lt;/h2&gt;

&lt;p&gt;With the HTML files and other necessary assets placed in the appropriate folder, it was time to configure &lt;strong&gt;NGINX&lt;/strong&gt; to serve the custom page. &lt;/p&gt;

&lt;p&gt;I navigated to the NGINX 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;cd&lt;/span&gt; /etc/nginx
&lt;span class="nb"&gt;sudo &lt;/span&gt;nano sites-enabled/default  &lt;span class="c"&gt;# where to modify the defauly NGINX configuration&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I edited the default NGINX configuration file located at &lt;code&gt;/etc/nginx/sites-available/default&lt;/code&gt; to point to the directory where I uploaded my files.&lt;/p&gt;

&lt;p&gt;Here’s how I updated the configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;server_name&lt;/span&gt; &lt;span class="s"&gt;&amp;lt;your-server-ip&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;# Root directory for your site&lt;/span&gt;
    &lt;span class="kn"&gt;root&lt;/span&gt; &lt;span class="n"&gt;/var/www/html/Folashade_HNG0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;# Default index file&lt;/span&gt;
    &lt;span class="kn"&gt;index&lt;/span&gt; &lt;span class="s"&gt;index.html&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;# Serve the main site content&lt;/span&gt;
    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;try_files&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt; &lt;span class="nv"&gt;$uri&lt;/span&gt;&lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;# Serve static assets (CSS, JS, images, fonts, logos)&lt;/span&gt;
    &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/assets/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;root&lt;/span&gt; &lt;span class="n"&gt;/var/www/html/Folashade_HNG0&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;p&gt;After saving the changes, I ran the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo nginx -t                 # Check if configuration is successful or give error if any issues found
sudo systemctl restart nginx  # Restart NGINX
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, my custom page was live! By visiting the VM’s IP address, I could see the page I had set up.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Challenges Faced
&lt;/h2&gt;

&lt;p&gt;At first, I couldn’t access my HTML files because the NGINX configuration pointed to the wrong directory. NGINX couldn’t find the files, leading to errors when trying to load the page. Once I identified the issue, I updated the NGINX config to correctly point to the folder where my HTML files were located. After making this change, everything worked as expected, and my custom page was live!&lt;br&gt;
&lt;strong&gt;Writing this article&lt;/strong&gt; was a bit tricky, I had to explain technical details in a way that would be easy for beginners to understand, while still covering all the important steps. However, it helped me better understand troubleshooting and thinking critically about each step.&lt;br&gt;
As the demand for cloud computing and automation grows, skills like these are becoming essential for professionals looking to work in roles such as &lt;a href="https://hng.tech/hire/devops-engineers" rel="noopener noreferrer"&gt;DevOps Engineers&lt;/a&gt; and &lt;a href="https://hng.tech/hire/cloud-engineers" rel="noopener noreferrer"&gt;Cloud Engineers&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Completing this project was an excellent learning experience. It helped me get hands-on experience with server configuration and troubleshooting, which are key skills in web hosting and DevOps.&lt;/p&gt;

&lt;p&gt;I hope this guide helps you on your path to mastering web server setup, and I encourage you to explore further as you expand your knowledge in Cloud and DevOps technologies.&lt;/p&gt;

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