<?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-04-13T23:45:32.430882Z</updated>
  <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&quot;&gt;&lt;code class=&quot;language-json&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color:#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;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;  &lt;span style=&quot;color:#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;color:#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;color:#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;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;    &lt;span style=&quot;color:#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;color:#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;color:#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;color:#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;line&quot; data-line=&quot;4&quot;&gt;    &lt;span style=&quot;color:#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;color:#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;color:#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;color:#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;line&quot; data-line=&quot;5&quot;&gt;    &lt;span style=&quot;color:#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;color:#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;color:#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;color:#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;line&quot; data-line=&quot;6&quot;&gt;    &lt;span style=&quot;color:#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;color:#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;color:#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;color:#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;line&quot; data-line=&quot;7&quot;&gt;    &lt;span style=&quot;color:#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;color:#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;color:#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;color:#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;line&quot; data-line=&quot;8&quot;&gt;    &lt;span style=&quot;color:#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;color:#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;color:#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;line&quot; data-line=&quot;9&quot;&gt;  &lt;span style=&quot;color:#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;&amp;rbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;10&quot;&gt;&lt;span style=&quot;color:#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;&amp;rbrace;&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&quot;&gt;&lt;code class=&quot;language-elixir&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color:#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;color:#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;line&quot; data-line=&quot;2&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color:#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;color:#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;color:#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;line&quot; data-line=&quot;4&quot;&gt;  &lt;span style=&quot;color:#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;color:#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;color:#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;color:#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;color:#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;color:#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;line&quot; data-line=&quot;5&quot;&gt;    &lt;span style=&quot;color:#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;color:#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;color:#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;color:#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;color:#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;line&quot; data-line=&quot;6&quot;&gt;  &lt;span style=&quot;color:#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;color:#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;line&quot; data-line=&quot;7&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;  &lt;span style=&quot;color:#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;color:#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;color:#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;color:#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;line&quot; data-line=&quot;9&quot;&gt;&lt;span style=&quot;color:#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&quot;&gt;&lt;code class=&quot;language-elixir&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color:#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;@&lt;/span&gt;&lt;span style=&quot;color:#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;tag &lt;/span&gt;&lt;span style=&quot;color:#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;color:#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;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color:#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;color:#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 that logs warnings&amp;quot;&lt;/span&gt; &lt;span style=&quot;color:#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;line&quot; data-line=&quot;3&quot;&gt;  &lt;span style=&quot;color:#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;color:#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;color:#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;color:#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;color:#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;color:#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;color:#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;color:#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;:ok&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color:#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;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&quot;&gt;&lt;code class=&quot;language-elixir&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color:#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;color:#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;color:#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;color:#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;color:#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;color:#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;color:#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&quot;&gt;&lt;code class=&quot;language-bash&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color:#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;color:#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;color:#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;color:#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;color:#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&quot;&gt;&lt;code class=&quot;language-yaml&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color:#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;color:#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;line&quot; data-line=&quot;2&quot;&gt;  &lt;span style=&quot;color:#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;color:#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;line&quot; data-line=&quot;3&quot;&gt;    &lt;span style=&quot;color:#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;color:#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;color:#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;line&quot; data-line=&quot;4&quot;&gt;    &lt;span style=&quot;color:#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;color:#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;line&quot; data-line=&quot;5&quot;&gt;      &lt;span style=&quot;color:#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;color:#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;color:#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;line&quot; data-line=&quot;6&quot;&gt;      &lt;span style=&quot;color:#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;color:#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;color:#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;line&quot; data-line=&quot;7&quot;&gt;      &lt;span style=&quot;color:#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;color:#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;color:#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;line&quot; data-line=&quot;8&quot;&gt;      &lt;span style=&quot;color:#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;color:#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;color:#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;line&quot; data-line=&quot;9&quot;&gt;      &lt;span style=&quot;color:#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;color:#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;color:#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&quot;&gt;&lt;code class=&quot;language-javascript&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color:#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;const&lt;/span&gt; &lt;span style=&quot;color:#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;color:#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;color:#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;getComputedStyle&lt;/span&gt;&lt;span style=&quot;color:#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;color:#d20f39; --lumis-latte-font-style:normal; --lumis-latte-font-weight:normal; --lumis-latte-text-decoration:none; --lumis-mocha:#f38ba8; --lumis-mocha-font-style:normal; --lumis-mocha-font-weight:normal; --lumis-mocha-text-decoration:none;&quot;&gt;document&lt;/span&gt;&lt;span style=&quot;color:#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;color:#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;documentElement&lt;/span&gt;&lt;span style=&quot;color:#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;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color:#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;const&lt;/span&gt; &lt;span style=&quot;color:#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;primary&lt;/span&gt; &lt;span style=&quot;color:#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;color:#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;color:#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;color:#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;color:#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;color:#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;color:#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;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&quot;&gt;&lt;code class=&quot;language-javascript&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color:#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;color:#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;color:#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;color:#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;color:#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;&amp;lbrace;&lt;/span&gt; &lt;span style=&quot;color:#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;color:#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;color:#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;&amp;lbrace;&lt;/span&gt; &lt;span style=&quot;color:#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;color:#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;color:#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;color:#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;color:#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;color:#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;color:#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;color:#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;color:#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;&amp;rbrace;&lt;/span&gt; &lt;span style=&quot;color:#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;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color:#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&quot;&gt;&lt;code class=&quot;language-yaml&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color:#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;color:#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;color:#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;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color:#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;color:#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;color:#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;line&quot; data-line=&quot;3&quot;&gt;&lt;span style=&quot;color:#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;color:#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;line&quot; data-line=&quot;4&quot;&gt;  &lt;span style=&quot;color:#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;color:#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;color:#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;line&quot; data-line=&quot;5&quot;&gt;&lt;span style=&quot;color:#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;color:#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;line&quot; data-line=&quot;6&quot;&gt;  &lt;span style=&quot;color:#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;color:#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;color:#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;line&quot; data-line=&quot;7&quot;&gt;  &lt;span style=&quot;color:#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;color:#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;color:#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;line&quot; data-line=&quot;8&quot;&gt;  &lt;span style=&quot;color:#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;color:#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;line&quot; data-line=&quot;9&quot;&gt;    &lt;span style=&quot;color:#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;color:#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;line&quot; data-line=&quot;10&quot;&gt;      &lt;span style=&quot;color:#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;color:#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;line&quot; data-line=&quot;11&quot;&gt;        &lt;span style=&quot;color:#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;color:#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;line&quot; data-line=&quot;12&quot;&gt;          &lt;span style=&quot;color:#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;color:#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;line&quot; data-line=&quot;13&quot;&gt;            &lt;span style=&quot;color:#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;color:#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;color:#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;color:#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;line&quot; data-line=&quot;14&quot;&gt;              &lt;span style=&quot;color:#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;color:#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;color:#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;line&quot; data-line=&quot;15&quot;&gt;              &lt;span style=&quot;color:#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>
  <entry>
    <content type="html">&lt;p&gt;&lt;code&gt;Element.scrollIntoView()&lt;/code&gt; scrolls an element’s parent container so that the element becomes visible.
Passing &lt;code&gt;false&lt;/code&gt; aligns the element to the bottom of the scrollable area, which is perfect for keeping a selected item in
view when navigating a list with arrow keys.&lt;/p&gt;
&lt;p&gt;I used this on my blog’s search component. When the user presses arrow keys, Phoenix LiveView pushes an event to the
client, which then scrolls the active result into view:&lt;/p&gt;
&lt;pre class=&quot;lumis&quot;&gt;&lt;code class=&quot;language-javascript&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color:#d20f39; --lumis-latte-font-style:normal; --lumis-latte-font-weight:normal; --lumis-latte-text-decoration:none; --lumis-mocha:#f38ba8; --lumis-mocha-font-style:normal; --lumis-mocha-font-weight:normal; --lumis-mocha-text-decoration:none;&quot;&gt;window&lt;/span&gt;&lt;span style=&quot;color:#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;color:#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;addEventListener&lt;/span&gt;&lt;span style=&quot;color:#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;color:#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;phx:search-choose&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#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;color:#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;color:#e64553; --lumis-latte-font-style:normal; --lumis-latte-font-weight:normal; --lumis-latte-text-decoration:none; --lumis-mocha:#eba0ac; --lumis-mocha-font-style:normal; --lumis-mocha-font-weight:normal; --lumis-mocha-text-decoration:none;&quot;&gt;e&lt;/span&gt;&lt;span style=&quot;color:#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;color:#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;span style=&quot;color:#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;&amp;lbrace;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;  &lt;span style=&quot;color:#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;const&lt;/span&gt; &lt;span style=&quot;color:#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;activeItem&lt;/span&gt; &lt;span style=&quot;color:#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;color:#d20f39; --lumis-latte-font-style:normal; --lumis-latte-font-weight:normal; --lumis-latte-text-decoration:none; --lumis-mocha:#f38ba8; --lumis-mocha-font-style:normal; --lumis-mocha-font-weight:normal; --lumis-mocha-text-decoration:none;&quot;&gt;this&lt;/span&gt;&lt;span style=&quot;color:#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;color:#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;el&lt;/span&gt;&lt;span style=&quot;color:#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;color:#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;querySelector&lt;/span&gt;&lt;span style=&quot;color:#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;color:#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;.menu-active&amp;quot;&lt;/span&gt;&lt;span style=&quot;color:#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;line&quot; data-line=&quot;3&quot;&gt;  &lt;span style=&quot;color:#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;activeItem&lt;/span&gt;&lt;span style=&quot;color:#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;color:#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;scrollIntoView&lt;/span&gt;&lt;span style=&quot;color:#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;color:#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;false&lt;/span&gt;&lt;span style=&quot;color:#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;line&quot; data-line=&quot;4&quot;&gt;&lt;span style=&quot;color:#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;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color:#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;The argument controls alignment:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;true&lt;/code&gt; (default): aligns to the &lt;strong&gt;top&lt;/strong&gt; of the scrollable area&lt;/li&gt;
&lt;li&gt;&lt;code&gt;false&lt;/code&gt;: aligns to the &lt;strong&gt;bottom&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;An object for more control: &lt;code&gt;&amp;lbrace; behavior: &amp;quot;smooth&amp;quot;, block: &amp;quot;nearest&amp;quot; &amp;rbrace;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;</content>
    <published>2025-02-01T00:00:00Z</published>
    <author>
      <name>Phil-Bastian Berndt</name>
    </author>
    <link href="https://pbb.io/blog/scroll-into-view"/>
    <id>https://pbb.io/blog/scroll-into-view</id>
    <title>TIL how to scroll elements into view with JavaScript</title>
    <updated>2025-02-01T00:00:00Z</updated>
  </entry>
  <entry>
    <content type="html">&lt;p&gt;In GitLab CI, the &lt;code&gt;variables&lt;/code&gt; block does not expand other variables at definition time. So this does &lt;strong&gt;not&lt;/strong&gt; work as expected:&lt;/p&gt;
&lt;pre class=&quot;lumis&quot;&gt;&lt;code class=&quot;language-yaml&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color:#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;variables&lt;/span&gt;&lt;span style=&quot;color:#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;line&quot; data-line=&quot;2&quot;&gt;  &lt;span style=&quot;color:#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;DEPLOY_USER&lt;/span&gt;&lt;span style=&quot;color:#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;color:#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;lbrace;DEPLOY_USER:-$CI_REGISTRY_USER&amp;rbrace;&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;  &lt;span style=&quot;color:#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;DEPLOY_TOKEN&lt;/span&gt;&lt;span style=&quot;color:#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;color:#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;lbrace;DEPLOY_TOKEN:-$CI_JOB_TOKEN&amp;rbrace;&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;$CI_REGISTRY_USER&lt;/code&gt; and &lt;code&gt;$CI_JOB_TOKEN&lt;/code&gt; references won’t be resolved in the &lt;code&gt;variables&lt;/code&gt; block because GitLab CI doesn’t support nested variable expansion there.&lt;/p&gt;
&lt;p&gt;The fix is to move the fallback logic into &lt;code&gt;before_script&lt;/code&gt;, where normal shell expansion applies:&lt;/p&gt;
&lt;pre class=&quot;lumis&quot;&gt;&lt;code class=&quot;language-yaml&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color:#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;before_script&lt;/span&gt;&lt;span style=&quot;color:#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;line&quot; data-line=&quot;2&quot;&gt;  &lt;span style=&quot;color:#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;color:#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;export&lt;/span&gt; &lt;span style=&quot;color:#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;DEPLOY_USER&lt;/span&gt;&lt;span style=&quot;color:#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;color:#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;&lt;/span&gt;&lt;span style=&quot;color:#ea76cb; --lumis-latte-font-style:normal; --lumis-latte-font-weight:normal; --lumis-latte-text-decoration:none; --lumis-mocha:#f5c2e7; --lumis-mocha-font-style:normal; --lumis-mocha-font-weight:normal; --lumis-mocha-text-decoration:none;&quot;&gt;$&amp;lbrace;&lt;/span&gt;&lt;span style=&quot;color:#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;DEPLOY_USER&lt;/span&gt;&lt;span style=&quot;color:#ea76cb; --lumis-latte-font-style:normal; --lumis-latte-font-weight:normal; --lumis-latte-text-decoration:none; --lumis-mocha:#f5c2e7; --lumis-mocha-font-style:normal; --lumis-mocha-font-weight:normal; --lumis-mocha-text-decoration:none;&quot;&gt;:-&lt;/span&gt;&lt;span style=&quot;color:#ea76cb; --lumis-latte-font-style:normal; --lumis-latte-font-weight:normal; --lumis-latte-text-decoration:none; --lumis-mocha:#f5c2e7; --lumis-mocha-font-style:normal; --lumis-mocha-font-weight:normal; --lumis-mocha-text-decoration:none;&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;color:#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;CI_REGISTRY_USER&lt;/span&gt;&lt;span style=&quot;color:#ea76cb; --lumis-latte-font-style:normal; --lumis-latte-font-weight:normal; --lumis-latte-text-decoration:none; --lumis-mocha:#f5c2e7; --lumis-mocha-font-style:normal; --lumis-mocha-font-weight:normal; --lumis-mocha-text-decoration:none;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color:#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;&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;3&quot;&gt;  &lt;span style=&quot;color:#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;color:#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;export&lt;/span&gt; &lt;span style=&quot;color:#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;DEPLOY_TOKEN&lt;/span&gt;&lt;span style=&quot;color:#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;color:#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;&lt;/span&gt;&lt;span style=&quot;color:#ea76cb; --lumis-latte-font-style:normal; --lumis-latte-font-weight:normal; --lumis-latte-text-decoration:none; --lumis-mocha:#f5c2e7; --lumis-mocha-font-style:normal; --lumis-mocha-font-weight:normal; --lumis-mocha-text-decoration:none;&quot;&gt;$&amp;lbrace;&lt;/span&gt;&lt;span style=&quot;color:#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;DEPLOY_TOKEN&lt;/span&gt;&lt;span style=&quot;color:#ea76cb; --lumis-latte-font-style:normal; --lumis-latte-font-weight:normal; --lumis-latte-text-decoration:none; --lumis-mocha:#f5c2e7; --lumis-mocha-font-style:normal; --lumis-mocha-font-weight:normal; --lumis-mocha-text-decoration:none;&quot;&gt;:-&lt;/span&gt;&lt;span style=&quot;color:#ea76cb; --lumis-latte-font-style:normal; --lumis-latte-font-weight:normal; --lumis-latte-text-decoration:none; --lumis-mocha:#f5c2e7; --lumis-mocha-font-style:normal; --lumis-mocha-font-weight:normal; --lumis-mocha-text-decoration:none;&quot;&gt;$&lt;/span&gt;&lt;span style=&quot;color:#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;CI_JOB_TOKEN&lt;/span&gt;&lt;span style=&quot;color:#ea76cb; --lumis-latte-font-style:normal; --lumis-latte-font-weight:normal; --lumis-latte-text-decoration:none; --lumis-mocha:#f5c2e7; --lumis-mocha-font-style:normal; --lumis-mocha-font-weight:normal; --lumis-mocha-text-decoration:none;&quot;&gt;&amp;rbrace;&lt;/span&gt;&lt;span style=&quot;color:#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;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is especially relevant when writing reusable CI templates where you want to allow overriding a variable but fall back to a CI-provided default.&lt;/p&gt;</content>
    <published>2024-11-04T00:00:00Z</published>
    <author>
      <name>Phil-Bastian Berndt</name>
    </author>
    <link href="https://pbb.io/blog/gitlab-ci-variable-default-variable"/>
    <id>https://pbb.io/blog/gitlab-ci-variable-default-variable</id>
    <title>TIL how to use a variable as the default for another variable in GitLab CI</title>
    <updated>2024-11-04T00:00:00Z</updated>
  </entry>
  <entry>
    <content type="html">&lt;p&gt;Docker Compose has an &lt;code&gt;include&lt;/code&gt; directive that lets you split your setup into multiple files:&lt;/p&gt;
&lt;pre class=&quot;lumis&quot;&gt;&lt;code class=&quot;language-yaml&quot; translate=&quot;no&quot; tabindex=&quot;0&quot;&gt;&lt;div class=&quot;line&quot; data-line=&quot;1&quot;&gt;&lt;span style=&quot;color:#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;# compose.yml&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;2&quot;&gt;&lt;span style=&quot;color:#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;include&lt;/span&gt;&lt;span style=&quot;color:#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;line&quot; data-line=&quot;3&quot;&gt;  &lt;span style=&quot;color:#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;color:#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;path&lt;/span&gt;&lt;span style=&quot;color:#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;color:#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;./compose/temporal/compose.yml&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;4&quot;&gt;    &lt;span style=&quot;color:#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;env_file&lt;/span&gt;&lt;span style=&quot;color:#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;line&quot; data-line=&quot;5&quot;&gt;      &lt;span style=&quot;color:#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;color:#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;./compose/temporal/.env&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;6&quot;&gt;  &lt;span style=&quot;color:#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;color:#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;path&lt;/span&gt;&lt;span style=&quot;color:#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;color:#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;./compose/compose-db.yml&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;7&quot;&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;8&quot;&gt;&lt;span style=&quot;color:#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;color:#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;line&quot; data-line=&quot;9&quot;&gt;  &lt;span style=&quot;color:#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;app&lt;/span&gt;&lt;span style=&quot;color:#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;line&quot; data-line=&quot;10&quot;&gt;    &lt;span style=&quot;color:#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;depends_on&lt;/span&gt;&lt;span style=&quot;color:#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;line&quot; data-line=&quot;11&quot;&gt;      &lt;span style=&quot;color:#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;color:#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;db&lt;/span&gt;
&lt;/div&gt;&lt;div class=&quot;line&quot; data-line=&quot;12&quot;&gt;      &lt;span style=&quot;color:#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;color:#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;temporal&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each included file is resolved relative to its own directory, so paths within it just work.
The included services can then be referenced directly via &lt;code&gt;depends_on&lt;/code&gt; or networking.
It also works recursively.&lt;/p&gt;</content>
    <published>2024-08-21T00:00:00Z</published>
    <author>
      <name>Phil-Bastian Berndt</name>
    </author>
    <link href="https://pbb.io/blog/docker-compose-include"/>
    <id>https://pbb.io/blog/docker-compose-include</id>
    <title>TIL you can include other files via Docker Compose</title>
    <updated>2024-08-21T00:00:00Z</updated>
  </entry>
</feed>