<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Self-Hosted on Luis Sousa Blog</title>
    <link>https://89393b0c.nuvai-blog.pages.dev/tags/self-hosted/</link>
    <description>Recent content in Self-Hosted on Luis Sousa Blog</description>
    <generator>Hugo</generator>
    <language>en</language>
    <lastBuildDate>Sat, 07 Mar 2026 12:06:00 +0000</lastBuildDate>
    <atom:link href="https://89393b0c.nuvai-blog.pages.dev/tags/self-hosted/index.xml" rel="self" type="application/rss+xml" />
    <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 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>
