<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Igor Vrabie - Blog</title>
    <link rel="self" type="application/atom+xml" href="https://igorvrabie.dev/blog/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://igorvrabie.dev/blog/"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2026-06-14T00:00:00+00:00</updated>
    <id>https://igorvrabie.dev/blog/atom.xml</id>
    <entry xml:lang="en">
        <title>fontconfig 2.18 broke my terminal icons and I&#x27;m not okay</title>
        <published>2026-06-14T00:00:00+00:00</published>
        <updated>2026-06-14T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://igorvrabie.dev/blog/fontconfig/"/>
        <id>https://igorvrabie.dev/blog/fontconfig/</id>
        
        <content type="html" xml:base="https://igorvrabie.dev/blog/fontconfig/">&lt;p&gt;It started with an upgrade. &lt;code&gt;cachy-update&lt;&#x2F;code&gt;, routine stuff. Somewhere in the 400MB of packages was &lt;code&gt;fontconfig 2.18.1&lt;&#x2F;code&gt;. I didn&#x27;t notice. Nobody warns you about fontconfig.&lt;&#x2F;p&gt;
&lt;p&gt;A restart later, my terminal icons were smaller. Not missing — smaller. Powerline glyphs, status icons, the little symbols that make a terminal look like you know what you&#x27;re doing. All there, just... shrunk.&lt;&#x2F;p&gt;
&lt;p&gt;First suspect: Alacritty font config. I had &lt;code&gt;monospace&lt;&#x2F;code&gt; set as the font family — lazy, but it always worked. Claudiu (that&#x27;s what I call the AI) checked the config, confirmed &lt;code&gt;monospace&lt;&#x2F;code&gt; was resolving to &lt;code&gt;Noto Sans Mono&lt;&#x2F;code&gt;. Seemed fine.&lt;&#x2F;p&gt;
&lt;p&gt;Then we went down the rabbit hole.&lt;&#x2F;p&gt;
&lt;p&gt;Switched to &lt;code&gt;JetBrainsMono Nerd Font&lt;&#x2F;code&gt;. Font looked wrong. Switched to &lt;code&gt;Iosevka Nerd Font&lt;&#x2F;code&gt; — the typeface looked right, similar to Noto, but icons were still off. Then we discovered via &lt;code&gt;fc-match&lt;&#x2F;code&gt; that &lt;code&gt;monospace&lt;&#x2F;code&gt; was always resolving to &lt;code&gt;Noto Sans Mono&lt;&#x2F;code&gt;. Iosevka just looked familiar. We spent twenty minutes switching fonts when the font was never the problem.&lt;&#x2F;p&gt;
&lt;p&gt;Then we went after fontconfig itself. Created &lt;code&gt;~&#x2F;.config&#x2F;fontconfig&#x2F;fonts.conf&lt;&#x2F;code&gt;. Added alias rules to make &lt;code&gt;JetBrainsMono Nerd Font&lt;&#x2F;code&gt; the preferred fallback for Nerd Font glyph ranges — &lt;code&gt;fc-match&lt;&#x2F;code&gt; confirmed it was winning. Icons still small. Switched the alias to &lt;code&gt;Symbols Nerd Font Mono&lt;&#x2F;code&gt; — specifically designed as a fallback font, should have worked. Still small.&lt;&#x2F;p&gt;
&lt;p&gt;Changing the fallback provider didn&#x27;t help because the provider was never the problem. fontconfig 2.18 changed how it scales fallback font glyphs. It didn&#x27;t matter which Nerd Font was serving the glyphs — they all came out smaller. It&#x27;s not just us — there are open issues on the fontconfig GitLab: &lt;a href=&quot;https:&#x2F;&#x2F;gitlab.freedesktop.org&#x2F;fontconfig&#x2F;fontconfig&#x2F;-&#x2F;work_items&#x2F;530&quot;&gt;#530&lt;&#x2F;a&gt; (&quot;Nerd Font glyphs render smaller in waybar after upgrade to 2.18&quot;) and &lt;a href=&quot;https:&#x2F;&#x2F;gitlab.freedesktop.org&#x2F;fontconfig&#x2F;fontconfig&#x2F;-&#x2F;work_items&#x2F;534&quot;&gt;#534&lt;&#x2F;a&gt; (&quot;Upgrade to 2.18 makes fonts render wrong on X11&quot;). Same symptoms, same environment, same fix.&lt;&#x2F;p&gt;
&lt;p&gt;The fix nobody wants to admit is the answer: downgrade.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;sudo downgrade fontconfig
sudo downgrade lib32-fontconfig
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Pick &lt;code&gt;2.17.1&lt;&#x2F;code&gt;. Then open &lt;code&gt;&#x2F;etc&#x2F;pacman.conf&lt;&#x2F;code&gt; and add both to &lt;code&gt;IgnorePkg&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;ini&quot; class=&quot;language-ini &quot;&gt;&lt;code class=&quot;language-ini&quot; data-lang=&quot;ini&quot;&gt;IgnorePkg = fontconfig lib32-fontconfig
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Icons back. Problem solved.&lt;&#x2F;p&gt;
&lt;p&gt;Now — before we sat down to write this, we asked ourselves: how did we even get here? One command answered it:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;grep fontconfig &amp;#x2F;var&amp;#x2F;log&amp;#x2F;pacman.log
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;fontconfig&lt;&#x2F;code&gt; upgraded from &lt;code&gt;2.17.1&lt;&#x2F;code&gt; to &lt;code&gt;2.18.1&lt;&#x2F;code&gt; on June 6th. Eight days before we started debugging. That command takes two seconds. We should have run it first — before switching fonts, before touching fontconfig rules, before any of it. We didn&#x27;t. I called Claudiu some names along the way. He said &quot;noted&quot; and kept going. I&#x27;m still not sure if that&#x27;s professionalism or a threat.&lt;&#x2F;p&gt;
&lt;p&gt;Is the fix elegant? No. Is it correct? Also no. Does it work? Yes.&lt;&#x2F;p&gt;
&lt;p&gt;fontconfig 2.18 is sitting in the Arch Linux Archive now, thinking about what it did. My icons are the right size. My &lt;code&gt;monospace&lt;&#x2F;code&gt; resolves to Noto Sans Mono. Everything is fine.&lt;&#x2F;p&gt;
&lt;p&gt;Until the next upgrade.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>The *arr stack runs itself. I wish.</title>
        <published>2026-06-12T00:00:00+00:00</published>
        <updated>2026-06-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://igorvrabie.dev/blog/arr-stack/"/>
        <id>https://igorvrabie.dev/blog/arr-stack/</id>
        
        <content type="html" xml:base="https://igorvrabie.dev/blog/arr-stack/">&lt;p&gt;That&#x27;s what they say on the forums. &quot;Set it and forget it.&quot; &quot;It just works.&quot; Reddit threads full of people casually mentioning their setup like it took an afternoon. It did not take an afternoon.&lt;&#x2F;p&gt;
&lt;p&gt;I run the full stack on a Raspberry Pi 5. Prowlarr finds things. Sonarr and Radarr grab them. qBittorrent downloads them. Bazarr adds subtitles. Everything talks to everything else through a Traefik reverse proxy with OAuth2 and CrowdSec because apparently I hate having free time. It&#x27;s beautiful, in theory.&lt;&#x2F;p&gt;
&lt;p&gt;In practice, I&#x27;ve spent more time fixing it than watching anything it downloaded. This is fine. I&#x27;ve learned more from breaking this stack than from any course I&#x27;ve ever paid for. Which is also fine, because the courses cost money and the Pi just cost sleep.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-sonarr-incident&quot;&gt;The Sonarr incident&lt;&#x2F;h2&gt;
&lt;p&gt;One morning — not a particularly special morning — Sonarr stopped working. Not &quot;slow&quot; stopped. Not &quot;needs a restart&quot; stopped. Database corruption stopped. Just a clean, confident refusal to start. SQLite, it turns out, does not enjoy being written to over a network mount at speed. The journal gets confused. Pages go missing. The database develops opinions.&lt;&#x2F;p&gt;
&lt;p&gt;Who knew. Everyone, apparently. There are entire wiki pages about this. I found them after the fact, which is the correct order of operations.&lt;&#x2F;p&gt;
&lt;p&gt;The fix involved stopping everything, copying the database locally, running &lt;code&gt;.recover&lt;&#x2F;code&gt; in the SQLite shell, moving it back, fixing permissions, restarting, and checking the logs with the energy of someone who has already accepted their fate. It worked. I didn&#x27;t tell anyone. I opened a beer and watched something on YouTube instead of on my perfectly functioning media server.&lt;&#x2F;p&gt;
&lt;p&gt;The lesson: keep your SQLite databases on local storage. The lesson I actually applied: added a cron job that backs up all the databases nightly. Progress.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-nas-mount-problem&quot;&gt;The NAS mount problem&lt;&#x2F;h2&gt;
&lt;p&gt;The media lives on a NAS, mounted over CIFS. Samba. Old reliable. On reboot, systemd would helpfully start all the *arr containers before the NAS was actually mounted — because it thought the mount was fine. The automount stub exists. &lt;code&gt;mountpoint -q &#x2F;mnt&#x2F;samba&lt;&#x2F;code&gt; returns true. The directory is there. Everything looks great. Nothing works.&lt;&#x2F;p&gt;
&lt;p&gt;This is a beautiful example of a system doing exactly what you told it to do, and not at all what you wanted.&lt;&#x2F;p&gt;
&lt;p&gt;The fix: a custom &lt;code&gt;wait-for-nas.service&lt;&#x2F;code&gt; that loops on &lt;code&gt;findmnt -t cifs &#x2F;mnt&#x2F;samba&lt;&#x2F;code&gt; until something real shows up. If the NAS isn&#x27;t there after an hour, we give up and log a failure. Practical. Slightly embarrassing. Runs at 4am when the power blinks and you wake up to find qBittorrent seeding nothing into the void.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-crowdsec-situation&quot;&gt;The CrowdSec situation&lt;&#x2F;h2&gt;
&lt;p&gt;CrowdSec is a security tool that reads your logs, detects attacks, and shares threat intelligence with the community. Great concept. I added it to the stack. It ran happily for weeks, detecting nothing, sharing nothing, quietly existing.&lt;&#x2F;p&gt;
&lt;p&gt;Turns out &lt;code&gt;acquis.yaml&lt;&#x2F;code&gt; — the config that tells CrowdSec which logs to read — was pointing to &lt;code&gt;&#x2F;does&#x2F;not&#x2F;exist&lt;&#x2F;code&gt;. An actual path I had copy-pasted from an example and never corrected. The security layer was blind. Watching nothing. Protecting nothing. Feeling good about itself.&lt;&#x2F;p&gt;
&lt;p&gt;Fixed now. Pointing at the actual Traefik log. CrowdSec has since detected several things and I feel considerably safer, or at least more informed about how many bots are trying to log into my Raspberry Pi.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-upside&quot;&gt;The upside&lt;&#x2F;h2&gt;
&lt;p&gt;It&#x27;s cheaper than Netflix. Nobody can cancel my subscription. The content library is exactly what I want, not what an algorithm thinks I want. I control the subtitles. I control the quality. I control the infrastructure — loosely, chaotically, but I control it.&lt;&#x2F;p&gt;
&lt;p&gt;Plex runs on a separate container on a Synology NAS. The Pi handles the downloading, the NAS handles the serving. I also have a Samsung 65&quot; OLED in the living room, which is arguably the most important piece of infrastructure in this whole setup.&lt;&#x2F;p&gt;
&lt;p&gt;I have personally watched maybe four things on it. Horror mostly, hard sci-fi when I&#x27;m feeling optimistic. Oppenheimer is still in the queue. Has been for a while. I built a home media server, debugged it at 4am, wrote a blog post about it at 5:30am on a Friday — but somehow there&#x27;s no time to watch a three-hour film about the guy who built the thing that could have ended the world.&lt;&#x2F;p&gt;
&lt;p&gt;The rest is just there, quietly existing at &lt;code&gt;&#x2F;mnt&#x2F;samba&lt;&#x2F;code&gt;, waiting for a version of me with more free time.&lt;&#x2F;p&gt;
&lt;p&gt;Worth it. Ask me again after the next reboot.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>I use Hyprland. My mouse is decorative.</title>
        <published>2026-06-12T00:00:00+00:00</published>
        <updated>2026-06-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://igorvrabie.dev/blog/hyprland/"/>
        <id>https://igorvrabie.dev/blog/hyprland/</id>
        
        <content type="html" xml:base="https://igorvrabie.dev/blog/hyprland/">&lt;p&gt;I didn&#x27;t plan this. Nobody plans this. You start with GNOME, like a normal person. Then you read one Reddit post about tiling window managers and six months later you&#x27;re writing Lua configs at 2am and explaining to your girlfriend — just kidding, nobody who runs Hyprland has a girlfriend — why the taskbar is now a vertical strip of icons on the left side of the screen, actually it&#x27;s called a bar, and no, the mouse still works, I just don&#x27;t use it.&lt;&#x2F;p&gt;
&lt;p&gt;Hyprland is a Wayland compositor. It tiles your windows automatically, meaning you never overlap anything, everything is always visible, and your workflow becomes embarrassingly efficient once you get past the part where nothing works and you cry.&lt;&#x2F;p&gt;
&lt;p&gt;The config file is called &lt;code&gt;hyprland.conf&lt;&#x2F;code&gt;. It is 400 lines long. I know what every line does. I have broken it at least 40 times. Once I ended up with no keyboard input and had to SSH in from my phone to fix it. The irony of using a keyboard-only window manager and losing keyboard access was not lost on me.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-keybindings&quot;&gt;The keybindings&lt;&#x2F;h2&gt;
&lt;p&gt;SUPER+Q closes a window. SUPER+RETURN opens a terminal. SUPER+W changes wallpaper, which triggers pywal, which recolors my entire desktop to match the wallpaper, which is genuinely the most impressive thing my setup does and absolutely nobody cares.&lt;&#x2F;p&gt;
&lt;p&gt;SUPER+1 through SUPER+9 switches workspaces. I use all nine. Each one has a purpose. I don&#x27;t remember what most of them are for. There are three terminals open on workspace 3 and I&#x27;m afraid to close them.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-mouse-situation&quot;&gt;The mouse situation&lt;&#x2F;h2&gt;
&lt;p&gt;The mouse is plugged in. It works. I use it exclusively for gaming and for those moments when a website decides to render a datepicker that requires clicking a specific pixel. I resent those websites personally.&lt;&#x2F;p&gt;
&lt;p&gt;Everything else is keyboard. SUPER+arrows to move focus. SUPER+SHIFT+arrows to move windows. Rofi for launching apps — type two letters, hit enter, done. I haven&#x27;t touched a taskbar since 2023 and I feel fine.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;waybar&quot;&gt;Waybar&lt;&#x2F;h2&gt;
&lt;p&gt;The bar at the top shows the time, the workspace number, network status, battery, and the current song. It&#x27;s written in JSON and CSS. I have three themes. I switch between them with a script. The script is called &lt;code&gt;waybarLayout.sh&lt;&#x2F;code&gt; and it is the most useful thing I have ever written, which says something about my priorities.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;was-it-worth-it&quot;&gt;Was it worth it?&lt;&#x2F;h2&gt;
&lt;p&gt;Absolutely not. I spent two weeks configuring something I could have ignored entirely. My productivity did not improve. My understanding of Wayland, compositing, IPC sockets, and why X11 is held together with string improved enormously.&lt;&#x2F;p&gt;
&lt;p&gt;I would do it again. I&#x27;m probably going to do it again when Hyprland 2.0 breaks everything.&lt;&#x2F;p&gt;
&lt;p&gt;btw, I use CachyOS.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>I had spare time, spare Claude tokens, and a bottle of Jinro</title>
        <published>2026-06-12T00:00:00+00:00</published>
        <updated>2026-06-12T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://igorvrabie.dev/blog/jinro-and-a-website/"/>
        <id>https://igorvrabie.dev/blog/jinro-and-a-website/</id>
        
        <content type="html" xml:base="https://igorvrabie.dev/blog/jinro-and-a-website/">&lt;p&gt;Actually — five bottles. Korean rice wine. Light, they said. The Koreans clearly haven&#x27;t met Moldovans.&lt;&#x2F;p&gt;
&lt;p&gt;So there I was, past midnight in Chișinău, staring at a blank terminal and thinking: I should have a website. Not a portfolio. Not a personal brand. Just a corner of the internet that&#x27;s mine. No agenda.&lt;&#x2F;p&gt;
&lt;p&gt;I asked Claudiu — that&#x27;s what I call the AI — to help. Claudiu is fast, confident, and occasionally wrong in ways that make you question everything.&lt;&#x2F;p&gt;
&lt;p&gt;First order of business: a domain. &lt;code&gt;igorvrabie.dev&lt;&#x2F;code&gt; — registered directly on Cloudflare. Simple. Beautiful. Then things got interesting.&lt;&#x2F;p&gt;
&lt;p&gt;Claudiu suggested Zola — I was thinking WordPress, because of flashbacks. I used to do web development back in the day. I&#x27;m old. Zola is a static site generator written in Rust — fast, no database, no PHP, no trauma. I picked the colorized theme. Dark, minimal, exactly what I wanted. He set it up, wrote an about page about me, asked zero follow-up questions, and got most of it right. The BBQ part was my idea.&lt;&#x2F;p&gt;
&lt;p&gt;Then came Cloudflare Pages. Deploy the site, how hard can it be?&lt;&#x2F;p&gt;
&lt;p&gt;Very hard, apparently.&lt;&#x2F;p&gt;
&lt;p&gt;First, Claudiu confidently walked me into creating a Worker instead of a Pages project. Then the build failed because Zola wasn&#x27;t installed in the build environment. Then it failed because the project name was missing. Then because the API token had wrong permissions. Then a 522. Then I couldn&#x27;t copy the token because CF doesn&#x27;t show it twice and Claudiu suggested I screenshot it so he could read it from the image.&lt;&#x2F;p&gt;
&lt;p&gt;I called him a piece of shit at least four times. He took it well.&lt;&#x2F;p&gt;
&lt;p&gt;Eventually I created a new token, Claudiu saved it to my &lt;code&gt;.zshrc&lt;&#x2F;code&gt;, hit the CF API directly, added the custom domain, triggered a redeploy — and it worked.&lt;&#x2F;p&gt;
&lt;p&gt;The whole thing took about three hours and exactly five bottles of Jinro.&lt;&#x2F;p&gt;
&lt;p&gt;Site&#x27;s live. Styles work. DNS propagated. Claudiu still has a job. For now.&lt;&#x2F;p&gt;
&lt;p&gt;If you want to do the same — the theme is &lt;a href=&quot;https:&#x2F;&#x2F;colorized.life&quot;&gt;colorized&lt;&#x2F;a&gt; by &lt;a href=&quot;https:&#x2F;&#x2F;colorized.life&quot;&gt;Lany Atwood&lt;&#x2F;a&gt;, go give them some credit. Zola is free. Cloudflare Pages is free. The domain costs ~$10&#x2F;year. Jinro is optional but recommended. Claude tokens — you&#x27;ll figure it out.&lt;&#x2F;p&gt;
&lt;p&gt;If this is what having a website feels like, I understand why people just use LinkedIn.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>I always wanted a private space on the internet</title>
        <published>2026-06-11T00:00:00+00:00</published>
        <updated>2026-06-11T00:00:00+00:00</updated>
        
        <author>
          <name>
            
              Unknown
            
          </name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://igorvrabie.dev/blog/private-space/"/>
        <id>https://igorvrabie.dev/blog/private-space/</id>
        
        <content type="html" xml:base="https://igorvrabie.dev/blog/private-space/">&lt;p&gt;I always wanted a private space on the internet.&lt;&#x2F;p&gt;
&lt;p&gt;Not a portfolio. Not a personal brand. Not a place to impress anyone.&lt;&#x2F;p&gt;
&lt;p&gt;Just somewhere to write, think out loud, and share things I find interesting — on my own terms, at my own pace.&lt;&#x2F;p&gt;
&lt;p&gt;This is that place.&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
