<?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: Shashank Morappanavar</title>
    <description>The latest articles on DEV Community by Shashank Morappanavar (@shashank215).</description>
    <link>https://dev.to/shashank215</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%2F2840083%2Fdaa59554-6a3e-4249-b681-18c05a0a10d7.jpg</url>
      <title>DEV Community: Shashank Morappanavar</title>
      <link>https://dev.to/shashank215</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shashank215"/>
    <language>en</language>
    <item>
      <title>🚫 Kubernetes Ingress-NGINX Deprecation: Why You Should Stop Using It &amp; What to Choose Instead</title>
      <dc:creator>Shashank Morappanavar</dc:creator>
      <pubDate>Sat, 15 Nov 2025 11:16:00 +0000</pubDate>
      <link>https://dev.to/shashank215/kubernetes-ingress-nginx-deprecation-why-you-should-stop-using-it-what-to-choose-instead-2nmo</link>
      <guid>https://dev.to/shashank215/kubernetes-ingress-nginx-deprecation-why-you-should-stop-using-it-what-to-choose-instead-2nmo</guid>
      <description>&lt;p&gt;For years, Ingress-NGINX was the default choice for exposing Kubernetes applications.&lt;br&gt;
It was simple, open-source, widely supported, and became the “standard” way for beginners to run ingress traffic.&lt;/p&gt;

&lt;p&gt;But the Kubernetes world has changed — Ingress-NGINX is no longer recommended, and many organizations have already moved away from it. Even the maintainers have reduced active support, major features are frozen, and the project has publicly acknowledged serious architectural limitations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This article explains:&lt;/strong&gt;&lt;br&gt;
Why Ingress-NGINX is being deprecated&lt;br&gt;
What changed in Kubernetes networking&lt;br&gt;
History behind maintainers stepping away&lt;br&gt;
Technical limitations&lt;br&gt;
Better alternatives to migrate to&lt;/p&gt;

&lt;h2&gt;
  
  
  📉 1. Why We Are Deprecating Ingress-NGINX
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1.1. The project has reached a maintenance bottleneck&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ingress-NGINX is an extremely complex controller built on top of NGINX’s Lua subsystem, template rendering, and custom patches. Over time:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Maintaining compatibility with upstream NGINX became harder&lt;/p&gt;

&lt;p&gt;Patching security vulnerabilities required deep C-level knowledge&lt;/p&gt;

&lt;p&gt;Very few contributors had the necessary expertise&lt;/p&gt;

&lt;p&gt;Maintainers themselves stated that the project has a very small active maintainer base and cannot guarantee long-term updates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.2. NGINX (upstream) did not collaborate actively&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key reasons maintainers mentioned:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Lack of official support from NGINX Inc.&lt;/p&gt;

&lt;p&gt;Breaking changes in NGINX requiring heavy rewrites&lt;/p&gt;

&lt;p&gt;No guarantee of long-term API compatibility&lt;/p&gt;

&lt;p&gt;Because of this, the project constantly lagged behind upstream NGINX releases.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.3. Ingress API became too limiting&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kubernetes' built-in Ingress API is intentionally minimal. It does not support:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Advanced routing&lt;/p&gt;

&lt;p&gt;Authentication flows&lt;/p&gt;

&lt;p&gt;Canary deployments&lt;/p&gt;

&lt;p&gt;Rate limiting&lt;/p&gt;

&lt;p&gt;Circuit breaking&lt;/p&gt;

&lt;p&gt;Traffic splitting&lt;/p&gt;

&lt;p&gt;mTLS&lt;/p&gt;

&lt;p&gt;TCP/UDP routing&lt;/p&gt;

&lt;p&gt;To support these, Ingress-NGINX had to build hundreds of annotations, which became impossible to maintain.&lt;/p&gt;

&lt;p&gt;Users ended up with:&lt;/p&gt;

&lt;p&gt;nginx.ingress.kubernetes.io/proxy-body-size: "0"&lt;br&gt;
nginx.ingress.kubernetes.io/rewrite-target: "/"&lt;br&gt;
nginx.ingress.kubernetes.io/ssl-redirect: "false"&lt;br&gt;
...&lt;br&gt;
(50 more annotations)&lt;/p&gt;

&lt;p&gt;This complexity is exactly why Kubernetes introduced Gateway API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.4. The future of Kubernetes Networking → Gateway API&lt;/strong&gt;&lt;br&gt;
Gateway API (GA since 2023) replaces Ingress.&lt;/p&gt;

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

&lt;p&gt;Standardized CRDs beyond Ingress&lt;/p&gt;

&lt;p&gt;Better extensibility for vendors&lt;/p&gt;

&lt;p&gt;First-class support for L4/L7 traffic controls&lt;/p&gt;

&lt;p&gt;Cleaner routing&lt;/p&gt;

&lt;p&gt;Cross-namespace &amp;amp; multi-tenant support&lt;/p&gt;

&lt;p&gt;No annotations hack&lt;/p&gt;

&lt;p&gt;Ingress-NGINX cannot evolve into Gateway API cleanly — it’s stuck with the old model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.5. Performance &amp;amp; architectural limitations&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NGINX-based controllers have:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;High memory consumption&lt;/p&gt;

&lt;p&gt;Less efficient multi-tenant isolation&lt;/p&gt;

&lt;p&gt;Slow reload times (config reloads entire NGINX)&lt;/p&gt;

&lt;p&gt;No native support for modern protocols (HTTP/3, gRPC-web, etc.)&lt;/p&gt;

&lt;p&gt;Modern proxies like Envoy outperform NGINX heavily in Kubernetes-native environments.&lt;/p&gt;

&lt;h2&gt;
  
  
  🕰️ 2. History: Why Maintainers Stopped / Reduced Support
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Phase 1: 2016–2019&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ingress-NGINX was the most popular ingress option because:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Kubernetes did not have Gateway API&lt;/p&gt;

&lt;p&gt;Only a few ingress controllers existed&lt;/p&gt;

&lt;p&gt;NGINX was stable and familiar&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 2: 2020–2022 — The “Annotation Hell" Era&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Dev teams struggled maintaining 100+ annotations.&lt;br&gt;
Features were overlapping, incompatible, or buggy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 3: 2023 — Gateway API announced stable&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ingress API became a legacy interface.&lt;/p&gt;

&lt;p&gt;Controller maintainers openly discussed:&lt;/p&gt;

&lt;p&gt;“Ingress is too limiting&lt;br&gt;
We cannot implement advanced traffic controls&lt;br&gt;
Gateway API will replace this.”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phase 4: 2024-2025 — Reduced active maintenance&lt;/strong&gt;&lt;br&gt;
Maintainers publicly noted:&lt;/p&gt;

&lt;p&gt;Huge backlog of issues&lt;/p&gt;

&lt;p&gt;Not enough skilled contributors&lt;/p&gt;

&lt;p&gt;Major CVEs pending for months&lt;/p&gt;

&lt;p&gt;Nginx upstream incompatibilities&lt;/p&gt;

&lt;p&gt;Move toward Kubernetes-native proxies&lt;/p&gt;

&lt;p&gt;While not “archived”, the project is effectively in slow maintenance mode — not evolving and not future-proof.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚫 3. Technical Reasons You Should Stop Using Ingress-NGINX
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;3.1. Annotations are fragile and vendor-specific&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Your configuration is locked to NGINX.&lt;br&gt;
If you switch controller → everything breaks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.2. Lack of advanced traffic management&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compared to modern ingress options, NGINX lacks:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Canary releases&lt;/p&gt;

&lt;p&gt;Weighted routing&lt;/p&gt;

&lt;p&gt;Retry policies&lt;/p&gt;

&lt;p&gt;Circuit breakers&lt;/p&gt;

&lt;p&gt;mTLS per route&lt;/p&gt;

&lt;p&gt;Traffic shadowing&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.3. Scaling causes full reloads&lt;/strong&gt;&lt;br&gt;
Every config change → restarts the entire NGINX worker group.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This causes:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;latency spikes&lt;/p&gt;

&lt;p&gt;dropped connections&lt;/p&gt;

&lt;p&gt;slow rollouts&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3.4. No native multi-tenant support&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NGINX has no concept of:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;cross-namespace routing&lt;/p&gt;

&lt;p&gt;delegated traffic governance&lt;/p&gt;

&lt;p&gt;namespace isolation policies&lt;/p&gt;

&lt;p&gt;Gateway API fixes this.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⭐ 4. Best Alternatives to Ingress-NGINX (2025)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;✅ 1. Envoy-based Proxies&lt;/strong&gt;&lt;br&gt;
Istio Gateway / Envoy Gateway&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Microservices&lt;/p&gt;

&lt;p&gt;Zero-downtime routing&lt;/p&gt;

&lt;p&gt;Advanced L7 traffic engineering&lt;/p&gt;

&lt;p&gt;Benefits:&lt;/p&gt;

&lt;p&gt;Native Gateway API support&lt;/p&gt;

&lt;p&gt;No reloads (Envoy is xDS-based)&lt;/p&gt;

&lt;p&gt;mTLS, retries, canaries, traffic splitting built-in&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✅ 2. Traefik&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Simpler environments&lt;/p&gt;

&lt;p&gt;Kubernetes dashboards&lt;/p&gt;

&lt;p&gt;High-performance basic routing&lt;/p&gt;

&lt;p&gt;Benefits:&lt;/p&gt;

&lt;p&gt;Native Gateway API support&lt;/p&gt;

&lt;p&gt;Auto TLS&lt;/p&gt;

&lt;p&gt;No reloads&lt;/p&gt;

&lt;p&gt;Simple CRDs&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✅ 3. HAProxy Ingress / HAProxy Gateway&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;High performance&lt;/p&gt;

&lt;p&gt;Low latency&lt;/p&gt;

&lt;p&gt;Large-scale clusters&lt;/p&gt;

&lt;p&gt;Benefits:&lt;/p&gt;

&lt;p&gt;Mature HAProxy engine&lt;/p&gt;

&lt;p&gt;Strong Gateway API roadmap&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✅ 4. NGINX Gateway Fabric (New – replaces Ingress-NGINX)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;NGINX Inc. now maintains this instead of Ingress-NGINX.&lt;/p&gt;

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

&lt;p&gt;Built for Gateway API&lt;/p&gt;

&lt;p&gt;Modern architecture&lt;/p&gt;

&lt;p&gt;Actively maintained&lt;/p&gt;

&lt;p&gt;No annotations&lt;/p&gt;

&lt;p&gt;Why it’s better:&lt;/p&gt;

&lt;p&gt;Ingress-NGINX → old, annotation hack&lt;br&gt;
NGINX Gateway Fabric → new, clean, Kubernetes-native&lt;/p&gt;

&lt;h2&gt;
  
  
  📦 5. If You Still Use Ingress-NGINX, What Should You Do?
&lt;/h2&gt;

&lt;p&gt;Short-term&lt;/p&gt;

&lt;p&gt;Lock your version&lt;/p&gt;

&lt;p&gt;Apply CVE patches manually&lt;/p&gt;

&lt;p&gt;Avoid complex annotations&lt;/p&gt;

&lt;p&gt;Long term (Recommended)&lt;/p&gt;

&lt;p&gt;Plan migration to a Gateway API controller&lt;/p&gt;

&lt;p&gt;Choose Envoy Gateway or NGINX Gateway Fabric&lt;/p&gt;

&lt;p&gt;Begin rewriting Ingress rules → Routes + Gateways&lt;/p&gt;

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

&lt;p&gt;Ingress-NGINX served the Kubernetes community incredibly well for years.&lt;br&gt;
But the world of cloud-native routing has evolved:&lt;/p&gt;

&lt;p&gt;The Ingress API is outdated&lt;/p&gt;

&lt;p&gt;NGINX architecture doesn’t fit modern service mesh needs&lt;/p&gt;

&lt;p&gt;Maintainers cannot keep up&lt;/p&gt;

&lt;p&gt;Gateway API is the future&lt;/p&gt;

&lt;p&gt;If you're starting a new project in 2025 or planning an upgrade — do not use Ingress-NGINX.&lt;br&gt;
The ecosystem is moving forward, and so should your architecture.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Shell Script to Rotate Logs, Extract Errors, and Alert Developers via Email (with Datadog Integration)</title>
      <dc:creator>Shashank Morappanavar</dc:creator>
      <pubDate>Sun, 27 Jul 2025 12:55:31 +0000</pubDate>
      <link>https://dev.to/shashank215/shell-script-to-rotate-logs-extract-errors-and-alert-developers-via-email-with-datadog-196c</link>
      <guid>https://dev.to/shashank215/shell-script-to-rotate-logs-extract-errors-and-alert-developers-via-email-with-datadog-196c</guid>
      <description>&lt;p&gt;&lt;strong&gt;Production apps generate thousands of log lines every day. If not managed properly:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Logs eat up disk space.&lt;/li&gt;
&lt;li&gt;Critical errors get buried in noise.&lt;/li&gt;
&lt;li&gt;Developers find out about issues too late.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, I built a shell-powered automation that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rotates and archives logs daily&lt;/li&gt;
&lt;li&gt;Extracts ERROR logs from gzipped archives&lt;/li&gt;
&lt;li&gt;Emails those errors to developers&lt;/li&gt;
&lt;li&gt;Sends success/failure status to Datadog Logs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Use Case:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine your app (Invoice) runs in production and writes logs to /var/log/invoice/. Every night, you want to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rotate those logs and gzip them&lt;/li&gt;
&lt;li&gt;Save them to /var/backups/logs/invoice/YYYY-MM-DD&lt;/li&gt;
&lt;li&gt;Extract only ERROR lines&lt;/li&gt;
&lt;li&gt;Email the developers a copy of that error log&lt;/li&gt;
&lt;li&gt;Push a status message to Datadog for audit and alerts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The Script&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;#!/bin/bash
set -euo pipefail

APP_NAME="invoice"
LOG_DIR="/var/log/$APP_NAME"
ARCHIVE_DIR="/var/backups/logs/$APP_NAME"
TODAY=$(date +%F)
ERROR_FILE="/tmp/${APP_NAME}_errors_$TODAY.log"
EMAIL_SUBJECT="[$APP_NAME] Errors Detected - $TODAY"
DEVELOPER_EMAILS=("dev1@example.com" "dev2@example.com")
DD_API_KEY="your_datadog_api_key"
DD_LOG_TAG="error-alert"

mkdir -p "$ARCHIVE_DIR/$TODAY"

log_to_datadog() {
  local message="$1"
  curl -X POST "https://http-intake.logs.datadoghq.com/v1/input" \
    -H "Content-Type: application/json" \
    -H "DD-API-KEY: $DD_API_KEY" \
    -d "{
      \"ddsource\": \"shell-script\",
      \"service\": \"$APP_NAME\",
      \"hostname\": \"$(hostname)\",
      \"message\": \"$message\",
      \"tags\": [\"env:prod\",\"task:$DD_LOG_TAG\"]
    }" &amp;gt;/dev/null 2&amp;gt;&amp;amp;1
}

send_error_email() {
  for email in "${DEVELOPER_EMAILS[@]}"; do
    mailx -s "$EMAIL_SUBJECT" -a "$ERROR_FILE" "$email" &amp;lt;&amp;lt;EOF
Hi Dev,

Errors were detected in today's logs for [$APP_NAME].

Please check the attached error log file for investigation.

Regards,
Automated Log Monitor
EOF
  done
}

echo " Rotating logs for $APP_NAME..."
if compgen -G "$LOG_DIR/*.log" &amp;gt; /dev/null; then
  find "$LOG_DIR" -type f -name "*.log" -exec gzip {} \;
  mv "$LOG_DIR"/*.gz "$ARCHIVE_DIR/$TODAY"
  echo " Rotated logs to $ARCHIVE_DIR/$TODAY"
  log_to_datadog " [$APP_NAME] Logs rotated successfully at $TODAY"
else
  echo " No logs to rotate."
  log_to_datadog "[$APP_NAME] No logs found for rotation on $TODAY"
fi

echo " Extracting errors..."
find "$ARCHIVE_DIR/$TODAY" -name "*.gz" -exec zgrep "ERROR" {} \; &amp;gt; "$ERROR_FILE" || true

if [ -s "$ERROR_FILE" ]; then
  echo " Found error logs. Sending alert..."
  send_error_email
  log_to_datadog " [$APP_NAME] Errors found and emailed to developers on $TODAY"
else
  echo "No errors found."
  log_to_datadog "[$APP_NAME] No errors found in logs on $TODAY"
  rm -f "$ERROR_FILE"
fi
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Schedule It With Cron&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;`# /etc/cron.d/log-monitor
0 2 * * * /opt/scripts/rotate-and-alert-errors.sh &amp;gt;&amp;gt; /var/log/log-monitor.log 2&amp;gt;&amp;amp;1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How This Helps DevOps &amp;amp; Developers&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Proactive Monitoring&lt;/strong&gt;&lt;br&gt;
No more “surprise bugs” — devs get error logs before users notice.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Disk-space Hygiene&lt;/strong&gt;&lt;br&gt;
Logs are rotated and compressed, preventing overflow.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Observability&lt;/strong&gt;&lt;br&gt;
All operations are visible in Datadog Logs. You can create monitors, dashboards, or anomaly alerts.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ul&gt;
&lt;li&gt;Build once, run forever&lt;/li&gt;
&lt;li&gt;Alert smartly, not noisily&lt;/li&gt;
&lt;li&gt;Give developers what they need, when they need it&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>productivity</category>
      <category>devops</category>
      <category>shell</category>
      <category>datadog</category>
    </item>
    <item>
      <title>🚀 How to Deploy Any WordPress Web App Using Docker</title>
      <dc:creator>Shashank Morappanavar</dc:creator>
      <pubDate>Mon, 05 May 2025 04:58:38 +0000</pubDate>
      <link>https://dev.to/shashank215/how-to-deploy-any-wordpress-web-app-using-docker-1h5c</link>
      <guid>https://dev.to/shashank215/how-to-deploy-any-wordpress-web-app-using-docker-1h5c</guid>
      <description>&lt;p&gt;If you're a developer or WordPress enthusiast looking to containerize your website for portability and ease of deployment, this step-by-step guide will walk you through the entire process—from setup to containerization.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Docker &amp;amp; Docker Compose installed&lt;/li&gt;
&lt;li&gt;A basic WordPress website (with custom plugins/themes if any)&lt;/li&gt;
&lt;li&gt;(Optional) Exported WordPress content in &lt;code&gt;.xml&lt;/code&gt; format&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;📁 &lt;strong&gt;Project Structure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Start by creating a working directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;wordpress-docker&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nt"&gt;Dockerfile&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nt"&gt;wp-content&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;   &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nt"&gt;plugins&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;│&lt;/span&gt;       &lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nt"&gt;hello-world-sample&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;
&lt;span class="err"&gt;├──&lt;/span&gt; &lt;span class="nt"&gt;wp-data&lt;/span&gt;&lt;span class="nc"&gt;.xml&lt;/span&gt;     &lt;span class="err"&gt;#&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nt"&gt;optional&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="nt"&gt;exported&lt;/span&gt; &lt;span class="nt"&gt;WordPress&lt;/span&gt; &lt;span class="nt"&gt;content&lt;/span&gt;
&lt;span class="err"&gt;└──&lt;/span&gt; &lt;span class="nt"&gt;docker-compose&lt;/span&gt;&lt;span class="nc"&gt;.yml&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🐳 &lt;strong&gt;Dockerfile for WordPress&lt;/strong&gt;&lt;br&gt;
Create a Dockerfile to extend the official WordPress image and include your custom plugin:&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; wordpress:6.5-php8.1-apache&lt;/span&gt;

&lt;span class="c"&gt;##Copy your plugin into the WordPress plugin directory&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; wp-content/plugins/hello-world-sample /var/www/html/wp-content/plugins/hello-world-sample&lt;/span&gt;

&lt;span class="c"&gt;##Fix permissions (optional)&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; www-data:www-data /var/www/html/wp-content/plugins/hello-world-sample
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🧩 &lt;strong&gt;Docker Compose File&lt;/strong&gt;&lt;br&gt;
Create docker-compose.yml to set up both WordPress and MySQL:&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;wordpress&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;8080:80"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;WORDPRESS_DB_HOST&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;db&lt;/span&gt;
      &lt;span class="na"&gt;WORDPRESS_DB_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wp_user&lt;/span&gt;
      &lt;span class="na"&gt;WORDPRESS_DB_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wp_pass&lt;/span&gt;
      &lt;span class="na"&gt;WORDPRESS_DB_NAME&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wp_db&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;wordpress_data:/var/www/html&lt;/span&gt;

  &lt;span class="na"&gt;db&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;mysql:5.7&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;always&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;MYSQL_DATABASE&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wp_db&lt;/span&gt;
      &lt;span class="na"&gt;MYSQL_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wp_user&lt;/span&gt;
      &lt;span class="na"&gt;MYSQL_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;wp_pass&lt;/span&gt;
      &lt;span class="na"&gt;MYSQL_ROOT_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rootpass&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;db_data:/var/lib/mysql&lt;/span&gt;

&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;wordpress_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;db_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🚀 &lt;strong&gt;Launch WordPress&lt;/strong&gt;&lt;br&gt;
Run this to build and start the containers:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Your site will be available at:&lt;br&gt;
&lt;a href="http://ec2-ip/wordpress" rel="noopener noreferrer"&gt;http://ec2-ip/wordpress&lt;/a&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>wordpress</category>
      <category>webdev</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
