<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Docker on Luis Sousa Blog</title>
    <link>https://89393b0c.nuvai-blog.pages.dev/tags/docker/</link>
    <description>Recent content in Docker on Luis Sousa Blog</description>
    <generator>Hugo</generator>
    <language>en</language>
    <lastBuildDate>Sun, 08 Mar 2026 10:00:00 +0000</lastBuildDate>
    <atom:link href="https://89393b0c.nuvai-blog.pages.dev/tags/docker/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Fixing &#39;Robots.txt Unreachable&#39; in Google Search Console with Traefik and Docker</title>
      <link>https://89393b0c.nuvai-blog.pages.dev/posts/fixing-robots-txt-unreachable-traefik-docker/</link>
      <pubDate>Sun, 08 Mar 2026 10:00:00 +0000</pubDate>
      <guid>https://89393b0c.nuvai-blog.pages.dev/posts/fixing-robots-txt-unreachable-traefik-docker/</guid>
      <description>&lt;p&gt;We run a travel blog (&lt;a href=&#34;https://joyofexploringtheworld.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;joyofexploringtheworld.com&lt;/a&gt;) on Docker Compose with Traefik v3 and Cloudflare. One morning Google Search Console showed every page blocked from indexing with &amp;ldquo;Failed: Robots.txt unreachable&amp;rdquo;. The site was working fine in a browser, so what was going on?&lt;/p&gt;&#xA;&lt;p&gt;Two separate issues were conspiring to break Googlebot&amp;rsquo;s ability to fetch &lt;code&gt;/robots.txt&lt;/code&gt;. Here&amp;rsquo;s what we found and how we fixed both.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-setup&#34;&gt;&#xA;  The setup&#xA;  &lt;a class=&#34;heading-link&#34; href=&#34;#the-setup&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;&#xA;    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;&#xA;  &lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;Our WordPress service sits on two Docker networks: &lt;code&gt;app-network&lt;/code&gt; (shared with Traefik, Redis, imgproxy) and &lt;code&gt;db-network&lt;/code&gt; (shared with MariaDB). We run two scaled WordPress containers behind Traefik&amp;rsquo;s load balancer.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Why Datadog Apache Metrics Showed 404 (And When to Disable the Check)</title>
      <link>https://89393b0c.nuvai-blog.pages.dev/posts/datadog-apache-404-wordpress-docker/</link>
      <pubDate>Sat, 07 Mar 2026 12:12:00 +0000</pubDate>
      <guid>https://89393b0c.nuvai-blog.pages.dev/posts/datadog-apache-404-wordpress-docker/</guid>
      <description>&lt;p&gt;We run &lt;a href=&#34;https://joyofexploringtheworld.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;joyofexploringtheworld.com&lt;/a&gt; with Datadog for observability. After setting up the Datadog Agent, we noticed the Apache integration was logging 404 errors every 15 seconds. Here&amp;rsquo;s why—and two ways to fix it.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-problem&#34;&gt;&#xA;  The problem&#xA;  &lt;a class=&#34;heading-link&#34; href=&#34;#the-problem&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;&#xA;    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;&#xA;  &lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;Datadog&amp;rsquo;s Apache integration polls &lt;code&gt;http://localhost/server-status?auto&lt;/code&gt; to scrape metrics (requests per second, busy workers, etc.). The official &lt;code&gt;wordpress:latest&lt;/code&gt; Docker image does not enable Apache&amp;rsquo;s &lt;code&gt;mod_status&lt;/code&gt; module. So the endpoint doesn&amp;rsquo;t exist, and every poll returns 404.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Automated WordPress Backups to Hetzner with Docker (Zero Plugins)</title>
      <link>https://89393b0c.nuvai-blog.pages.dev/posts/wordpress-docker-automated-backups-hetzner/</link>
      <pubDate>Sat, 07 Mar 2026 12:08:00 +0000</pubDate>
      <guid>https://89393b0c.nuvai-blog.pages.dev/posts/wordpress-docker-automated-backups-hetzner/</guid>
      <description>&lt;p&gt;We run a travel blog at &lt;a href=&#34;https://joyofexploringtheworld.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;joyofexploringtheworld.com&lt;/a&gt; on a single VPS with Docker Compose. Managed backup plugins add overhead, cost money, and only back up what WordPress can see. We wanted to back up everything—volumes, configs, database—automatically, with offsite copies. Here&amp;rsquo;s how we did it with zero WordPress plugins.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-backup-service&#34;&gt;&#xA;  The backup service&#xA;  &lt;a class=&#34;heading-link&#34; href=&#34;#the-backup-service&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;&#xA;    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;&#xA;  &lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;We use &lt;a href=&#34;https://github.com/offen/docker-volume-backup&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;offen/docker-volume-backup&lt;/a&gt; as a sidecar container in our Docker Compose stack. It runs on a cron schedule, tars up the mounted volumes, and ships the archive to a remote Hetzner Storage Box via SFTP.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Self-hosted image optimization for WordPress with imgproxy (no premium plugins)</title>
      <link>https://89393b0c.nuvai-blog.pages.dev/posts/self-hosted-wordpress-imgproxy/</link>
      <pubDate>Sat, 07 Mar 2026 12:06:00 +0000</pubDate>
      <guid>https://89393b0c.nuvai-blog.pages.dev/posts/self-hosted-wordpress-imgproxy/</guid>
      <description>&lt;p&gt;We run a travel blog (&lt;a href=&#34;https://joyofexploringtheworld.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;joyofexploringtheworld.com&lt;/a&gt;) on a budget VPS with Docker Compose and free Cloudflare. Premium image plugins like ShortPixel charge for resize and optimize—we wanted dynamic images without recurring costs. Here’s how we did it with imgproxy.&lt;/p&gt;&#xA;&lt;h2 id=&#34;why-imgproxy&#34;&gt;&#xA;  Why imgproxy&#xA;  &lt;a class=&#34;heading-link&#34; href=&#34;#why-imgproxy&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;&#xA;    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;&#xA;  &lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;imgproxy runs in Docker, supports signed URLs and allowlisted sources, and outputs WebP/AVIF. We use the official image &lt;code&gt;ghcr.io/imgproxy/imgproxy&lt;/code&gt; and pin a version tag for stable deploys. No post edits needed: we rewrite image URLs at runtime via a WordPress MU-plugin so existing content and our Bricksy Pro FSE output stay unchanged.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Running WordPress Cron the Right Way When Your Site Lives in Docker</title>
      <link>https://89393b0c.nuvai-blog.pages.dev/posts/running-wordpress-cron-right-way-docker/</link>
      <pubDate>Sat, 07 Mar 2026 12:05:00 +0000</pubDate>
      <guid>https://89393b0c.nuvai-blog.pages.dev/posts/running-wordpress-cron-right-way-docker/</guid>
      <description>&lt;p&gt;We host a travel blog (&lt;a href=&#34;https://joyofexploringtheworld.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;joyofexploringtheworld.com&lt;/a&gt;) on a low-cost VPS with Docker Compose and Cloudflare in front. WordPress’s built-in cron was causing intermittent timeouts in our logs. Here’s how we fixed it.&lt;/p&gt;&#xA;&lt;h2 id=&#34;the-problem-with-wordpress-cron-in-docker&#34;&gt;&#xA;  The problem with WordPress cron in Docker&#xA;  &lt;a class=&#34;heading-link&#34; href=&#34;#the-problem-with-wordpress-cron-in-docker&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;&#xA;    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;&#xA;  &lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;WordPress cron normally “pings itself” on each page load—an HTTP POST to the site from inside the container. Behind a CDN and in Docker, that ping can time out, fail, or hit the wrong instance. We saw cURL timeouts in Datadog and unreliable scheduled tasks.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How We Sped Up Our Travel Blog (Without Changing Hosts)</title>
      <link>https://89393b0c.nuvai-blog.pages.dev/posts/how-we-sped-up-our-travel-blog/</link>
      <pubDate>Sat, 07 Mar 2026 12:00:00 +0000</pubDate>
      <guid>https://89393b0c.nuvai-blog.pages.dev/posts/how-we-sped-up-our-travel-blog/</guid>
      <description>&lt;p&gt;We run a travel blog at &lt;a href=&#34;https://joyofexploringtheworld.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;joyofexploringtheworld.com&lt;/a&gt; that helps travellers plan itineraries—hosted on a low-cost VPS with Docker Compose and Cloudflare’s free tier. Here are four changes that improved speed without changing hosts or paying for premium plugins.&lt;/p&gt;&#xA;&lt;h2 id=&#34;1-give-the-database-more-memory&#34;&gt;&#xA;  1. Give the database more memory&#xA;  &lt;a class=&#34;heading-link&#34; href=&#34;#1-give-the-database-more-memory&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;&#xA;    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;&#xA;  &lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;On a 24 GB VPS, MariaDB’s default InnoDB buffer pool (~128 MB) was too small. We increased it to 2 GB and set a 4 GB memory limit on the DB container. Redis’s &lt;code&gt;maxmemory&lt;/code&gt; was raised from 1 GB to 2 GB.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How We Speeded Up Our Travel Blog (Without Changing Hosts)</title>
      <link>https://89393b0c.nuvai-blog.pages.dev/posts/how-we-speeded-up-our-travel-blog/</link>
      <pubDate>Sat, 07 Mar 2026 12:00:00 +0000</pubDate>
      <guid>https://89393b0c.nuvai-blog.pages.dev/posts/how-we-speeded-up-our-travel-blog/</guid>
      <description>&lt;p&gt;We run a travel blog at &lt;a href=&#34;https://joyofexploringtheworld.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;joyofexploringtheworld.com&lt;/a&gt; that helps travellers plan itineraries—hosted on a low-cost VPS with Docker Compose and Cloudflare’s free tier. Here are four changes that improved speed without changing hosts or paying for premium plugins.&lt;/p&gt;&#xA;&lt;h2 id=&#34;1-give-the-database-more-memory&#34;&gt;&#xA;  1. Give the database more memory&#xA;  &lt;a class=&#34;heading-link&#34; href=&#34;#1-give-the-database-more-memory&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;&#xA;    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;&#xA;  &lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;On a 24 GB VPS, MariaDB’s default InnoDB buffer pool (~128 MB) was too small. We increased it to 2 GB and set a 4 GB memory limit on the DB container. Redis’s &lt;code&gt;maxmemory&lt;/code&gt; was raised from 1 GB to 2 GB.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Why Our Site Went Down for an Hour (And What We Fixed)</title>
      <link>https://89393b0c.nuvai-blog.pages.dev/posts/why-our-site-went-down-for-an-hour/</link>
      <pubDate>Sat, 07 Mar 2026 10:00:00 +0000</pubDate>
      <guid>https://89393b0c.nuvai-blog.pages.dev/posts/why-our-site-went-down-for-an-hour/</guid>
      <description>&lt;p&gt;We run a travel blog (&lt;a href=&#34;https://joyofexploringtheworld.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;joyofexploringtheworld.com&lt;/a&gt;) that helps people plan itineraries—hosted on a low-cost VPS with Docker Compose and Cloudflare. One small performance tweak took the whole site offline for an hour. Here&amp;rsquo;s what happened and how we fixed it.&lt;/p&gt;&#xA;&lt;h2 id=&#34;what-went-wrong&#34;&gt;&#xA;  What Went Wrong&#xA;  &lt;a class=&#34;heading-link&#34; href=&#34;#what-went-wrong&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;&#xA;    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;&#xA;  &lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;We added a Traefik compression middleware to speed up responses. The new config lived in a &lt;strong&gt;separate YAML file&lt;/strong&gt;. Traefik was configured to load only a &lt;strong&gt;single file&lt;/strong&gt; (e.g. &lt;code&gt;real-ip.yaml&lt;/code&gt;), not the whole directory. The router referenced &lt;code&gt;compress@file&lt;/code&gt;, but that file was never loaded. Every request failed.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Running a WordPress Travel Blog on a Budget VPS: The Full Docker Stack</title>
      <link>https://89393b0c.nuvai-blog.pages.dev/posts/wordpress-docker-compose-production-stack/</link>
      <pubDate>Sat, 07 Mar 2026 09:00:00 +0000</pubDate>
      <guid>https://89393b0c.nuvai-blog.pages.dev/posts/wordpress-docker-compose-production-stack/</guid>
      <description>&lt;p&gt;We run &lt;a href=&#34;https://joyofexploringtheworld.com&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;joyofexploringtheworld.com&lt;/a&gt; — a travel blog — on a single 24 GB VPS using Docker Compose and free-tier Cloudflare. No managed WordPress hosting, no premium plugins, no surprise invoices. Here is the full stack, laid out so you can steal whatever is useful.&lt;/p&gt;&#xA;&lt;h2 id=&#34;architecture-overview&#34;&gt;&#xA;  Architecture overview&#xA;  &lt;a class=&#34;heading-link&#34; href=&#34;#architecture-overview&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;&#xA;    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;&#xA;  &lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;The request path looks like this:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Internet&#xA;  -&amp;gt; Cloudflare (CDN / APO / edge SSL)&#xA;    -&amp;gt; Traefik v3 (reverse proxy, TLS termination for origin)&#xA;      -&amp;gt; 2 WordPress containers (round-robin with sticky session cookies)&#xA;        -&amp;gt; MariaDB 11 (single-writer database)&#xA;        -&amp;gt; Redis (persistent object cache)&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Alongside the main request path we run a handful of supporting services: &lt;strong&gt;imgproxy&lt;/strong&gt; on a dedicated subdomain for on-the-fly image resizing and format conversion, a &lt;strong&gt;wp-cron sidecar&lt;/strong&gt; that hits &lt;code&gt;wp-cron.php&lt;/code&gt; every five minutes so we can disable the default front-end cron, an &lt;strong&gt;automated backup&lt;/strong&gt; container that dumps the database and syncs uploads to Hetzner Storage Box nightly, and the &lt;strong&gt;Datadog agent&lt;/strong&gt; for logs, traces, and container metrics.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
