<?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: Pavan S</title>
    <description>The latest articles on DEV Community by Pavan S (@pavan_s_7438006da5249fe71).</description>
    <link>https://dev.to/pavan_s_7438006da5249fe71</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%2F2263138%2F1569d876-772c-4ccd-969a-cb501ae117e5.jpg</url>
      <title>DEV Community: Pavan S</title>
      <link>https://dev.to/pavan_s_7438006da5249fe71</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pavan_s_7438006da5249fe71"/>
    <language>en</language>
    <item>
      <title>Most Developers Can Write the Code. Almost None of Them Can Ship It.</title>
      <dc:creator>Pavan S</dc:creator>
      <pubDate>Thu, 25 Jun 2026 12:59:35 +0000</pubDate>
      <link>https://dev.to/pavan_s_7438006da5249fe71/most-developers-can-write-the-code-almost-none-of-them-can-ship-it-ef7</link>
      <guid>https://dev.to/pavan_s_7438006da5249fe71/most-developers-can-write-the-code-almost-none-of-them-can-ship-it-ef7</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;A real story about a job assignment, a broken Docker config, and a deployment that went live in minutes.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  It started with a panic message
&lt;/h2&gt;

&lt;p&gt;A developer reached out to us with 24 hours left on a DevOps job assignment.&lt;/p&gt;

&lt;p&gt;The task: take a &lt;strong&gt;Task Manager application&lt;/strong&gt; (already fully built) and deploy it to a live production server with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker + Docker Compose&lt;/li&gt;
&lt;li&gt;PostgreSQL, Redis, NGINX reverse proxy&lt;/li&gt;
&lt;li&gt;GitHub Actions CI/CD pipeline&lt;/li&gt;
&lt;li&gt;SSL setup&lt;/li&gt;
&lt;li&gt;A real, accessible domain — not localhost&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The code was done. That wasn't the problem.&lt;/p&gt;

&lt;p&gt;The problem was everything that comes &lt;em&gt;after&lt;/em&gt; the code.&lt;/p&gt;




&lt;h2&gt;
  
  
  The gap nobody talks about
&lt;/h2&gt;

&lt;p&gt;Here's what most bootcamps, tutorials, and CS courses teach you:&lt;/p&gt;

&lt;p&gt;✅ Write the code&lt;br&gt;&lt;br&gt;
✅ Make it work locally&lt;br&gt;&lt;br&gt;
✅ Push it to GitHub  &lt;/p&gt;

&lt;p&gt;Here's what they don't teach you:&lt;/p&gt;

&lt;p&gt;❌ Write a production Dockerfile&lt;br&gt;&lt;br&gt;
❌ Configure NGINX as a reverse proxy&lt;br&gt;&lt;br&gt;
❌ Set up a CI/CD pipeline that actually deploys&lt;br&gt;&lt;br&gt;
❌ Get it running on a real server with a domain  &lt;/p&gt;

&lt;p&gt;This developer had spent hours on Stack Overflow, watching YouTube tutorials, and manually editing config files. Nothing worked. Docker wouldn't build. NGINX was misconfigured. The pipeline kept failing.&lt;/p&gt;

&lt;p&gt;Sound familiar?&lt;/p&gt;


&lt;h2&gt;
  
  
  What happened when they used DevLauch
&lt;/h2&gt;

&lt;p&gt;They connected their repository to &lt;strong&gt;DevPilot&lt;/strong&gt; — our AI-powered DevOps platform.&lt;/p&gt;

&lt;p&gt;Here's what happened in the next few minutes:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Task&lt;/th&gt;
&lt;th&gt;Status&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Dockerfile&lt;/td&gt;
&lt;td&gt;✅ Generated and fixed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Docker Compose&lt;/td&gt;
&lt;td&gt;✅ Configured (app + PostgreSQL + Redis)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NGINX reverse proxy&lt;/td&gt;
&lt;td&gt;✅ Running&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitHub Actions CI/CD&lt;/td&gt;
&lt;td&gt;✅ Pipeline live&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Domain deployment&lt;/td&gt;
&lt;td&gt;✅ Live on a real URL&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Total time: minutes.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The live project: &lt;a href="https://webvory-intern.devlauch.com" rel="noopener noreferrer"&gt;https://webvory-intern.devlauch.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;While other candidates submitted screenshots of apps running on &lt;code&gt;localhost:3000&lt;/code&gt;, this developer submitted a fully deployed, publicly accessible application.&lt;/p&gt;


&lt;h2&gt;
  
  
  Why Docker + NGINX trips everyone up
&lt;/h2&gt;

&lt;p&gt;Let's break down the two things that break 90% of deployment attempts.&lt;/p&gt;
&lt;h3&gt;
  
  
  Docker mistakes beginners make
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# ❌ Wrong — copies everything, bloats the image&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="c"&gt;# ✅ Right — copy dependency files first, then install, then copy source&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; package*.json ./&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Always use a &lt;code&gt;.dockerignore&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;node_modules
.env
.git
*.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  NGINX reverse proxy — the config that actually works
&lt;/h3&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;yourdomain.com&lt;/span&gt;&lt;span class="p"&gt;;&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;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://app:3000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;Host&lt;/span&gt; &lt;span class="nv"&gt;$host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Real-IP&lt;/span&gt; &lt;span class="nv"&gt;$remote_addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Forwarded-For&lt;/span&gt; &lt;span class="nv"&gt;$proxy_add_x_forwarded_for&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;The key mistake most people make: they try to proxy to &lt;code&gt;localhost&lt;/code&gt; inside the Docker network. Use the &lt;strong&gt;service name&lt;/strong&gt; from your &lt;code&gt;docker-compose.yml&lt;/code&gt; instead (in this case, &lt;code&gt;app&lt;/code&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  The Docker Compose structure that connects everything
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3.8'&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgresql://user:password@db:5432/taskdb&lt;/span&gt;
      &lt;span class="na"&gt;REDIS_URL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;redis://redis:6379&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&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&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;redis&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;postgres:16&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;POSTGRES_DB&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;taskdb&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_USER&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;user&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;password&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;postgres_data:/var/lib/postgresql/data&lt;/span&gt;

  &lt;span class="na"&gt;redis&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;redis:alpine&lt;/span&gt;

  &lt;span class="na"&gt;nginx&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;nginx:alpine&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;80:80"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;443:443"&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;./nginx.conf:/etc/nginx/conf.d/default.conf&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;app&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;postgres_data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The CI/CD pipeline that actually deploys
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to Production&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to server&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;appleboy/ssh-action@master&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.SERVER_HOST }}&lt;/span&gt;
          &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.SERVER_USER }}&lt;/span&gt;
          &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.SSH_PRIVATE_KEY }}&lt;/span&gt;
          &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
            &lt;span class="s"&gt;cd /app&lt;/span&gt;
            &lt;span class="s"&gt;git pull origin main&lt;/span&gt;
            &lt;span class="s"&gt;docker compose down&lt;/span&gt;
            &lt;span class="s"&gt;docker compose up -d --build&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Store your secrets in &lt;strong&gt;GitHub → Settings → Secrets and variables → Actions&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The real lesson
&lt;/h2&gt;

&lt;p&gt;The developer who came to us wasn't a bad engineer. They just hit the wall that almost every developer hits the first time they try to ship something for real.&lt;/p&gt;

&lt;p&gt;The tools exist. The knowledge is out there. But it takes days to piece together — and when you have a 24-hour deadline, you don't have days.&lt;/p&gt;

&lt;p&gt;That's why we built &lt;strong&gt;DevPilot&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You focus on the code. We handle the Dockerfile, the pipeline, the NGINX config, the server deployment — and when something breaks, our AI fixes it and redeploys automatically.&lt;/p&gt;

&lt;p&gt;Whether it's a job assignment, a college project, a freelance client, or your startup's MVP — you deserve to ship it with confidence.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try it yourself
&lt;/h2&gt;

&lt;p&gt;🔗 &lt;strong&gt;Live student assignment:&lt;/strong&gt; &lt;a href="https://webvory-intern.devlauch.com" rel="noopener noreferrer"&gt;webvory-intern.devlauch.com&lt;/a&gt;&lt;br&gt;&lt;br&gt;
🚀 &lt;strong&gt;DevPilot:&lt;/strong&gt; &lt;a href="https://devlauch.com" rel="noopener noreferrer"&gt;devlauch.com&lt;/a&gt;&lt;br&gt;&lt;br&gt;
📧 &lt;strong&gt;Questions:&lt;/strong&gt; &lt;a href="mailto:support@devlauch.com"&gt;support@devlauch.com&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built something you can't ship? We can help. Drop a comment below or reach out directly.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Tags:&lt;/strong&gt; &lt;code&gt;devops&lt;/code&gt; &lt;code&gt;docker&lt;/code&gt; &lt;code&gt;nginx&lt;/code&gt; &lt;code&gt;cicd&lt;/code&gt; &lt;code&gt;beginners&lt;/code&gt; &lt;code&gt;github-actions&lt;/code&gt; &lt;code&gt;deployment&lt;/code&gt; &lt;code&gt;webdev&lt;/code&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>DevPilot: I Built the IDP I Wish Existed as a DevOps Engineer</title>
      <dc:creator>Pavan S</dc:creator>
      <pubDate>Fri, 05 Jun 2026 15:18:48 +0000</pubDate>
      <link>https://dev.to/pavan_s_7438006da5249fe71/devpilot-i-built-the-idp-i-wish-existed-as-a-devops-engineer-mn5</link>
      <guid>https://dev.to/pavan_s_7438006da5249fe71/devpilot-i-built-the-idp-i-wish-existed-as-a-devops-engineer-mn5</guid>
      <description>&lt;h1&gt;
  
  
  DevPilot: How I Finally Finished My IDP After Abandoning It for a Year
&lt;/h1&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;DevPilot&lt;/strong&gt; — a self-hosted Internal Developer Platform (IDP) that does in one UI what used to take a full platform team: connects your GitHub/Bitbucket repos, auto-generates Jenkinsfiles and Dockerfiles using AI, runs CI/CD pipelines, &lt;strong&gt;self-heals failed builds automatically&lt;/strong&gt;, deploys to any VM via SSH, and provisions AWS infrastructure (EC2, RDS, S3) on demand.&lt;/p&gt;

&lt;p&gt;No Backstage. No YAML sprawl. No plugin ecosystem to maintain. Just connect your repo and go.&lt;/p&gt;

&lt;p&gt;GitHub repo: &lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/pavan-3000" rel="noopener noreferrer"&gt;
        pavan-3000
      &lt;/a&gt; / &lt;a href="https://github.com/pavan-3000/DevopsPilot" rel="noopener noreferrer"&gt;
        DevopsPilot
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
&lt;/div&gt;





&lt;h2&gt;
  
  
  The Problem I Was Solving
&lt;/h2&gt;

&lt;p&gt;I was working as a DevOps engineer in India. Most of our developers were based in the US — which means their working hours are our midnight.&lt;/p&gt;

&lt;p&gt;The pattern repeated itself every week:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A US developer hits a blocker at their 10am (our 10pm) — they need a new Jenkins pipeline, or an EC2 instance, or a Dockerfile fix&lt;/li&gt;
&lt;li&gt;Our DevOps team is asleep&lt;/li&gt;
&lt;li&gt;The developer waits. Half a day of productivity gone.&lt;/li&gt;
&lt;li&gt;Or we get a call. Someone on the India team works through the night to unblock one developer on the other side of the world.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This wasn't a people problem. Our team was good. It was a &lt;strong&gt;process problem&lt;/strong&gt; — developers shouldn't need to wait for a DevOps engineer to create a Jenkins job. That's not skilled work. It's a form.&lt;/p&gt;

&lt;p&gt;I started asking: what if a developer could just click a button, pick their repo and branch, and have a working pipeline in 60 seconds? No Slack message. No ticket. No waiting for someone in a different timezone to wake up.&lt;/p&gt;

&lt;p&gt;That's when I found &lt;strong&gt;Platform Engineering&lt;/strong&gt; and the concept of an IDP — a self-service layer that puts pipeline creation, infrastructure provisioning, and build management directly in the developer's hands. My first attempt was Backstage.&lt;/p&gt;




&lt;h2&gt;
  
  
  The "Before" — The Abandoned Backstage Project
&lt;/h2&gt;

&lt;p&gt;About a year ago I started building an IDP on top of Backstage (Spotify's open-source platform). I got excited. I read the docs. I cloned the repo.&lt;/p&gt;

&lt;p&gt;Then reality hit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Backstage is a framework, not a product.&lt;/strong&gt; You still build everything yourself.&lt;/li&gt;
&lt;li&gt;The plugin ecosystem is huge but poorly documented.&lt;/li&gt;
&lt;li&gt;Kubernetes is basically required for production hosting.&lt;/li&gt;
&lt;li&gt;Every config change meant rebuilding the entire catalog.&lt;/li&gt;
&lt;li&gt;My day job kept interrupting — on-call rotations, release freezes, incident reviews.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After 3 months I had: a running Backstage instance that showed a software catalog. That's it. No pipelines. No automation. No healing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I closed the laptop and didn't open that folder again for eight months.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The "After" — DevPilot
&lt;/h2&gt;

&lt;p&gt;This challenge made me pick it up again. Except I didn't pick up Backstage — I threw it out and built what I actually needed.&lt;/p&gt;

&lt;p&gt;DevPilot is the IDP I wish existed when I started as a DevOps engineer:&lt;/p&gt;

&lt;h3&gt;
  
  
  Connect in minutes
&lt;/h3&gt;

&lt;p&gt;Link GitHub or Bitbucket via OAuth. Connect your Jenkins server with a URL + API token. That's the setup.&lt;/p&gt;

&lt;h3&gt;
  
  
  AI-powered pipeline creation
&lt;/h3&gt;

&lt;p&gt;No Jenkinsfile? No Dockerfile? DevPilot generates both using Claude AI — a production-ready Dockerfile based on your language, and a Jenkinsfile with Docker build, Trivy security scan, registry push, and VM deploy stages pre-wired.&lt;/p&gt;

&lt;h3&gt;
  
  
  Self-healing CI
&lt;/h3&gt;

&lt;p&gt;When a build fails, DevPilot reads the build log, asks the AI what's wrong, patches the Jenkinsfile or Dockerfile, pushes the fix to your repo, and retriggers the build — automatically, up to 5 times. Engineers wake up to a green build, not a Slack mention.&lt;/p&gt;

&lt;h3&gt;
  
  
  Infrastructure provisioning
&lt;/h3&gt;

&lt;p&gt;EC2, RDS, S3 — provision from the UI. DevPilot generates the SSH keypair, spins the instance, bootstraps Docker, and registers it as a deploy target in under 5 minutes. Or sync your existing AWS resources with one click.&lt;/p&gt;

&lt;h3&gt;
  
  
  Command Center
&lt;/h3&gt;

&lt;p&gt;A split-panel AI chat UI. Ask "what's failing?" or "give me a pipeline report" in plain English. Deploy, stop, or debug pipelines directly from the chat. Manage Docker containers running on your EC2 instances without leaving the browser.&lt;/p&gt;




&lt;h2&gt;
  
  
  How GitHub Copilot Helped
&lt;/h2&gt;

&lt;p&gt;When I restarted this project, I used AI heavily throughout development — including GitHub Copilot for autocompletion in VS Code. The parts where it made the biggest difference:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AWS SDK v3 modular imports&lt;/strong&gt; — the new &lt;code&gt;@aws-sdk/client-*&lt;/code&gt; pattern was unfamiliar to me. Copilot correctly autocompleted &lt;code&gt;CreateBucketCommand&lt;/code&gt;, &lt;code&gt;PutPublicAccessBlockCommand&lt;/code&gt;, and the polling loop for &lt;code&gt;DescribeInstanceStatus&lt;/code&gt; without me having to read the full SDK docs every time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Jenkins XML config generation&lt;/strong&gt; — the &lt;code&gt;config.xml&lt;/code&gt; format for pipeline jobs is tedious. Copilot completed the XML template once I typed the opening tags, saving me from reading the Jenkins API docs for each credential type.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSE (Server-Sent Events) streaming&lt;/strong&gt; — I hadn't implemented SSE before. Once I typed &lt;code&gt;res.setHeader('Content-Type', 'text/event-stream')&lt;/code&gt;, Copilot suggested the correct keep-alive, flush pattern, and cleanup on &lt;code&gt;req.on('close')&lt;/code&gt; which I would have missed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;node-forge RSA keypair generation&lt;/strong&gt; — unfamiliar library. Copilot autocompleted the async keygen call and the PEM export format on the first try.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The self-healing loop logic I wrote myself — it was the core innovation and I wanted full ownership of how it worked. But Copilot saved me hours on the boilerplate that surrounds the interesting parts.&lt;/p&gt;




&lt;h2&gt;
  
  
  Key Features (Before vs After)
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Capability&lt;/th&gt;
&lt;th&gt;Backstage attempt (Before)&lt;/th&gt;
&lt;th&gt;DevPilot (After)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CI pipeline creation&lt;/td&gt;
&lt;td&gt;Manual plugin setup, never finished&lt;/td&gt;
&lt;td&gt;AI-generated Jenkinsfile, one wizard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dockerfile&lt;/td&gt;
&lt;td&gt;Not implemented&lt;/td&gt;
&lt;td&gt;AI-generated on first push&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Build failure recovery&lt;/td&gt;
&lt;td&gt;Not implemented&lt;/td&gt;
&lt;td&gt;Self-healing loop (5 retries, AI-patched)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Infrastructure&lt;/td&gt;
&lt;td&gt;Not implemented&lt;/td&gt;
&lt;td&gt;EC2 + RDS + S3 provisioning&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI integration&lt;/td&gt;
&lt;td&gt;Not implemented&lt;/td&gt;
&lt;td&gt;Claude/GPT throughout — generate, fix, analyze, chat&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deploy to VM&lt;/td&gt;
&lt;td&gt;Not implemented&lt;/td&gt;
&lt;td&gt;SSH deploy stage, docker pull + run&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Status&lt;/td&gt;
&lt;td&gt;Abandoned&lt;/td&gt;
&lt;td&gt;Shipped&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Technical Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; React 18, React Router v6, inline CSS (dark GitHub-style theme)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend:&lt;/strong&gt; Node.js, Express 4, PostgreSQL 16&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI:&lt;/strong&gt; Anthropic Claude (claude-haiku-4-5) or OpenAI GPT-4o-mini&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS SDK:&lt;/strong&gt; @aws-sdk/client-ec2, @aws-sdk/client-rds, @aws-sdk/client-s3 (v3)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSH/Crypto:&lt;/strong&gt; node-forge (RSA keypair gen), ssh2 (EC2 bootstrap)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deploy:&lt;/strong&gt; Docker + docker-compose, Nginx reverse proxy&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  What I Learned
&lt;/h2&gt;

&lt;p&gt;Building this in the "finish-up" sprint taught me something I should have known earlier: &lt;strong&gt;the value of a product comes from finishing, not from architecting&lt;/strong&gt;. Backstage is architecturally beautiful. DevPilot is a 4,000-line Express app. DevPilot is the one that actually solves the problem.&lt;/p&gt;

&lt;p&gt;The self-healing loop is the feature I'm most proud of — not because it's technically impressive (it's a polling loop with an AI call inside), but because it's genuinely useful. The first time I watched it fix a broken Dockerfile at midnight without me touching anything, I understood why I built this.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Rate limiting on auth endpoints (pre-beta blocker)&lt;/li&gt;
&lt;li&gt;HTTPS + Let's Encrypt for public URL + working OAuth callbacks&lt;/li&gt;
&lt;li&gt;Build history timeline (last 10 builds per pipeline)&lt;/li&gt;
&lt;li&gt;Email/Slack notifications on build failure&lt;/li&gt;
&lt;li&gt;GCP and Azure infrastructure support&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Built solo during the GitHub Finish-Up-A-Thon challenge. The abandoned Backstage project was started in mid-2025. DevPilot was the restart.&lt;/em&gt;&lt;/p&gt;

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

</description>
      <category>devchallenge</category>
      <category>githubchallenge</category>
      <category>devops</category>
      <category>github</category>
    </item>
    <item>
      <title>"Building a Serverless REST API with AWS Lambda, API Gateway, and DynamoDB Using Python"</title>
      <dc:creator>Pavan S</dc:creator>
      <pubDate>Sun, 27 Oct 2024 09:07:59 +0000</pubDate>
      <link>https://dev.to/pavan_s_7438006da5249fe71/building-a-serverless-rest-api-with-aws-lambda-api-gateway-and-dynamodb-using-python-35jb</link>
      <guid>https://dev.to/pavan_s_7438006da5249fe71/building-a-serverless-rest-api-with-aws-lambda-api-gateway-and-dynamodb-using-python-35jb</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;In this project, I developed a serverless REST API using AWS Lambda, API Gateway, and DynamoDB. The API enables CRUD operations on employee records, demonstrating how to leverage AWS's serverless architecture to build scalable, cost-effective applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tech Stack
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;AWS Lambda&lt;/strong&gt;: Executes CRUD functions without the need for server management.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API Gateway&lt;/strong&gt;: Routes HTTP requests to specific Lambda functions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DynamoDB&lt;/strong&gt;: Stores employee records in a NoSQL database.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Python (boto3)&lt;/strong&gt;: Handles the application logic and database operations.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step-by-Step Project Setup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Set Up DynamoDB Table
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Navigate to DynamoDB&lt;/strong&gt; in the AWS Console and &lt;strong&gt;create a new table&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Table Name&lt;/strong&gt;: &lt;code&gt;employee_info&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Primary Key&lt;/strong&gt;: &lt;code&gt;employeeid&lt;/code&gt; (String).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Attributes&lt;/strong&gt;: Define fields such as &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;department&lt;/code&gt;, &lt;code&gt;position&lt;/code&gt;, and &lt;code&gt;salary&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;DynamoDB offers a highly scalable NoSQL solution perfect for handling unstructured employee data.&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%2F4rr1thnd9jdekigun6rz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4rr1thnd9jdekigun6rz.png" alt="DynamoDB " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Create an IAM Policy
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Sign in to the AWS Management Console&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Navigate to the &lt;strong&gt;IAM&lt;/strong&gt; console.&lt;/li&gt;
&lt;li&gt;In the left navigation pane, click on &lt;strong&gt;Policies&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click on the &lt;strong&gt;Create policy&lt;/strong&gt; button.&lt;/li&gt;
&lt;li&gt;ADD policy for Dynamodb&lt;/li&gt;
&lt;/ol&gt;

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

&lt;h3&gt;
  
  
  Step 3: Write the Lambda Function Code
&lt;/h3&gt;

&lt;p&gt;Create a Lambda function in Python that will handle requests for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Retrieving all employees or a specific employee (&lt;code&gt;GET&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Adding a new employee (&lt;code&gt;POST&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Updating an employee's details (&lt;code&gt;PATCH&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Deleting an employee record (&lt;code&gt;DELETE&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h2&gt;
  
  
  Step 4: Create API Gateway Endpoints
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Set Up API Gateway
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;API Gateway&lt;/strong&gt; and create a REST API.&lt;/li&gt;
&lt;li&gt;Define Resources and Methods:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;/employee&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;GET&lt;/code&gt; - Retrieve employee data.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;POST&lt;/code&gt; - Add new employee.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PATCH&lt;/code&gt; - Update existing employee data.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;DELETE&lt;/code&gt; - Remove an employee record.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;/employees&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;GET&lt;/code&gt; - Retrieve all employees.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;/Status&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;GET&lt;/code&gt; - Retrieve all employees Status.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

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

&lt;h3&gt;
  
  
  Connect Methods to Lambda
&lt;/h3&gt;

&lt;p&gt;For each HTTP method, connect the endpoint to the appropriate Lambda function.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Deploy the API
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Create a &lt;strong&gt;Deployment Stage&lt;/strong&gt; in API Gateway.&lt;/li&gt;
&lt;li&gt;Deploy the API to make the endpoints accessible.&lt;/li&gt;
&lt;li&gt;Note the endpoint URL generated by API Gateway; this will serve as the base URL for the REST API.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Example Requests
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GET&lt;/strong&gt; &lt;code&gt;/employee?employeeid=123&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Retrieves data for employee with ID 123.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;POST&lt;/strong&gt; &lt;code&gt;/employee&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Adds a new employee.&lt;/p&gt;

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



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
json
  {
    "employeeid": "123",
    "name": "John Doe",
    "position": "Engineer",
    "salary": 60000
  }

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

&lt;/div&gt;

</description>
      <category>aws</category>
      <category>cloudskills</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
