<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/feed.xsl" type="text/xsl"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <link rel="self" href="https://pbb.io/blog.atom"/>
  <subtitle>Posts and learnings about software development, functional programming, and the web.</subtitle>
  <author>
    <name>Phil-Bastian Berndt</name>
    <email>me@pbb.io</email>
  </author>
  <id>https://pbb.io/</id>
  <title/>
  <updated>2026-08-08T16:06:46.739794Z</updated>
  <entry>
    <content type="html">&lt;p&gt;Dropping the iframe only gets you halfway, because the thumbnail still phones home. What it takes to serve YouTube preview images from your own domain.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://pbb.io/blog/youtube-thumbnail-proxy&quot;&gt;Read more…&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-07-31T00:00:00Z</published>
    <author>
      <name>Phil-Bastian Berndt</name>
    </author>
    <link href="https://pbb.io/blog/youtube-thumbnail-proxy"/>
    <id>https://pbb.io/blog/youtube-thumbnail-proxy</id>
    <title>Embedding YouTube without leaking your readers&apos; IPs</title>
    <updated>2026-07-31T00:00:00Z</updated>
  </entry>
  <entry>
    <content type="html">&lt;p&gt;A book slug returning 400 as an Ecto.Query.CastError, because a sixteen-byte string is also a valid raw UUID. Why casting is the wrong way to tell ids and slugs apart.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://pbb.io/blog/ecto-uuid-cast-sixteen-bytes&quot;&gt;Read more…&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-07-30T00:00:00Z</published>
    <author>
      <name>Phil-Bastian Berndt</name>
    </author>
    <link href="https://pbb.io/blog/ecto-uuid-cast-sixteen-bytes"/>
    <id>https://pbb.io/blog/ecto-uuid-cast-sixteen-bytes</id>
    <title>Ecto.UUID.cast/1 will eat anything sixteen bytes long</title>
    <updated>2026-07-30T00:00:00Z</updated>
  </entry>
  <entry>
    <content type="html">&lt;p&gt;Sunday evening, three of the four Raspberry Pi nodes in my k3s cluster went NotReady at once. SSH? &lt;code&gt;Connection reset by peer&lt;/code&gt;. The nodes weren’t dead — they just wouldn’t talk to anyone. One of them only came back after a power cycle.&lt;/p&gt;
&lt;p&gt;The culprit: swap. Raspberry Pi OS ships with &lt;code&gt;dphys-swapfile&lt;/code&gt; enabled, a swapfile sitting on the SD card. A stock kubelet refuses to start while swap is on (&lt;code&gt;--fail-swap-on&lt;/code&gt; defaults to true, and kubeadm’s preflight checks make you disable it), but k3s sets &lt;code&gt;fail-swap-on=false&lt;/code&gt; for you. So a k3s cluster on Pis runs on swap from day one, and nothing ever tells you.&lt;/p&gt;
&lt;p&gt;Kubernetes wants swap off because its whole memory model assumes it. When a node runs out of RAM, the kubelet evicts pods or the kernel OOM-kills them, and they get restarted elsewhere. Ugly, but fast — and self-healing. With swap, the kernel instead does you the “favor” of paging memory out to storage. On an SD card, that means the node grinds into a thrash loop: nothing gets killed, nothing recovers, everything just gets slower until the kubelet misses its lease renewals (hello NotReady) and sshd can’t even finish a handshake. Swap converts a fast, recoverable pod failure into a slow node death that ends at the power outlet.&lt;/p&gt;
&lt;p&gt;Two more things I learned while cleaning up:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;swapoff&lt;/code&gt; on a struggling node looks hung. It isn’t — it has to page everything back into RAM first, and pulling that off an SD card under memory pressure takes minutes. Watch it instead of killing it:&lt;/p&gt;
&lt;pre class=&quot;lumis lumis-themes mocha latte&quot; style=&quot;--lumis-mocha: #cdd6f4; --lumis-mocha-bg: #1e1e2e; --lumis-latte: #4c4f69; --lumis-latte-bg: #eff1f5;&quot;&gt;&lt;code class=&quot;language-bash&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;--lumis-latte: #1e66f5; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #89b4fa; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;watch&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;&amp;#39;cat /proc/swaps; echo; free -h&amp;#39;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The permanent fix on Raspberry Pi OS:&lt;/p&gt;
&lt;pre class=&quot;lumis lumis-themes mocha latte&quot; style=&quot;--lumis-mocha: #cdd6f4; --lumis-mocha-bg: #1e1e2e; --lumis-latte: #4c4f69; --lumis-latte-bg: #eff1f5;&quot;&gt;&lt;code class=&quot;language-bash&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;--lumis-mocha: #89b4fa; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #1e66f5; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;sudo&lt;/span&gt; &lt;span style=&quot;--lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;dphys-swapfile&lt;/span&gt; &lt;span style=&quot;--lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;swapoff&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;--lumis-mocha: #89b4fa; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #1e66f5; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;sudo&lt;/span&gt; &lt;span style=&quot;--lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;systemctl&lt;/span&gt; &lt;span style=&quot;--lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;disable&lt;/span&gt; &lt;span style=&quot;--lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;--now&lt;/span&gt; &lt;span style=&quot;--lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;dphys-swapfile&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Postscript: since Kubernetes 1.34, swap is actually supported — &lt;code&gt;NodeSwap&lt;/code&gt; went GA with its &lt;code&gt;LimitedSwap&lt;/code&gt; mode for burstable pods. But that’s a deliberate, configured trade-off, not a distro quietly leaving a swapfile on your SD card.&lt;/p&gt;</content>
    <published>2026-04-12T00:00:00Z</published>
    <author>
      <name>Phil-Bastian Berndt</name>
    </author>
    <link href="https://pbb.io/blog/k8s-swap-zombie-nodes"/>
    <id>https://pbb.io/blog/k8s-swap-zombie-nodes</id>
    <title>TIL swap turns Kubernetes OOM kills into zombie nodes</title>
    <updated>2026-04-12T00:00:00Z</updated>
  </entry>
  <entry>
    <content type="html">&lt;p&gt;A simple CSS trick to make light-background screenshots look good in dark mode without maintaining two versions of every image.&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://pbb.io/blog/invert-images-dark-mode-css&quot;&gt;Read more…&lt;/a&gt;&lt;/p&gt;</content>
    <published>2026-03-21T00:00:00Z</published>
    <author>
      <name>Phil-Bastian Berndt</name>
    </author>
    <link href="https://pbb.io/blog/invert-images-dark-mode-css"/>
    <id>https://pbb.io/blog/invert-images-dark-mode-css</id>
    <title>Inverting images for dark mode with pure CSS</title>
    <updated>2026-03-21T00:00:00Z</updated>
  </entry>
  <entry>
    <content type="html">&lt;p&gt;Since v1.3.9, Bun supports &lt;code&gt;--parallel&lt;/code&gt; and &lt;code&gt;--sequential&lt;/code&gt; flags on &lt;code&gt;bun run&lt;/code&gt;,
eliminating the need for &lt;code&gt;npm-run-all2&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;lumis lumis-themes latte mocha&quot; style=&quot;--lumis-latte: #4c4f69; --lumis-latte-bg: #eff1f5; --lumis-mocha: #cdd6f4; --lumis-mocha-bg: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-json&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;{&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;2&quot;&gt;  &lt;span style=&quot;--lumis-latte: #7287fd; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #b4befe; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;&amp;quot;scripts&amp;quot;&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;{&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;3&quot;&gt;    &lt;span style=&quot;--lumis-latte: #7287fd; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #b4befe; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;&amp;quot;install&amp;quot;&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;&amp;quot;bun run --sequential &amp;#39;install:*&amp;#39;&amp;quot;&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;4&quot;&gt;    &lt;span style=&quot;--lumis-latte: #7287fd; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #b4befe; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;&amp;quot;install:copy-files&amp;quot;&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;&amp;quot;copy-files-from-to&amp;quot;&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;5&quot;&gt;    &lt;span style=&quot;--lumis-latte: #7287fd; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #b4befe; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;&amp;quot;install:whatever&amp;quot;&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;&amp;quot;...&amp;quot;&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;6&quot;&gt;    &lt;span style=&quot;--lumis-latte: #7287fd; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #b4befe; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;&amp;quot;lint&amp;quot;&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;&amp;quot;bun run --parallel &amp;#39;lint:*&amp;#39;&amp;quot;&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;7&quot;&gt;    &lt;span style=&quot;--lumis-latte: #7287fd; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #b4befe; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;&amp;quot;lint:credo&amp;quot;&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;&amp;quot;mix credo --strict&amp;quot;&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;8&quot;&gt;    &lt;span style=&quot;--lumis-latte: #7287fd; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #b4befe; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;&amp;quot;lint:eslint&amp;quot;&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;&amp;quot;eslint .&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;9&quot;&gt;  &lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;}&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;10&quot;&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;}&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Glob patterns like &lt;code&gt;&amp;#39;install:*&amp;#39;&lt;/code&gt; match all scripts with that prefix (just like &lt;code&gt;npm-run-all2&lt;/code&gt;’s &lt;code&gt;run-s install:*&lt;/code&gt;).&lt;/p&gt;</content>
    <published>2026-02-09T00:00:00Z</published>
    <author>
      <name>Phil-Bastian Berndt</name>
    </author>
    <link href="https://pbb.io/blog/bun-run-parallel-sequential"/>
    <id>https://pbb.io/blog/bun-run-parallel-sequential</id>
    <title>TIL Bun has built-in parallel and sequential script running</title>
    <updated>2026-02-09T00:00:00Z</updated>
  </entry>
  <entry>
    <content type="html">&lt;p&gt;If a test triggers noisy log output, you can use &lt;code&gt;ExUnit.CaptureLog.capture_log/2&lt;/code&gt; to capture the noisy function:&lt;/p&gt;
&lt;pre class=&quot;lumis lumis-themes mocha latte&quot; style=&quot;--lumis-mocha: #cdd6f4; --lumis-mocha-bg: #1e1e2e; --lumis-latte: #4c4f69; --lumis-latte-bg: #eff1f5;&quot;&gt;&lt;code class=&quot;language-elixir&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;--lumis-latte: #8839ef; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #cba6f7; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;import&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #df8e1d; --lumis-latte-font-style: italic; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #f9e2af; --lumis-mocha-font-style: italic; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;ExUnit.CaptureLog&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;2&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;--lumis-latte: #1e66f5; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #89b4fa; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;test&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;&amp;quot;logs a warning&amp;quot;&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #8839ef; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #cba6f7; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;do&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;4&quot;&gt;  &lt;span style=&quot;--lumis-latte: #4c4f69; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #cdd6f4; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;log&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #04a5e5; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #89dceb; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #1e66f5; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #89b4fa; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;capture_log&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #8839ef; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #cba6f7; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;fn&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #04a5e5; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #89dceb; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;-&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;5&quot;&gt;    &lt;span style=&quot;--lumis-latte: #df8e1d; --lumis-latte-font-style: italic; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #f9e2af; --lumis-mocha-font-style: italic; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;MyApp&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #04a5e5; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #89dceb; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #1e66f5; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #89b4fa; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;noisy_function&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;6&quot;&gt;  &lt;span style=&quot;--lumis-latte: #8839ef; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #cba6f7; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;end&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;7&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;8&quot;&gt;  &lt;span style=&quot;--lumis-latte: #1e66f5; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #89b4fa; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;assert&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #4c4f69; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #cdd6f4; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;log&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #04a5e5; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #89dceb; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;=~&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;&amp;quot;something went wrong&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;9&quot;&gt;&lt;span style=&quot;--lumis-latte: #8839ef; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #cba6f7; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To silence logs for the whole test, use the &lt;code&gt;@tag&lt;/code&gt; attribute:&lt;/p&gt;
&lt;pre class=&quot;lumis lumis-themes mocha latte&quot; style=&quot;--lumis-mocha: #cdd6f4; --lumis-mocha-bg: #1e1e2e; --lumis-latte: #4c4f69; --lumis-latte-bg: #eff1f5;&quot;&gt;&lt;code class=&quot;language-elixir&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;--lumis-mocha: #fab387; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #fe640b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;@&lt;/span&gt;&lt;span style=&quot;--lumis-mocha: #fab387; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #fe640b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;tag &lt;/span&gt;&lt;span style=&quot;--lumis-mocha: #f2cdcd; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #dd7878; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;capture_log: &lt;/span&gt;&lt;span style=&quot;--lumis-mocha: #fab387; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #fe640b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;true&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;--lumis-mocha: #89b4fa; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #1e66f5; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;test&lt;/span&gt; &lt;span style=&quot;--lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;&amp;quot;something that logs warnings&amp;quot;&lt;/span&gt; &lt;span style=&quot;--lumis-mocha: #cba6f7; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #8839ef; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;do&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;3&quot;&gt;  &lt;span style=&quot;--lumis-mocha: #89b4fa; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #1e66f5; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;assert&lt;/span&gt; &lt;span style=&quot;--lumis-mocha: #f9e2af; --lumis-mocha-font-style: italic; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #df8e1d; --lumis-latte-font-style: italic; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;MyApp&lt;/span&gt;&lt;span style=&quot;--lumis-mocha: #89dceb; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #04a5e5; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--lumis-mocha: #89b4fa; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #1e66f5; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;noisy_function&lt;/span&gt;&lt;span style=&quot;--lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;--lumis-mocha: #89dceb; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #04a5e5; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;==&lt;/span&gt; &lt;span style=&quot;--lumis-mocha: #f2cdcd; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #dd7878; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;:ok&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;--lumis-mocha: #cba6f7; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #8839ef; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or enable it globally for all tests in &lt;code&gt;test/test_helper.exs&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;lumis lumis-themes latte mocha&quot; style=&quot;--lumis-latte: #4c4f69; --lumis-latte-bg: #eff1f5; --lumis-mocha: #cdd6f4; --lumis-mocha-bg: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-elixir&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;--lumis-latte: #df8e1d; --lumis-latte-font-style: italic; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #f9e2af; --lumis-mocha-font-style: italic; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;ExUnit&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #04a5e5; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #89dceb; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #1e66f5; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #89b4fa; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;start&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #dd7878; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #f2cdcd; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;capture_log: &lt;/span&gt;&lt;span style=&quot;--lumis-latte: #fe640b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #fab387; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;true&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In all cases, if a test fails, the captured logs are included in the failure report.&lt;/p&gt;</content>
    <published>2025-12-05T00:00:00Z</published>
    <author>
      <name>Phil-Bastian Berndt</name>
    </author>
    <link href="https://pbb.io/blog/exunit-capture-log"/>
    <id>https://pbb.io/blog/exunit-capture-log</id>
    <title>TIL how to suppress log output in ExUnit tests</title>
    <updated>2025-12-05T00:00:00Z</updated>
  </entry>
  <entry>
    <content type="html">&lt;p&gt;macOS stores a “file create date” that most tools can’t modify.
&lt;code&gt;exiftool&lt;/code&gt; can change both the creation and modification dates of all files in a folder at once:&lt;/p&gt;
&lt;pre class=&quot;lumis lumis-themes latte mocha&quot; style=&quot;--lumis-latte: #4c4f69; --lumis-latte-bg: #eff1f5; --lumis-mocha: #cdd6f4; --lumis-mocha-bg: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-bash&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;--lumis-latte: #1e66f5; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #89b4fa; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;exiftool&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;&amp;quot;-FileCreateDate=2021:09:28 12:00:00&amp;quot;&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;&amp;quot;-FileModifyDate=2021:09:28 12:00:00&amp;quot;&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;-overwrite_original&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;.&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;-overwrite_original&lt;/code&gt; flag prevents exiftool from creating backup copies.&lt;/p&gt;</content>
    <published>2025-08-11T00:00:00Z</published>
    <author>
      <name>Phil-Bastian Berndt</name>
    </author>
    <link href="https://pbb.io/blog/macos-change-file-create-date"/>
    <id>https://pbb.io/blog/macos-change-file-create-date</id>
    <title>TIL how to bulk-change file creation dates on macOS</title>
    <updated>2025-08-11T00:00:00Z</updated>
  </entry>
  <entry>
    <content type="html">&lt;p&gt;Bash can open TCP connections via &lt;code&gt;/dev/tcp&lt;/code&gt; without needing &lt;code&gt;curl&lt;/code&gt;, &lt;code&gt;wget&lt;/code&gt;, or &lt;code&gt;nc&lt;/code&gt; installed.
This is handy for Docker healthchecks in minimal images:&lt;/p&gt;
&lt;pre class=&quot;lumis lumis-themes mocha latte&quot; style=&quot;--lumis-mocha: #cdd6f4; --lumis-mocha-bg: #1e1e2e; --lumis-latte: #4c4f69; --lumis-latte-bg: #eff1f5;&quot;&gt;&lt;code class=&quot;language-yaml&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;--lumis-latte: #7287fd; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #b4befe; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;services&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;2&quot;&gt;  &lt;span style=&quot;--lumis-latte: #7287fd; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #b4befe; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;collabora&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;3&quot;&gt;    &lt;span style=&quot;--lumis-latte: #7287fd; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #b4befe; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;image&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;collabora/code&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;4&quot;&gt;    &lt;span style=&quot;--lumis-latte: #7287fd; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #b4befe; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;healthcheck&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;5&quot;&gt;      &lt;span style=&quot;--lumis-latte: #7287fd; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #b4befe; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;test&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;bash -c &amp;quot;exec 6&amp;lt;&amp;gt; /dev/tcp/localhost/9980&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;6&quot;&gt;      &lt;span style=&quot;--lumis-latte: #7287fd; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #b4befe; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;interval&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;15s&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;7&quot;&gt;      &lt;span style=&quot;--lumis-latte: #7287fd; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #b4befe; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;retries&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #fe640b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #fab387; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;5&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;8&quot;&gt;      &lt;span style=&quot;--lumis-latte: #7287fd; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #b4befe; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;start_period&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;60s&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;9&quot;&gt;      &lt;span style=&quot;--lumis-latte: #7287fd; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #b4befe; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;timeout&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;10s&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;exec 6&amp;lt;&amp;gt; /dev/tcp/localhost/9980&lt;/code&gt; tries to open file descriptor 6 as a read-write connection to &lt;code&gt;localhost:9980&lt;/code&gt;.
If the port is not listening, it fails and the healthcheck reports unhealthy.&lt;/p&gt;</content>
    <published>2025-05-16T00:00:00Z</published>
    <author>
      <name>Phil-Bastian Berndt</name>
    </author>
    <link href="https://pbb.io/blog/docker-healthcheck-bash-tcp"/>
    <id>https://pbb.io/blog/docker-healthcheck-bash-tcp</id>
    <title>TIL how to check if a port is open using only Bash</title>
    <updated>2025-05-16T00:00:00Z</updated>
  </entry>
  <entry>
    <content type="html">&lt;p&gt;Tailwind 4 exposes all theme values as CSS custom properties, so you can read them from JavaScript via &lt;code&gt;getComputedStyle&lt;/code&gt; without importing any config:&lt;/p&gt;
&lt;pre class=&quot;lumis lumis-themes mocha latte&quot; style=&quot;--lumis-mocha: #cdd6f4; --lumis-mocha-bg: #1e1e2e; --lumis-latte: #4c4f69; --lumis-latte-bg: #eff1f5;&quot;&gt;&lt;code class=&quot;language-javascript&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;--lumis-mocha: #cba6f7; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #8839ef; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;--lumis-mocha: #cdd6f4; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #4c4f69; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;styles&lt;/span&gt; &lt;span style=&quot;--lumis-mocha: #89dceb; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #04a5e5; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;--lumis-mocha: #89b4fa; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #1e66f5; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;getComputedStyle&lt;/span&gt;&lt;span style=&quot;--lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--lumis-mocha: #f38ba8; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #d20f39; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;document&lt;/span&gt;&lt;span style=&quot;--lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--lumis-mocha: #b4befe; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #7287fd; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;documentElement&lt;/span&gt;&lt;span style=&quot;--lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;--lumis-mocha: #cba6f7; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #8839ef; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;const&lt;/span&gt; &lt;span style=&quot;--lumis-mocha: #cdd6f4; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #4c4f69; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;primary&lt;/span&gt; &lt;span style=&quot;--lumis-mocha: #89dceb; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #04a5e5; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;=&lt;/span&gt; &lt;span style=&quot;--lumis-mocha: #cdd6f4; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #4c4f69; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;styles&lt;/span&gt;&lt;span style=&quot;--lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--lumis-mocha: #89b4fa; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #1e66f5; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;getPropertyValue&lt;/span&gt;&lt;span style=&quot;--lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;&amp;quot;--color-primary&amp;quot;&lt;/span&gt;&lt;span style=&quot;--lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none; --lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I used this to style the topbar loading indicator with my theme’s primary color instead of a hardcoded value:&lt;/p&gt;
&lt;pre class=&quot;lumis lumis-themes latte mocha&quot; style=&quot;--lumis-latte: #4c4f69; --lumis-latte-bg: #eff1f5; --lumis-mocha: #cdd6f4; --lumis-mocha-bg: #1e1e2e;&quot;&gt;&lt;code class=&quot;language-javascript&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;--lumis-latte: #4c4f69; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #cdd6f4; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;topbar&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #1e66f5; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #89b4fa; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;config&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;{&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #7287fd; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #b4befe; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;barColors&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;{&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #fe640b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #fab387; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #4c4f69; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #cdd6f4; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;styles&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;.&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #1e66f5; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #89b4fa; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;getPropertyValue&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;(&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;&amp;quot;--color-primary&amp;quot;&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;)&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;}&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;}&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This keeps the color in sync with the theme automatically.&lt;/p&gt;</content>
    <published>2025-04-19T00:00:00Z</published>
    <author>
      <name>Phil-Bastian Berndt</name>
    </author>
    <link href="https://pbb.io/blog/tailwind-theme-vars-in-js"/>
    <id>https://pbb.io/blog/tailwind-theme-vars-in-js</id>
    <title>TIL how to reference Tailwind 4 theme variables in JavaScript</title>
    <updated>2025-04-19T00:00:00Z</updated>
  </entry>
  <entry>
    <content type="html">&lt;p&gt;If you have a Kubernetes CronJob that runs every minute and a job fails, the failed pod sticks around with its resource
reservations still held. With a new pod spawning every minute, your cluster resources can be exhausted very quickly.&lt;/p&gt;
&lt;p&gt;Consider either removing resource requests from frequent CronJobs or setting a strict &lt;code&gt;failedJobsHistoryLimit&lt;/code&gt;:&lt;/p&gt;
&lt;pre class=&quot;lumis lumis-themes mocha latte&quot; style=&quot;--lumis-mocha: #cdd6f4; --lumis-mocha-bg: #1e1e2e; --lumis-latte: #4c4f69; --lumis-latte-bg: #eff1f5;&quot;&gt;&lt;code class=&quot;language-yaml&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;--lumis-latte: #7287fd; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #b4befe; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;apiVersion&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;batch/v1&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;--lumis-latte: #7287fd; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #b4befe; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;kind&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;CronJob&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;--lumis-latte: #7287fd; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #b4befe; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;metadata&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;4&quot;&gt;  &lt;span style=&quot;--lumis-latte: #7287fd; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #b4befe; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;my-job&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;5&quot;&gt;&lt;span style=&quot;--lumis-latte: #7287fd; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #b4befe; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;spec&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;6&quot;&gt;  &lt;span style=&quot;--lumis-latte: #7287fd; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #b4befe; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;schedule&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;&amp;quot;* * * * *&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;7&quot;&gt;  &lt;span style=&quot;--lumis-latte: #7287fd; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #b4befe; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;failedJobsHistoryLimit&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #fe640b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #fab387; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;1&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;8&quot;&gt;  &lt;span style=&quot;--lumis-latte: #7287fd; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #b4befe; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;jobTemplate&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;9&quot;&gt;    &lt;span style=&quot;--lumis-latte: #7287fd; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #b4befe; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;spec&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;10&quot;&gt;      &lt;span style=&quot;--lumis-latte: #7287fd; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #b4befe; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;template&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;11&quot;&gt;        &lt;span style=&quot;--lumis-latte: #7287fd; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #b4befe; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;spec&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;12&quot;&gt;          &lt;span style=&quot;--lumis-latte: #7287fd; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #b4befe; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;containers&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;:&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;13&quot;&gt;            &lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;-&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #7287fd; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #b4befe; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;name&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;my-job&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;14&quot;&gt;              &lt;span style=&quot;--lumis-latte: #7287fd; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #b4befe; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;image&lt;/span&gt;&lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;:&lt;/span&gt; &lt;span style=&quot;--lumis-latte: #40a02b; --lumis-latte-font-style: normal; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #a6e3a1; --lumis-mocha-font-style: normal; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;my-image&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;l-line&quot; data-line=&quot;15&quot;&gt;              &lt;span style=&quot;--lumis-latte: #7c7f93; --lumis-latte-font-style: italic; --lumis-latte-font-weight: normal; --lumis-latte-text-decoration: none; --lumis-mocha: #9399b2; --lumis-mocha-font-style: italic; --lumis-mocha-font-weight: normal; --lumis-mocha-text-decoration: none;&quot;&gt;# no resources.requests here&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Without this, a single downstream outage can cascade into cluster-wide resource pressure just from piling up failed pods.&lt;/p&gt;</content>
    <published>2025-02-06T00:00:00Z</published>
    <author>
      <name>Phil-Bastian Berndt</name>
    </author>
    <link href="https://pbb.io/blog/k8s-cronjob-resource-reservations"/>
    <id>https://pbb.io/blog/k8s-cronjob-resource-reservations</id>
    <title>TIL not to use resource reservations on frequent Kubernetes CronJobs</title>
    <updated>2025-02-06T00:00:00Z</updated>
  </entry>
</feed>