<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Posts on Hallblazzar: Dev Journal</title>
    <link>https://dev-journal.hallblazzar.dev/posts/</link>
    <description>Recent content in Posts on Hallblazzar: Dev Journal</description>
    <generator>Hugo</generator>
    <language>en</language>
    <lastBuildDate>Sat, 23 May 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://dev-journal.hallblazzar.dev/posts/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>DNS Resolution Issue Caused By NetBird </title>
      <link>https://dev-journal.hallblazzar.dev/posts/2026_may_23_netbird_dns/</link>
      <pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate>
      <guid>https://dev-journal.hallblazzar.dev/posts/2026_may_23_netbird_dns/</guid>
      <description>&lt;p&gt;If you use NetBird as VPN solution and occasionally encounter DNS resolution issue, this topic could help.&lt;/p&gt;&#xA;&lt;h1 id=&#34;background&#34;&gt;&#xA;  Background&#xA;  &lt;a class=&#34;heading-link&#34; href=&#34;#background&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;&#xA;    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;&#xA;  &lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p&gt;I&amp;rsquo;ve been using &lt;a href=&#34;https://netbird.io/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;NetBird&lt;/a&gt; to access my homelab for a while. There are few reasons I chose it:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Sovereignty - I can deploy and gain control over all components.&lt;/li&gt;&#xA;&lt;li&gt;Run Out-Of-Box - NetBird provides good web-based GUI to manage clients and certs. I can control everything through the well-designed web interface without having to interact with config files and CLIs&lt;/li&gt;&#xA;&lt;li&gt;Custom DNS - To provide HTTPs/TLS to my homelab services, I want to bind public domains map to service IPs. However, DNS providers like CloudFlare restrict &lt;a href=&#34;https://en.wikipedia.org/wiki/DNS_rebinding&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;DNS rebinding&lt;/a&gt; to public domains and private IPs. Therefore, an alternative approach is binding private IPs to private DNS records, and mapping them to public DNS records via CNAME. This approach requires VPN solutions to support custom private DNS. Though some people might compelely rely on private DNS and private IP, that means they need to manage certificates by themselves as generally modern SSL issuers like &lt;a href=&#34;https://letsencrypt.org/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Let&amp;rsquo;s Encrypt&lt;/a&gt; require DNS validation, where public domains are necessary (especially for free solutions).&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Other VPN solutions also support some features above like &lt;a href=&#34;https://www.zerotier.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;ZeroTier&lt;/a&gt; and &lt;a href=&#34;https://tailscale.com/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;TailScale&lt;/a&gt;, but their control plane are basically non-open-sourced and cannot be self-hosted.&lt;/p&gt;</description>
    </item>
    <item>
      <title>My Experienc About Kubernetes CNI Plugin Migration</title>
      <link>https://dev-journal.hallblazzar.dev/posts/2026_may_02_cni_migration/</link>
      <pubDate>Sat, 02 May 2026 00:00:00 +0000</pubDate>
      <guid>https://dev-journal.hallblazzar.dev/posts/2026_may_02_cni_migration/</guid>
      <description>&lt;div class=&#34;notice tip&#34;&gt;&#xA;  &lt;div class=&#34;notice-title&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-lightbulb&#34; aria-hidden=&#34;true&#34;&gt;&lt;/i&gt;Tip&#xA;  &lt;/div&gt;&#xA;  &lt;div class=&#34;notice-content&#34;&gt;TL;DR: If you&amp;rsquo;re a developer looking for alternatives and migration plans for CNI plugin on your Kubernetes cluster, Cilium is a good choise which supports live-migration from almost any CNIs, NetworkPolicies and comprehensive observability ecosystems.&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;p&gt;CNI plugin migration for a running Kubernetes cluster, especially in production environment, is never a trivial task. One simple strategy is &lt;a href=&#34;https://www.redhat.com/en/topics/devops/what-is-blue-green-deployment&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Blue/Green deployment&lt;/a&gt;, which provisions a new cluster with target CNI and moving workloads from current cluster to the new one. This approach ensures the least downtime(still need extra setup, e.g., loadbalancer, to ensure availability) and ignores discrepancy between CNIs. However, what if in-place migration is necessary? This is not common but challenging senario, and mostly needed when operating a cluster with stateful or unmanaged workloads. For instance, a platform provides computing resource by Kubernetes but operators have no control to services deployed on it. If operators want to migrate CNI without letting users aware/involve, in-place migration will still be required.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Kubernetes Dynamic Client Requires Plural Resource Type</title>
      <link>https://dev-journal.hallblazzar.dev/posts/2026_may_01_k8s_dyn_plural/</link>
      <pubDate>Fri, 01 May 2026 00:00:00 +0000</pubDate>
      <guid>https://dev-journal.hallblazzar.dev/posts/2026_may_01_k8s_dyn_plural/</guid>
      <description>&lt;p&gt;In GoLang, in addition to invoking &lt;code&gt;kubectl&lt;/code&gt;, an alternative approach to access CRDs on a Kubernetes cluster via &lt;a href=&#34;https://pkg.go.dev/k8s.io/client-go/dynamic#ResourceInterface&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Dynamic client&lt;/a&gt;. It allows users to access CRDs programmatically without &lt;code&gt;exec&lt;/code&gt; module and &lt;code&gt;kubectl&lt;/code&gt;, which requires handling shells, exit code and STDIN/STDOU. However, it seems the module is not well document. An general error type users encounter often is &lt;code&gt;resource type not found&lt;/code&gt; related error, which could be triggered by the code:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;func&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;GetNetworkPolicy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ctx&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;dynamic&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Interface&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;policy&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;error&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#x9;&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;gvr&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;schema&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;GroupVersionResource&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;cilium.io&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Version&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;v2&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Resource&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;ciliumclusterwidenetworkpolicy&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;policy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;:=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Resource&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;gvr&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ctx&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;policy&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;metav1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;GetOptions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{})&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;!=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;kc&#34;&gt;nil&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;fmt&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;Errof&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Error getting policy: %v&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;err&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&#x9;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;// ... snipped&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The issue here is the resource type. I didn&amp;rsquo;t find documents mention that directly, but value of&lt;code&gt;Resource&lt;/code&gt; member in the &lt;code&gt;GroupVersionResource&lt;/code&gt; structure should be plural. To make code above work correctly, &lt;code&gt;ciliumclusterwidenetworkpolicy&lt;/code&gt; should be &lt;code&gt;ciliumclusterwidenetworkpolicies&lt;/code&gt;. This is different from writing K8s objects in yaml format which singular is used. By contrary, if the problem is target objects not found, then users should get errors like &lt;code&gt;ciliumclusterwidenetworkpolicy not found&lt;/code&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Adopting Dev Container In Development Workflow</title>
      <link>https://dev-journal.hallblazzar.dev/posts/2026_apr_20_devcontainer/</link>
      <pubDate>Mon, 20 Apr 2026 00:00:00 +0000</pubDate>
      <guid>https://dev-journal.hallblazzar.dev/posts/2026_apr_20_devcontainer/</guid>
      <description>&lt;p&gt;This is a brief introduction about the way I adopt Dev Container in my development workflow. If you&amp;rsquo;re interested in free yourself from managing different development environments across different programming languages/framworks while using modern IDEs. Dev Container could be a good choice for you.&lt;/p&gt;&#xA;&lt;p&gt;If you&amp;rsquo;re a software developer work across multiple projects, sometimes you might need to switch between different versions of programming languages/framwork. Though modern programming languages support multiple version managers like &lt;a href=&#34;https://github.com/nvm-sh/nvm&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;NVM&lt;/a&gt; for NodeJS and &lt;a href=&#34;https://docs.python.org/3/library/venv.html&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Virtual Environment&lt;/a&gt; for Python, users still need to carefully setup/select environments to avoid changing global runtime. &lt;a href=&#34;https://docs.python.org/3/library/venv.html&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;asdf&lt;/a&gt; is a great all-in-one solution but requires extra setup for projects.&lt;/p&gt;</description>
    </item>
    <item>
      <title>How Did I Choose OS For My Laptop?</title>
      <link>https://dev-journal.hallblazzar.dev/posts/2026_apr_19_choose_os/</link>
      <pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate>
      <guid>https://dev-journal.hallblazzar.dev/posts/2026_apr_19_choose_os/</guid>
      <description>&lt;div class=&#34;notice tip&#34;&gt;&#xA;  &lt;div class=&#34;notice-title&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-lightbulb&#34; aria-hidden=&#34;true&#34;&gt;&lt;/i&gt;Tip&#xA;  &lt;/div&gt;&#xA;  &lt;div class=&#34;notice-content&#34;&gt;TL;DR: If you&amp;rsquo;re a developer who is struggling on selecting Linux based desktop environment for your laptop/workstation, Debian can be the most reliable solution for you. Otherwise, consider pickup and test from &lt;a href=&#34;https://distrowatch.com/dwres.php?resource=popularity&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;DistroWatch&lt;/a&gt; to find most suitable one for you.&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;p&gt;It&amp;rsquo;s a story about how I chose OS for my new laptop, which is also a 2 + 3 months journey.&lt;/p&gt;&#xA;&lt;p&gt;Last November (2025), I spent about $1,200 on a Dell Pro 14 Laptop (64 GB RAM, AMD Ryzen 5 220) with Black Friday deal to replace my Surface Laptop 3 (32 GB RAM, i7-1065G7). The Surface Laptop 3 was pretty good for developers, but Windows 11 and recent desktop applications (plus WSL2) seems too heavy to it. It just ran slower from time to time even after re-install the whole system. As a result, by the end of last year, I decided to replace it.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Watchout Cloud Run With Cloud Storage Volumes</title>
      <link>https://dev-journal.hallblazzar.dev/posts/2026_apr_13_gcp/</link>
      <pubDate>Mon, 13 Apr 2026 00:00:00 +0000</pubDate>
      <guid>https://dev-journal.hallblazzar.dev/posts/2026_apr_13_gcp/</guid>
      <description>&lt;p&gt;Few things I recently encountered while deploying Cloud Run services with Cloud Storage volumes on GCP, which I think worth of sharing.&lt;/p&gt;&#xA;&lt;h2 id=&#34;container-exit-without-reporting-errors&#34;&gt;&#xA;  Container Exit Without Reporting Errors&#xA;  &lt;a class=&#34;heading-link&#34; href=&#34;#container-exit-without-reporting-errors&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;&#xA;    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;&#xA;  &lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;In general, when creating a Cloud Run service with Cloud Storage volume, the Service Account used to perform the service creation operation should have Storage Object User or Admin role. If not, you might see:&lt;/p&gt;</description>
    </item>
    <item>
      <title>lbhepler: A Python Based Wrapper For Debian Live Build</title>
      <link>https://dev-journal.hallblazzar.dev/posts/2026_apr_12_lbhelper/</link>
      <pubDate>Sun, 12 Apr 2026 00:00:00 +0000</pubDate>
      <guid>https://dev-journal.hallblazzar.dev/posts/2026_apr_12_lbhelper/</guid>
      <description>&lt;div class=&#34;notice tip&#34;&gt;&#xA;  &lt;div class=&#34;notice-title&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-lightbulb&#34; aria-hidden=&#34;true&#34;&gt;&lt;/i&gt;Tip&#xA;  &lt;/div&gt;&#xA;  &lt;div class=&#34;notice-content&#34;&gt;&lt;p&gt;TL;DR: If you&amp;rsquo;re trying to build your own Debian image(especially for desktop environment), I created a Python3 based library, &lt;a href=&#34;https://hallblazzar.github.io/lbhelper/source/index.html&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;lbhelper&lt;/a&gt;, could help you simplify the work.&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Online document - &lt;a href=&#34;https://hallblazzar.github.io/lbhelper/source/index.html&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;https://hallblazzar.github.io/lbhelper/source/index.html&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;GitHub - &lt;a href=&#34;https://github.com/HallBlazzar/lbhelper&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;https://github.com/HallBlazzar/lbhelper&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;A Debian Image based on this library, which is also the OS I run on my laptop - &lt;a href=&#34;https://github.com/HallBlazzar/myos&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;https://github.com/HallBlazzar/myos&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;PyPi page - &lt;a href=&#34;https://pypi.org/project/lbhelper/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;https://pypi.org/project/lbhelper/&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&lt;/div&gt;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;h2 id=&#34;image-customization-options&#34;&gt;&#xA;  Image Customization Options&#xA;  &lt;a class=&#34;heading-link&#34; href=&#34;#image-customization-options&#34;&gt;&#xA;    &lt;i class=&#34;fa-solid fa-link&#34; aria-hidden=&#34;true&#34; title=&#34;Link to heading&#34;&gt;&lt;/i&gt;&#xA;    &lt;span class=&#34;sr-only&#34;&gt;Link to heading&lt;/span&gt;&#xA;  &lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;If you&amp;rsquo;re trying to build your own Debian image for your desktop/laptop, you might have hard time on finding a suitable solution. In general, people tend to run shell scripts or &lt;a href=&#34;https://docs.ansible.com/projects/ansible/latest/playbook_guide/playbooks_intro.html&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Ansible playbooks&lt;/a&gt; after first boot, which is simple and straightforward. But these scripts are rarely performed and handy, which are broken easily as packages/configs out-of-date. Though the &lt;a href=&#34;https://penguins-eggs.net/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Penguin&amp;rsquo;s Egg&lt;/a&gt; is a good approaches to package your system, result image is easily become non-reproducible as changes to packages/configs are missing. Some people might consider &lt;a href=&#34;https://fai-project.org/FAIme/&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;FAI&lt;/a&gt;, but it doesn&amp;rsquo;t provide customizations more than install packages. &lt;a href=&#34;https://developer.hashicorp.com/packer&#34;  class=&#34;external-link&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Packer&lt;/a&gt; seems makes result more reliable and reproducible, but is too heavy as it requires VMs to build images.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
