<?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: Alex Boguslavets</title>
    <description>The latest articles on DEV Community by Alex Boguslavets (@alex_boguslavets_b6280b12).</description>
    <link>https://dev.to/alex_boguslavets_b6280b12</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%2F1958639%2F4afd1168-f947-4bce-81c7-a54dd1fde7e3.jpg</url>
      <title>DEV Community: Alex Boguslavets</title>
      <link>https://dev.to/alex_boguslavets_b6280b12</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/alex_boguslavets_b6280b12"/>
    <language>en</language>
    <item>
      <title>Docker for Beginners: Containerize Your App in 30 Minutes</title>
      <dc:creator>Alex Boguslavets</dc:creator>
      <pubDate>Thu, 23 Apr 2026 08:12:36 +0000</pubDate>
      <link>https://dev.to/alex_boguslavets_b6280b12/docker-for-beginners-containerize-your-app-in-30-minutes-47em</link>
      <guid>https://dev.to/alex_boguslavets_b6280b12/docker-for-beginners-containerize-your-app-in-30-minutes-47em</guid>
      <description>&lt;p&gt;I remember the first time I heard "it works on my machine." Three developers, three different environments, one broken deploy. Docker solves exactly this problem.&lt;/p&gt;

&lt;p&gt;In this guide you'll go from zero to a running containerized app in 30 minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Docker, actually?
&lt;/h2&gt;

&lt;p&gt;Docker packages your app + its dependencies + runtime into a single image. That image runs the same way everywhere — your laptop, a teammate's Mac, AWS EC2.&lt;/p&gt;

&lt;p&gt;Think of it like a shipping container: standardized box, works on any ship.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Docker Desktop installed (&lt;a href="https://docs.docker.com/get-docker/" rel="noopener noreferrer"&gt;docs.docker.com&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Basic terminal knowledge&lt;/li&gt;
&lt;li&gt;Any web app (we'll use a simple Node.js example)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1: Create a simple app
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// app.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;server&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createServer&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;end&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello from Docker! 🐳&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Running on port 3000&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;//&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;package.json&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"docker-demo"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node app.js"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Write a Dockerfile
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# Start from official Node image&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; node:20-alpine&lt;/span&gt;

&lt;span class="c"&gt;# Set working directory inside container&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /app&lt;/span&gt;

&lt;span class="c"&gt;# Copy dependency files first (layer caching)&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="c"&gt;# Copy the rest of the app&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;# Expose the port&lt;/span&gt;
&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 3000&lt;/span&gt;

&lt;span class="c"&gt;# Start command&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["node", "app.js"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Build and run
&lt;/h2&gt;



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

&lt;span class="c"&gt;# Run a container from it&lt;/span&gt;
docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 3000:3000 my-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt; — you'll see "Hello from Docker! 🐳"&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Add Docker Compose
&lt;/h2&gt;

&lt;p&gt;For real apps you need a database too. Docker Compose manages multiple containers:&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;# docker-compose.yml&lt;/span&gt;
&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3.8'&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3000:3000"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;DATABASE_URL=postgres://user:password@db:5432/myapp    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="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-alpine&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_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;POSTGRES_DB&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;myapp&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;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;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One command — app + database, both running.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key concepts to remember
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Concept&lt;/th&gt;
&lt;th&gt;What it is&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Image&lt;/td&gt;
&lt;td&gt;Blueprint (like a class)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Container&lt;/td&gt;
&lt;td&gt;Running instance (like an object)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dockerfile&lt;/td&gt;
&lt;td&gt;Recipe to build an image&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Docker Compose&lt;/td&gt;
&lt;td&gt;Tool to run multiple containers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Volume&lt;/td&gt;
&lt;td&gt;Persistent storage for containers&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Common mistakes beginners make
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Copying node_modules into the image&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add 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
.git
.env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Running as root&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Add this to your Dockerfile before CMD:&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;RUN &lt;/span&gt;addgroup &lt;span class="nt"&gt;-S&lt;/span&gt; appgroup &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; adduser &lt;span class="nt"&gt;-S&lt;/span&gt; appuser &lt;span class="nt"&gt;-G&lt;/span&gt; appgroup
&lt;span class="k"&gt;USER&lt;/span&gt;&lt;span class="s"&gt; appuser&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Not using layer caching&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Always copy &lt;code&gt;package.json&lt;/code&gt; and run &lt;code&gt;npm install&lt;/code&gt; BEFORE copying your source code. Docker caches each layer — if your code changes but dependencies don't, it won't reinstall everything.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next?
&lt;/h2&gt;

&lt;p&gt;Once you're comfortable with basics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Multi-stage builds&lt;/strong&gt; — smaller production images&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Health checks&lt;/strong&gt; — Docker restarts unhealthy containers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docker secrets&lt;/strong&gt; — secure way to pass credentials&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kubernetes&lt;/strong&gt; — when you need to scale beyond one server&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Real talk
&lt;/h2&gt;

&lt;p&gt;Docker has a learning curve. The first Dockerfile feels weird. But after a week you won't be able to imagine developing without it.&lt;/p&gt;

&lt;p&gt;No more "works on my machine." No more dependency conflicts. No more manual server setup.&lt;/p&gt;




&lt;p&gt;I use Docker daily running a Rails + PostgreSQL + Nginx stack on AWS EC2. If you have questions about specific setups — drop them in the comments.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>devops</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>5 Security Mistakes I See on Every Server Audit</title>
      <dc:creator>Alex Boguslavets</dc:creator>
      <pubDate>Wed, 22 Apr 2026 10:55:00 +0000</pubDate>
      <link>https://dev.to/alex_boguslavets_b6280b12/5-security-mistakes-i-see-on-every-server-audit-165b</link>
      <guid>https://dev.to/alex_boguslavets_b6280b12/5-security-mistakes-i-see-on-every-server-audit-165b</guid>
      <description>&lt;p&gt;Every server I audit has at least three of these issues. They're simple to fix, yet consistently overlooked. A single breach can cost a small business thousands of dollars in downtime, data loss, and reputation damage.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. SSH with Password Authentication
&lt;/h2&gt;

&lt;p&gt;If your server accepts SSH passwords, it's being brute-forced right now. Check your &lt;code&gt;/var/log/auth.log&lt;/code&gt; — you'll see hundreds of failed login attempts daily from bots around the world.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; Switch to SSH key authentication and disable password login:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# /etc/ssh/sshd_config&lt;/span&gt;
PasswordAuthentication no
PubkeyAuthentication &lt;span class="nb"&gt;yes
&lt;/span&gt;PermitRootLogin no
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This single change eliminates 99% of brute-force attacks. Takes 5 minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. No Firewall Rules
&lt;/h2&gt;

&lt;p&gt;I regularly find servers with all ports open to the internet. Database ports (3306, 5432), Redis (6379), admin panels — all accessible from anywhere.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; Use ufw to allow only what's needed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ufw default deny incoming
ufw allow 22/tcp    &lt;span class="c"&gt;# SSH&lt;/span&gt;
ufw allow 80/tcp    &lt;span class="c"&gt;# HTTP&lt;/span&gt;
ufw allow 443/tcp   &lt;span class="c"&gt;# HTTPS&lt;/span&gt;
ufw &lt;span class="nb"&gt;enable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Unattended Upgrades Disabled
&lt;/h2&gt;

&lt;p&gt;Security patches are released weekly. If your server isn't automatically installing them, you're running known-vulnerable software. The Equifax breach happened because of an unpatched vulnerability — the fix had been available for months.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; Enable automatic security updates on Ubuntu:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;unattended-upgrades
dpkg-reconfigure &lt;span class="nt"&gt;-plow&lt;/span&gt; unattended-upgrades
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Running Services as Root
&lt;/h2&gt;

&lt;p&gt;If your web application runs as root and gets compromised, the attacker has full control of your server. Running services as unprivileged users limits the blast radius of any vulnerability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; Create dedicated users for each service. With Docker, don't run containers with &lt;code&gt;--privileged&lt;/code&gt; unless absolutely necessary.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. No Backups (or Untested Backups)
&lt;/h2&gt;

&lt;p&gt;Having backups is step one. Testing them is step two — and most people skip it. I've seen companies discover their backups were corrupted only when they needed to restore.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; Automate daily backups to an external location (S3, another server). Set up a monthly restore test. If you can't restore it, it's not a backup — it's a hope.&lt;/p&gt;

&lt;h2&gt;
  
  
  Take Action Today
&lt;/h2&gt;

&lt;p&gt;These five fixes take less than an hour total and dramatically improve your security posture.&lt;/p&gt;




&lt;p&gt;Not sure about your server's security? I offer comprehensive server audits with a detailed report and remediation plan. Contact me for a security review.&lt;/p&gt;

</description>
      <category>security</category>
      <category>devops</category>
      <category>linux</category>
      <category>server</category>
    </item>
    <item>
      <title>Monitoring 101: Grafana + Prometheus for Your Infrastructure</title>
      <dc:creator>Alex Boguslavets</dc:creator>
      <pubDate>Tue, 21 Apr 2026 07:14:00 +0000</pubDate>
      <link>https://dev.to/alex_boguslavets_b6280b12/monitoring-101-grafana-prometheus-for-your-infrastructure-c12</link>
      <guid>https://dev.to/alex_boguslavets_b6280b12/monitoring-101-grafana-prometheus-for-your-infrastructure-c12</guid>
      <description>&lt;p&gt;How do you know your server is healthy right now? Is CPU at 90%? Is the disk almost full? Are response times increasing? If you can't answer these questions instantly, you need monitoring.&lt;/p&gt;

&lt;p&gt;Most businesses discover problems the worst way possible: customers complain. By then, you've already lost revenue and trust. Good monitoring means you know about issues before your users do.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Monitoring Stack
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Prometheus&lt;/strong&gt; collects metrics from your servers and applications. It scrapes data every 15 seconds and stores it in a time-series database.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Grafana&lt;/strong&gt; visualizes those metrics in beautiful, customizable dashboards. CPU usage over time, memory trends, request rates — all in real-time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Alertmanager&lt;/strong&gt; sends notifications when things go wrong. Email, Slack, Telegram, PagerDuty — choose your channel.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to Monitor
&lt;/h2&gt;

&lt;p&gt;Start with the "USE" method:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Utilization&lt;/strong&gt; — CPU, memory, disk usage percentage&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Saturation&lt;/strong&gt; — queue lengths, swap usage, I/O wait&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Errors&lt;/strong&gt; — 5xx responses, failed requests, connection timeouts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For web applications, add:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Response time (p50, p95, p99)&lt;/li&gt;
&lt;li&gt;Request rate (requests per second)&lt;/li&gt;
&lt;li&gt;Error rate (percentage of failed requests)&lt;/li&gt;
&lt;li&gt;Database query time&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Alerting Done Right
&lt;/h2&gt;

&lt;p&gt;The biggest mistake in monitoring is too many alerts. If everything is "critical," nothing is.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Alert on symptoms, not causes — "website is slow" is better than "CPU is high"&lt;/li&gt;
&lt;li&gt;Set meaningful thresholds — 80% disk usage is a warning, 95% is critical&lt;/li&gt;
&lt;li&gt;Include runbook links — every alert should tell you what to do next&lt;/li&gt;
&lt;li&gt;Avoid alert fatigue — if you're ignoring alerts, your thresholds are wrong&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;The easiest way to start is with Docker Compose. Prometheus, Grafana, and node_exporter can be running in under 10 minutes. There are also excellent community dashboards for common setups — no need to build from scratch.&lt;/p&gt;

&lt;p&gt;If your infrastructure runs without monitoring, you're flying blind.&lt;/p&gt;




&lt;p&gt;I can set up a complete monitoring stack for your infrastructure in a day. &lt;a href="https://alexxdevops.com/en/contact" rel="noopener noreferrer"&gt;Reach out&lt;/a&gt; and stop guessing.&lt;/p&gt;

</description>
      <category>monitoring</category>
      <category>devops</category>
      <category>prometheus</category>
      <category>grafana</category>
    </item>
    <item>
      <title>How AI Tools Are Changing DevOps: My Real Experience</title>
      <dc:creator>Alex Boguslavets</dc:creator>
      <pubDate>Mon, 20 Apr 2026 14:00:00 +0000</pubDate>
      <link>https://dev.to/alex_boguslavets_b6280b12/how-ai-tools-are-changing-devops-my-real-experience-33ho</link>
      <guid>https://dev.to/alex_boguslavets_b6280b12/how-ai-tools-are-changing-devops-my-real-experience-33ho</guid>
      <description>&lt;p&gt;When ChatGPT launched, many people panicked. "AI will replace developers!" In reality, after using AI tools daily for over a year: AI doesn't replace engineers — it amplifies them. I'm 2-3x more productive, not because AI writes my code, but because it eliminates the boring parts.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Actually Use AI For
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Writing Ansible Playbooks and Scripts
&lt;/h3&gt;

&lt;p&gt;Instead of spending 30 minutes writing a playbook from scratch, I describe what I need: &lt;em&gt;"Create an Ansible playbook that installs Docker on Ubuntu 22.04, adds the current user to the docker group, and enables the service."&lt;/em&gt; I get a working draft in seconds, then review and customize it.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Debugging Configuration Issues
&lt;/h3&gt;

&lt;p&gt;Nginx returning 502? Paste the error log into Claude, describe your setup, and get targeted suggestions. AI is excellent at pattern-matching common misconfigurations that would take 45 minutes of Stack Overflow browsing.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Writing Documentation
&lt;/h3&gt;

&lt;p&gt;Nobody likes writing runbooks. I describe the procedure, AI generates clean structured documentation. I review it, add context — done in a quarter of the time.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Learning New Tools
&lt;/h3&gt;

&lt;p&gt;"Explain Prometheus alerting rules with examples" gives you a personalized tutorial instantly. Like having a senior engineer available 24/7.&lt;/p&gt;

&lt;h2&gt;
  
  
  What AI Is Bad At
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Architecture decisions — AI doesn't understand your business context, budget, or team capabilities&lt;/li&gt;
&lt;li&gt;Security-critical configurations — always verify against official documentation&lt;/li&gt;
&lt;li&gt;Debugging production issues — AI can help analyze logs, but it can't access your systems&lt;/li&gt;
&lt;li&gt;Novel problems — if it's not in the training data, AI will confidently give you wrong answers&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  My AI Toolkit
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Claude&lt;/strong&gt; — my go-to for complex tasks, long documents, and code review. Excellent reasoning.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ChatGPT&lt;/strong&gt; — great for quick questions and brainstorming.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub Copilot&lt;/strong&gt; — autocomplete on steroids. Saves time on repetitive patterns.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Claude Code&lt;/strong&gt; — this entire website was built with AI assistance. Blog, payments, SEO — all developed faster thanks to AI pair programming.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;AI tools are not magic — they're power tools. A chainsaw doesn't make you a lumberjack, but a lumberjack with a chainsaw is 10x more productive than one with an axe.&lt;/p&gt;




&lt;p&gt;Want to learn how AI can speed up your infrastructure work? &lt;a href="https://alexxdevops.com/en/booking" rel="noopener noreferrer"&gt;Book a free consultation&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>devops</category>
      <category>productivity</category>
      <category>tools</category>
    </item>
    <item>
      <title>Docker for Beginners: Containerize Your App in 30 Minutes</title>
      <dc:creator>Alex Boguslavets</dc:creator>
      <pubDate>Mon, 20 Apr 2026 05:30:10 +0000</pubDate>
      <link>https://dev.to/alex_boguslavets_b6280b12/docker-for-beginners-containerize-your-app-in-30-minutes-4nb3</link>
      <guid>https://dev.to/alex_boguslavets_b6280b12/docker-for-beginners-containerize-your-app-in-30-minutes-4nb3</guid>
      <description>&lt;p&gt;"It works on my machine" — the most dreaded phrase in software development. Docker eliminates this problem entirely. When your app runs in a Docker container, it runs the same way everywhere: on your laptop, on your colleague's Mac, on a Linux server in AWS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Concepts in Plain Language
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Image&lt;/strong&gt; — a blueprint (recipe) for your container. Think of it as a snapshot of a configured system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Container&lt;/strong&gt; — a running instance of an image. You can run multiple containers from the same image.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Dockerfile&lt;/strong&gt; — a text file with instructions on how to build your image.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Docker Compose&lt;/strong&gt; — a tool for running multiple containers together (e.g., your app + database + Redis).&lt;/p&gt;

&lt;h2&gt;
  
  
  A Real Dockerfile Example
&lt;/h2&gt;

&lt;p&gt;Here's a Dockerfile for a Rails application:&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; ruby:3.3&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; Gemfile Gemfile.lock ./&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;bundle &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;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 3000&lt;/span&gt;

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["rails", "server", "-b", "0.0.0.0"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Six lines that package your entire application into a portable container.&lt;/p&gt;

&lt;h2&gt;
  
  
  Docker Compose: The Real Power
&lt;/h2&gt;

&lt;p&gt;Most applications need more than one service. Docker Compose lets you define everything in one file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;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;3000:3000"&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="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;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;pgdata:/var/lib/postgresql/data&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run &lt;code&gt;docker compose up&lt;/code&gt; and your entire stack starts in seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to Use Docker
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Your team works on different operating systems&lt;/li&gt;
&lt;li&gt;You need consistent environments across dev, staging, and production&lt;/li&gt;
&lt;li&gt;You want to simplify deployment and scaling&lt;/li&gt;
&lt;li&gt;You're setting up a CI/CD pipeline&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're still installing dependencies manually on each server, Docker will change your workflow forever.&lt;/p&gt;




&lt;p&gt;Need help containerizing your application? Let's talk.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>devops</category>
      <category>containers</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Why Every Small Business Needs a CI/CD Pipeline in 2026</title>
      <dc:creator>Alex Boguslavets</dc:creator>
      <pubDate>Thu, 16 Apr 2026 07:00:00 +0000</pubDate>
      <link>https://dev.to/alex_boguslavets_b6280b12/why-every-small-business-needs-a-cicd-pipeline-in-2026-22c4</link>
      <guid>https://dev.to/alex_boguslavets_b6280b12/why-every-small-business-needs-a-cicd-pipeline-in-2026-22c4</guid>
      <description>&lt;p&gt;If you're still deploying your application by SSHing into a server and running commands manually, you're not alone — but you're losing money. Every manual deployment is a risk: a forgotten step, a typo in a command, or a missing environment variable can bring your site down.&lt;/p&gt;

&lt;p&gt;I've seen teams spend 2-3 hours on each deployment, doing the same repetitive steps every time. That's 2-3 hours of skilled developer time wasted on something a machine can do in 2 minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is CI/CD and Why Should You Care?
&lt;/h2&gt;

&lt;p&gt;CI (Continuous Integration) means every code change is automatically tested. CD (Continuous Deployment) means every tested change is automatically deployed to your server. Together, they form a pipeline that takes your code from a Git push to a live website — without human intervention.&lt;/p&gt;

&lt;p&gt;Here's what a typical pipeline looks like:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Developer pushes code to GitHub&lt;/li&gt;
&lt;li&gt;Automated tests run (unit tests, linting, security checks)&lt;/li&gt;
&lt;li&gt;If tests pass, code is deployed to staging&lt;/li&gt;
&lt;li&gt;After approval, code goes to production&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Real Example: A Self-Hosted Pipeline
&lt;/h2&gt;

&lt;p&gt;This website uses GitHub Actions with a self-hosted runner. When I push to master:&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;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;master&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;self-hosted&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: actions/checkout@v4      - name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Sync files&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rsync -av --exclude='.git' . ubuntu@server:/app      - name&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Restart app&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ssh ubuntu@server "cd /app &amp;amp;&amp;amp; docker compose restart web"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Total deploy time: under 60 seconds. Zero manual steps.&lt;/p&gt;

&lt;h2&gt;
  
  
  The ROI Is Obvious
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Manual deployment&lt;/th&gt;
&lt;th&gt;CI/CD pipeline&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Time per deploy&lt;/td&gt;
&lt;td&gt;30-120 min&lt;/td&gt;
&lt;td&gt;1-2 min&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Human error risk&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Near zero&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deploy frequency&lt;/td&gt;
&lt;td&gt;Weekly (fear-driven)&lt;/td&gt;
&lt;td&gt;Daily or more&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rollback time&lt;/td&gt;
&lt;td&gt;30-60 min&lt;/td&gt;
&lt;td&gt;1 click&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Teams with CI/CD deploy 10-20x more frequently and have 5x fewer incidents according to the DORA metrics report.&lt;/p&gt;

&lt;h2&gt;
  
  
  You Don't Need to Start Big
&lt;/h2&gt;

&lt;p&gt;You don't need a complex setup on day one. Start with:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;GitHub Actions — free for public repos, 2,000 min/month free for private&lt;/li&gt;
&lt;li&gt;One job — just run tests on every push&lt;/li&gt;
&lt;li&gt;Add deploy step — rsync + restart when tests pass&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it. You can add staging environments, approval gates, and notifications later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Objections
&lt;/h2&gt;

&lt;p&gt;"Our app is too simple for CI/CD." No app is too simple. Even a static website benefits from automated deploys.&lt;/p&gt;

&lt;p&gt;"It takes too long to set up." A basic pipeline takes 1-2 hours. You'll recover that time on the first deployment.&lt;/p&gt;

&lt;p&gt;"Our team is too small." Solo developers benefit the most — you have no one to catch your mistakes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;CI/CD isn't a luxury for big tech companies. It's a basic hygiene practice that any team of any size can implement in an afternoon.&lt;/p&gt;




&lt;p&gt;Want a CI/CD pipeline set up for your project? Browse our automation services or book a free call.&lt;/p&gt;

</description>
      <category>cicd</category>
      <category>devops</category>
      <category>automation</category>
      <category>github</category>
    </item>
    <item>
      <title>Docker Compose in Production: Is It a Good Idea?</title>
      <dc:creator>Alex Boguslavets</dc:creator>
      <pubDate>Wed, 15 Apr 2026 11:10:58 +0000</pubDate>
      <link>https://dev.to/alex_boguslavets_b6280b12/docker-compose-in-production-is-it-a-good-idea-bgh</link>
      <guid>https://dev.to/alex_boguslavets_b6280b12/docker-compose-in-production-is-it-a-good-idea-bgh</guid>
      <description>&lt;p&gt;"Use Kubernetes in production, Docker Compose is just for development." You've probably heard this. It's not wrong — but it's also not the whole story. For small teams, single-server setups, and projects that don't need horizontal scaling, Docker Compose in production is a completely valid choice.&lt;/p&gt;

&lt;p&gt;This very website runs on Docker Compose in production — on a single AWS t3.micro instance. Here's what I've learned.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Docker Compose in Production Makes Sense
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Single server setup — your app fits on one machine (most small businesses do)&lt;/li&gt;
&lt;li&gt;Low traffic — under ~1,000 concurrent users&lt;/li&gt;
&lt;li&gt;Small team — 1-5 developers who don't want Kubernetes complexity&lt;/li&gt;
&lt;li&gt;Predictable load — no need for auto-scaling&lt;/li&gt;
&lt;li&gt;Budget constraints — one EC2 instance costs $15-30/month vs $150+ for managed Kubernetes&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Real Limitations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;No auto-healing — if a container crashes, you need a restart policy to bring it back&lt;/li&gt;
&lt;li&gt;No horizontal scaling — you can't easily add more web servers&lt;/li&gt;
&lt;li&gt;No rolling deployments — deploys cause a brief downtime window&lt;/li&gt;
&lt;li&gt;Single point of failure — if the server goes down, everything goes down&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Making It Production-Ready
&lt;/h2&gt;

&lt;p&gt;With a few additions, Docker Compose becomes quite robust:&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;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;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;healthcheck&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CMD"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;curl"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;-f"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:3000/health"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
      &lt;span class="na"&gt;interval&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;30s&lt;/span&gt;
      &lt;span class="na"&gt;retries&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3&lt;/span&gt;
  &lt;span class="na"&gt;nginx&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
  &lt;span class="na"&gt;db&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add &lt;code&gt;restart: unless-stopped&lt;/code&gt; to every service. It ensures containers come back up after a server reboot or crash.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deployment Without Downtime
&lt;/h2&gt;

&lt;p&gt;Zero-downtime deploys with Docker Compose require a bit of creativity:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sync new code to the server (rsync)&lt;/li&gt;
&lt;li&gt;Build the new image: &lt;code&gt;docker compose build web&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Run migrations: &lt;code&gt;docker compose exec web rails db:migrate&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Reload: &lt;code&gt;docker compose up -d --no-deps web&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Nginx continues serving the old container while the new one starts. The gap is typically under 5 seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  When to Move to Kubernetes
&lt;/h2&gt;

&lt;p&gt;Graduate to Kubernetes when you need: multiple servers, auto-scaling, canary deployments, or if your team grows beyond 10 engineers. For everything else, Docker Compose is fast, simple, and reliable enough.&lt;/p&gt;




&lt;p&gt;Need help containerizing your application? Browse our containerization services.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>devops</category>
      <category>containers</category>
      <category>infrastructure</category>
    </item>
    <item>
      <title>GitHub Actions vs GitLab CI: Which One Should You Use in 2026?</title>
      <dc:creator>Alex Boguslavets</dc:creator>
      <pubDate>Wed, 15 Apr 2026 09:05:08 +0000</pubDate>
      <link>https://dev.to/alex_boguslavets_b6280b12/github-actions-vs-gitlab-ci-which-one-should-you-use-in-2026-gln</link>
      <guid>https://dev.to/alex_boguslavets_b6280b12/github-actions-vs-gitlab-ci-which-one-should-you-use-in-2026-gln</guid>
      <description>&lt;p&gt;GitHub Actions and GitLab CI are the two dominant CI/CD platforms in 2026. If your code is already on one platform, the answer is usually obvious. But for new projects — or migrations — the choice matters.&lt;/p&gt;

&lt;p&gt;Here's what I've learned running both in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub Actions: Strengths
&lt;/h2&gt;

&lt;p&gt;Ecosystem is unmatched. The GitHub Marketplace has thousands of pre-built actions for everything from deploying to AWS to sending Slack notifications. Most open-source projects use GitHub Actions, so finding examples is easy.&lt;/p&gt;

&lt;p&gt;Self-hosted runners are simple to set up. Add a runner to your server in 10 minutes. This is how I deploy this website — a macOS runner on my own machine handles all deployments for free.&lt;/p&gt;

&lt;p&gt;Tight GitHub integration. Branch protection rules, required status checks, environment protection rules, and deployment history are all first-class features.&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;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;self-hosted&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: actions/checkout@v4      - run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./deploy.sh&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  GitLab CI: Strengths
&lt;/h2&gt;

&lt;p&gt;All-in-one platform. GitLab includes built-in container registry, package registry, security scanning, dependency scanning, and infrastructure management. With GitHub you need to integrate these separately.&lt;/p&gt;

&lt;p&gt;Better for private infrastructure. GitLab's self-hosted option (GitLab CE/EE) gives you full control — useful for enterprises with strict compliance requirements.&lt;/p&gt;

&lt;p&gt;Pipeline visualization is superior. GitLab's pipeline UI shows stages, job dependencies, and artifacts more clearly than GitHub Actions' linear view.&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;stages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;build&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;deploy&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;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deploy&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="na"&gt;rsync -av . user@server:/app  only&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Honest Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;GitHub Actions&lt;/th&gt;
&lt;th&gt;GitLab CI&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Free minutes (public repos)&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;td&gt;400/month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Free minutes (private repos)&lt;/td&gt;
&lt;td&gt;2,000/month&lt;/td&gt;
&lt;td&gt;400/month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Marketplace/integrations&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;td&gt;Good&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Self-hosted&lt;/td&gt;
&lt;td&gt;Good&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Built-in security scanning&lt;/td&gt;
&lt;td&gt;Basic (paid)&lt;/td&gt;
&lt;td&gt;Included&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pipeline UI&lt;/td&gt;
&lt;td&gt;Good&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  My Recommendation
&lt;/h2&gt;

&lt;p&gt;Choose &lt;strong&gt;GitHub Actions&lt;/strong&gt; if: your team lives in GitHub, you work with open-source, or you want the largest ecosystem of ready-made integrations.&lt;/p&gt;

&lt;p&gt;Choose &lt;strong&gt;GitLab CI&lt;/strong&gt; if: you need a self-hosted all-in-one platform, work in an enterprise with compliance requirements, or value built-in security scanning.&lt;/p&gt;

&lt;p&gt;For most small-to-medium teams in 2026: GitHub Actions wins on convenience. For enterprises needing full control: GitLab CI wins on completeness.&lt;/p&gt;




&lt;p&gt;Need help setting up a CI/CD pipeline? Browse our DevOps services or contact us directly.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>cicd</category>
      <category>github</category>
      <category>gitlab</category>
    </item>
    <item>
      <title>GitHub Actions vs GitLab CI: Which One Should You Use in 2026? delete</title>
      <dc:creator>Alex Boguslavets</dc:creator>
      <pubDate>Wed, 15 Apr 2026 09:01:06 +0000</pubDate>
      <link>https://dev.to/alex_boguslavets_b6280b12/github-actions-vs-gitlab-ci-which-one-should-you-use-in-2026-55mk</link>
      <guid>https://dev.to/alex_boguslavets_b6280b12/github-actions-vs-gitlab-ci-which-one-should-you-use-in-2026-55mk</guid>
      <description>&lt;p&gt;GitHub Actions and GitLab CI are the two dominant CI/CD platforms in 2026. If your code is already on one platform, the answer is usually obvious. But for new projects — or migrations — the choice matters.&lt;/p&gt;

&lt;p&gt;Here's what I've learned running both in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub Actions: Strengths
&lt;/h2&gt;

&lt;p&gt;Ecosystem is unmatched. The GitHub Marketplace has thousands of pre-built actions for everything from deploying to AWS to sending Slack notifications. Most open-source projects use GitHub Actions, so finding examples is easy.&lt;/p&gt;

&lt;p&gt;Self-hosted runners are simple to set up. Add a runner to your server in 10 minutes. This is how I deploy this website — a macOS runner on my own machine handles all deployments for free.&lt;/p&gt;

&lt;p&gt;Tight GitHub integration. Branch protection rules, required status checks, environment protection rules, and deployment history are all first-class features.&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;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;self-hosted&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: actions/checkout@v4      - run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./deploy.sh&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  GitLab CI: Strengths
&lt;/h2&gt;

&lt;p&gt;All-in-one platform. GitLab includes built-in container registry, package registry, security scanning, dependency scanning, and infrastructure management. With GitHub you need to integrate these separately.&lt;/p&gt;

&lt;p&gt;Better for private infrastructure. GitLab's self-hosted option (GitLab CE/EE) gives you full control — useful for enterprises with strict compliance requirements.&lt;/p&gt;

&lt;p&gt;Pipeline visualization is superior. GitLab's pipeline UI shows stages, job dependencies, and artifacts more clearly than GitHub Actions' linear view.&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;stages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;build&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;deploy&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;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;deploy&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="na"&gt;rsync -av . user@server:/app  only&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Honest Comparison
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;GitHub Actions&lt;/th&gt;
&lt;th&gt;GitLab CI&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Free minutes (public repos)&lt;/td&gt;
&lt;td&gt;Unlimited&lt;/td&gt;
&lt;td&gt;400/month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Free minutes (private repos)&lt;/td&gt;
&lt;td&gt;2,000/month&lt;/td&gt;
&lt;td&gt;400/month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Marketplace/integrations&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;td&gt;Good&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Self-hosted&lt;/td&gt;
&lt;td&gt;Good&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Built-in security scanning&lt;/td&gt;
&lt;td&gt;Basic (paid)&lt;/td&gt;
&lt;td&gt;Included&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pipeline UI&lt;/td&gt;
&lt;td&gt;Good&lt;/td&gt;
&lt;td&gt;Excellent&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  My Recommendation
&lt;/h2&gt;

&lt;p&gt;Choose &lt;strong&gt;GitHub Actions&lt;/strong&gt; if: your team lives in GitHub, you work with open-source, or you want the largest ecosystem of ready-made integrations.&lt;/p&gt;

&lt;p&gt;Choose &lt;strong&gt;GitLab CI&lt;/strong&gt; if: you need a self-hosted all-in-one platform, work in an enterprise with compliance requirements, or value built-in security scanning.&lt;/p&gt;

&lt;p&gt;For most small-to-medium teams in 2026: GitHub Actions wins on convenience. For enterprises needing full control: GitLab CI wins on completeness.&lt;/p&gt;




&lt;p&gt;Need help setting up a CI/CD pipeline? Browse our DevOps services or contact us directly.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>cicd</category>
      <category>github</category>
      <category>gitlab</category>
    </item>
    <item>
      <title>AWS Cost Optimization: 7 Things You're Probably Overpaying For</title>
      <dc:creator>Alex Boguslavets</dc:creator>
      <pubDate>Wed, 15 Apr 2026 08:54:47 +0000</pubDate>
      <link>https://dev.to/alex_boguslavets_b6280b12/aws-cost-optimization-7-things-youre-probably-overpaying-for-1gmc</link>
      <guid>https://dev.to/alex_boguslavets_b6280b12/aws-cost-optimization-7-things-youre-probably-overpaying-for-1gmc</guid>
      <description>&lt;p&gt;Most AWS bills have hidden waste. I've audited dozens of AWS accounts and the same patterns appear every time. Companies pay 30-50% more than they need to — not because AWS is expensive, but because the defaults are not optimized for cost.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Oversized EC2 Instances
&lt;/h2&gt;

&lt;p&gt;That t3.large running at 5% CPU? You're paying for capacity you don't use. AWS Cost Explorer shows CPU and memory utilization history. Check it. Most workloads can run on a size smaller than what was originally provisioned "just to be safe."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; Enable AWS Compute Optimizer. It analyzes 14 days of metrics and recommends right-sized instances. Potential savings: 30-60% on compute.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Unattached EBS Volumes
&lt;/h2&gt;

&lt;p&gt;Every time you terminate an EC2 instance without deleting its storage volume, the volume keeps charging you. These "orphan" volumes accumulate silently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; Run this to find them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws ec2 describe-volumes &lt;span class="nt"&gt;--filters&lt;/span&gt; &lt;span class="nv"&gt;Name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;status,Values&lt;span class="o"&gt;=&lt;/span&gt;available
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Delete what you don't need. Set "Delete on termination" to true for new instances.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Old Snapshots Nobody Deleted
&lt;/h2&gt;

&lt;p&gt;EBS snapshots cost $0.05/GB/month. A 100GB snapshot taken daily for a year = $1,825/year in snapshots alone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; Use AWS Backup with lifecycle policies to automatically expire snapshots after 30-90 days.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. NAT Gateway Data Transfer
&lt;/h2&gt;

&lt;p&gt;NAT Gateways charge $0.045 per GB processed. If your EC2 instances pull large Docker images through a NAT Gateway, costs add up fast.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; Use VPC endpoints for S3 and ECR (free data transfer). Cache Docker layers locally.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. On-Demand Instances for Stable Workloads
&lt;/h2&gt;

&lt;p&gt;On-Demand is the most expensive pricing model. If your production server runs 24/7, you're overpaying by 30-60% compared to Reserved Instances or Savings Plans.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; Buy a 1-year Compute Savings Plan for your baseline capacity. Keep On-Demand only for burst workloads.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Unused Elastic IPs
&lt;/h2&gt;

&lt;p&gt;Elastic IPs are free when attached to a running instance. When unattached: $0.005/hour = $3.60/month each.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; Audit your EIPs monthly. Release any that aren't attached to a running instance.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. CloudWatch Logs Retention Set to "Never Expire"
&lt;/h2&gt;

&lt;p&gt;CloudWatch Logs storage costs $0.03/GB/month with no expiry by default. Application logs grow quickly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt; Set retention to 30-90 days on all log groups. Export older logs to S3 where storage costs 80% less.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;AWS cost optimization isn't a one-time task — it's an ongoing practice. Set up a monthly cost review, use AWS Cost Anomaly Detection for alerts, and tag everything so you know what each service costs.&lt;/p&gt;

&lt;p&gt;Most clients I work with save 25-40% within the first month of a cloud audit.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Need a cloud cost audit for your AWS account? &lt;a href="https://alexxdevops.com/en/contact" rel="noopener noreferrer"&gt;Get in touch.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>devops</category>
      <category>cloud</category>
      <category>infrastructure</category>
    </item>
  </channel>
</rss>
