<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Blåhaj Pen Reader</title>
    <link>https://pen.blahaj.zone</link>
    <description>Read the latest posts from Blåhaj Pen.</description>
    <pubDate>Tue, 28 Apr 2026 07:42:21 +0000</pubDate>
    <item>
      <title>DVDs and Music Bees</title>
      <link>https://pen.blahaj.zone/the-gnu-linux-diary/dvds-and-music-bees</link>
      <description>&lt;![CDATA[An excerpt from my my diary, from the 17th of February, 2024.&#xA;&#xA;Today, I got a request from a family member to create a DVD, from several short videos of him playing on the guitar. I figure this shouldn’t be a big deal, but I was incorrect. Apparently, authoring DVDs is a giant pain in the ass—at least with the media I was given. All of these clips were in some strange AVI formatted video, which was massive, and didn’t even want to play properly in some media programs. I imagine the best course of action would be to just re-encode this mess, maybe into MP4 with ffmpeg, and just be done with it, especially as I wasn’t confident it’d fit on the DVD without modification. Okay, so let’s hop into the terminal and get ffmpeg installed. What’s even nicer about this, is it’s very easy to just open a terminal right in the directory, and modify my existing scripts.!--more-- I probably should just make my batch files bash ones instead sometime, but whatever, it’s running! Nice and simple—or so I thought—as when I checked the converted output, the audio just became a wall of white noise.&#xA;&#xA;Okay great, something must be wrong with the GNU/Linux installation...I guess? I try I few different encoding and re-encoding settings, they all fail the same way, I decide this isn’t my project anyway, and just boot back into Windows. I run ffmpeg again, it still fails miserably; honestly, that’s a huge relief. The files are just awful, thank god it’s not an OS related issue. This is where I find out some video programs fail to play it, and that Audacity imports the track as white noise too. Lovely, so how the heck will I be able to cut and convert this stuff into a proper format then? Strangely enough, it was Microsoft’s proprietary video clip tool that actually managed to do it, after messing with it a bit to make it think the entire video was a clip to convert. I have no idea why that worked, but oh well, at least I can use some free DVD authoring software. This isn’t really related to GNU/Linux any further, but let’s just say this was an absolute nightmare, and it took five burns to get a single usable configuration. It was like a balancing act of preserving re-encoding failures and successes, along with DVD commands which I guess weren’t added by default.&#xA;&#xA;Okay, shows over, back to Pop!_OS, that’s the point of this, after all! Well actually, wait, since I’m here, now would be a great time to export my MusicBee ratings into a simple playlist format like .m3u. After that, I could look for a proper music app for my new system! I got my playlists ready, so it’s time to jump back in. Now I’m looking for something free and open source, something which has automatic playlists for ratings, the ability to rate music, and ideally has some customization features. Looking around online, it seems like the most popular one that fits this bill is Clementine. Oddly, they seemingly haven’t had an official release for several years, despite very recent active work in the GitHub repository. Not really sure what’s up with that, but I could grab some prerelease installation if necessary.&#xA;&#xA;I do see a flatpak from not too long ago on the Pop shop, and figure that should be more than enough to evaluate if it will work for me. It can recognize my library no problem, though tag embedded ratings seem to differ from MusicBee, which is fine, as I could simply import the playlists...right? Well no, they just don’t function properly at all. This is a problem, .m3u files are pretty basic, it’s literally just directories isn’t it? I took some random album, saved an .m3u playlist in Clementine, and well—it’s a mess. There’s so much extra baggage saved here, which would make conversion unreasonable between what I have from MusicBee, and this. It’s a pretty big deal, and unfortunately a deal breaker, but I did see a fork of Clementine with far more recent releases from this month! It’s called Strawberry, and little did I know, it would actually bridge the gap I needed, saving the day. &#xA;&#xA;Strawberry is similar as you might imagine; it feels a little nicer, and has some extra features, but otherwise I figured this might be pointless. My thought was maybe the .m3u playlists would differ, because the info preserved in Clementine was pretty needless. To my actual shock, the Hail Mary I wagered was dead on. The playlists here and from MusicBee are identical, aside from a single line at the top for external directories, #EXTM3U, which is trivial to append. Now we’re getting to business, so I alter the directories to match my new drives, import the playlist, and...there are broken entries. Thankfully, I pick up almost immediately what happened, but unfortunately there’s no automated way to resolve the conflict. The problem is that MusicBee isn’t case sensitive, while Strawberry is, so any song I updated capitalization for in the folder structure, never updated the data within MusicBee. This seems like a Strawberry oversight more than anything, but whatever, I can deal with this type of problem.&#xA;&#xA;I pop open the native text editor, and get to work replacing capitalization for a number of songs, in literally every rating playlist. After deleting and importing a couple times, all of the errors are resolved, I can select all, and then set every single song’s rating to the correct value! Fantastic stuff, and then I can make auto playlists if I need to export the data in the future. It took a number of hours, but thousands of entries are all imported, meaning my local favorites and rated tracks are all ready to go now! This is extremely important, because it means I can now ditch my Windows music collection, and progress it entirely with free software utilizing GNU/Linux. I do have some issues to resolve, mainly revolving around other satellite tools and tagging, but at the very least, the biggest hurdle has been crossed! Also—added bonus—my FiiO hardware works better than it did before. It has special modes for higher res audio playbacks (e.g. 24bit / 96khz), which never worked in Windows, but are plug and play here. I found this out by listening to a recent album I got called Jet Flight, and seeing the green color I should when such audio is passed through the DAC.]]&gt;</description>
      <content:encoded><![CDATA[<p><em>An excerpt from my my diary, from the 17th of February, 2024.</em></p>

<p>Today, I got a request from a family member to create a DVD, from several short videos of him playing on the guitar. I figure this shouldn’t be a big deal, but I was incorrect. Apparently, authoring DVDs is a giant pain in the ass—at least with the media I was given. All of these clips were in some strange AVI formatted video, which was massive, and didn’t even want to play properly in some media programs. I imagine the best course of action would be to just re-encode this mess, maybe into MP4 with ffmpeg, and just be done with it, especially as I wasn’t confident it’d fit on the DVD without modification. Okay, so let’s hop into the terminal and get ffmpeg installed. What’s even nicer about this, is it’s very easy to just open a terminal right in the directory, and modify my existing scripts. I probably should just make my batch files <em>bash</em> ones instead sometime, but whatever, it’s running! Nice and simple—or so I thought—as when I checked the converted output, the audio just became a wall of white noise.</p>

<p>Okay great, something must be wrong with the GNU/Linux installation...I guess? I try I few different encoding and re-encoding settings, they all fail the same way, I decide this isn’t my project anyway, and just boot back into Windows. I run ffmpeg again, it still fails miserably; honestly, that’s a huge relief. The files are just awful, thank god it’s not an OS related issue. This is where I find out some video programs fail to play it, and that Audacity imports the track as white noise too. Lovely, so how the heck will I be able to cut and convert this stuff into a proper format then? Strangely enough, it was Microsoft’s proprietary video clip tool that actually managed to do it, after messing with it a bit to make it think the entire video was a clip to convert. I have no idea why that worked, but oh well, at least I can use some free DVD authoring software. This isn’t really related to GNU/Linux any further, but let’s just say this was an absolute nightmare, and it took five burns to get a single usable configuration. It was like a balancing act of preserving re-encoding failures and successes, along with DVD commands which I guess weren’t added by default.</p>

<p>Okay, shows over, back to Pop!_OS, that’s the point of this, after all! Well actually, wait, since I’m here, now would be a <em>great</em> time to export my MusicBee ratings into a simple playlist format like .m3u. After that, I could look for a proper music app for my new system! I got my playlists ready, so it’s time to jump back in. Now I’m looking for something free and open source, something which has automatic playlists for ratings, the ability to rate music, and ideally has some customization features. Looking around online, it seems like the most popular one that fits this bill is <a href="https://www.clementine-player.org/" rel="nofollow">Clementine</a>. Oddly, they seemingly haven’t had an official release for several years, despite very recent active work in the GitHub repository. Not really sure what’s up with that, but I could grab some prerelease installation if necessary.</p>

<p>I do see a flatpak from not too long ago on the Pop shop, and figure that should be more than enough to evaluate if it will work for me. It can recognize my library no problem, though tag embedded ratings seem to differ from MusicBee, which is fine, as I could simply import the playlists...right? Well no, they just don’t function properly at all. This is a problem, .m3u files are pretty basic, it’s literally just directories isn’t it? I took some random album, saved an .m3u playlist in Clementine, and well—it’s a mess. There’s so much extra baggage saved here, which would make conversion unreasonable between what I have from MusicBee, and this. It’s a pretty big deal, and unfortunately a deal breaker, but I did see a fork of Clementine with far more recent releases from this month! It’s called <a href="https://www.strawberrymusicplayer.org/" rel="nofollow">Strawberry</a>, and little did I know, it would actually bridge the gap I needed, saving the day.</p>

<p>Strawberry is similar as you might imagine; it feels a little nicer, and has some extra features, but otherwise I figured this might be pointless. My thought was maybe the .m3u playlists would differ, because the info preserved in Clementine was pretty needless. To my actual shock, the Hail Mary I wagered was dead on. The playlists here and from MusicBee are identical, aside from a single line at the top for external directories, <code>#EXTM3U</code>, which is trivial to append. Now we’re getting to business, so I alter the directories to match my new drives, import the playlist, and...there are broken entries. Thankfully, I pick up almost immediately what happened, but unfortunately there’s no automated way to resolve the conflict. The problem is that MusicBee <em>isn’t</em> case sensitive, while Strawberry <strong>is</strong>, so any song I updated capitalization for in the folder structure, never updated the data within MusicBee. This seems like a Strawberry oversight more than anything, but whatever, I can deal with this type of problem.</p>

<p>I pop open the native text editor, and get to work replacing capitalization for a number of songs, in literally every rating playlist. After deleting and importing a couple times, all of the errors are resolved, I can select all, and then set every single song’s rating to the correct value! Fantastic stuff, and then I can make auto playlists if I need to export the data in the future. It took a number of hours, but thousands of entries are all imported, meaning my local favorites and rated tracks are all ready to go now! This is extremely important, because it means I can now ditch my Windows music collection, and progress it entirely with free software utilizing GNU/Linux. I do have some issues to resolve, mainly revolving around other satellite tools and tagging, but at the very least, the biggest hurdle has been crossed! Also—added bonus—my FiiO hardware works better than it did before. It has special modes for higher res audio playbacks (e.g. 24bit / 96khz), which never worked in Windows, but are plug and play here. I found this out by listening to a recent album I got called Jet Flight, and seeing the green color I should when such audio is passed through the DAC.</p>
]]></content:encoded>
      <author>The GNU/Linux Diary</author>
      <guid>https://pen.blahaj.zone/read/a/20hmkffd0t</guid>
      <pubDate>Sat, 25 Apr 2026 18:22:27 +0000</pubDate>
    </item>
    <item>
      <title>On Content Warnings and Spoilers</title>
      <link>https://pen.blahaj.zone/reilyhh/on-content-warnings-and-spoilers</link>
      <description>&lt;![CDATA[I take content warnings and spoilers very seriously. I think they protect the user themselves, and not just the users around them. I&#39;ve had many times where I vented about something traumatic, or said some bad news, only for my eyes to slightly go up and read that all over again. So by having spoilers, I was able to protect myself from re-reading sensitive content. &#xA;&#xA;!--more--&#xA;The key thing about content/trigger warnings I think is &#34;Readiness&#34;. Yes, sure, it is to protect some folks from being triggered by the content due to having bad past experiences with it. But I also think that it&#39;s there to give users a choice, do you want to read something that might upset you or not? Like you might not have any bad past experiences with X, Y, and Z, but what if you just woke up, and the first thing you were greeted with was a bad case of X, Y, or Z? Or if you expected to see a wholesome chat room with kitty cuddles and meows only to see unspoilered sensitive content. That surprise, that shock, I don&#39;t like that.&#xA;&#xA;Here&#39;s a post on how to spoiler things on Matrix chatting clients, and the last two sections cover the internet in general.]]&gt;</description>
      <content:encoded><![CDATA[<p>I take content warnings and spoilers very seriously. I think they protect the user themselves, and not just the users around them. I&#39;ve had many times where I vented about something traumatic, or said some bad news, only for my eyes to slightly go up and read that all over again. So by having spoilers, I was able to protect myself from re-reading sensitive content.</p>



<p>The key thing about content/trigger warnings I think is “Readiness”. Yes, sure, it is to protect some folks from being triggered by the content due to having bad past experiences with it. But I also think that it&#39;s there to give users a choice, do you want to read something that might upset you or not? Like you might not have any bad past experiences with X, Y, and Z, but what if you just woke up, and the first thing you were greeted with was a bad case of X, Y, or Z? Or if you expected to see a wholesome chat room with kitty cuddles and meows only to see unspoilered sensitive content. That surprise, that shock, I don&#39;t like that.</p>

<p><a href="https://pen.blahaj.zone/reilyhh/matrix-tips-and-tricks" rel="nofollow">Here&#39;s a post</a> on how to spoiler things on Matrix chatting clients, and the last two sections cover the internet in general.</p>
]]></content:encoded>
      <author>reilyh</author>
      <guid>https://pen.blahaj.zone/read/a/ywmbw3nwjs</guid>
      <pubDate>Sat, 25 Apr 2026 16:45:37 +0000</pubDate>
    </item>
    <item>
      <title>Matrix Tips and Tricks!</title>
      <link>https://pen.blahaj.zone/reilyhh/matrix-tips-and-tricks</link>
      <description>&lt;![CDATA[Spoilers!&#xA;&#xA;For spoilering you could use the following format:&#xA;&#xA;!--more--&#xA;&#xA;Double Pipes&#xA;&#xA;If your client support this syntax ||spoilered text|| you should write like this:&#xA; CW/TW: Description Of The Warning ||Actual Content||&#xA;&#xA;The /spoiler Command&#xA;&#xA;If your client does not support that syntax, check if your client provides a /spoiler command: &#xA;in that case you should send a message that details the CW/TW then reply to it using the /spoiler command&#xA;&#xA;Long Text and Other Forms of Media&#xA;&#xA;An excellent way would be to use https://trggr.link/ you could write CW/TWs for any kind of media: images, videos, large text, etc.&#xA;&#xA;Although keep in mind that trggr isn&#39;t a file hosting service, it only supports text. To send sensitive media, upload to an external file host, like https://catbox.moe or other file hosting services.&#xA;&#xA;Stickers&#xA;&#xA;I am known as the sticker girl, I&#39;ve been mostly collecting images on the internet, cropping them, sometimes editing them slightly to fit my needs. I even drew some stickers. So here&#39;s what I learned:&#xA;&#xA;[This section is under construction]]]&gt;</description>
      <content:encoded><![CDATA[<h2 id="spoilers">Spoilers!</h2>

<p>For spoilering you could use the following format:</p>



<p><strong>Double Pipes</strong></p>

<p>If your client support this syntax ||spoilered text|| you should write like this:
 CW/TW: Description Of The Warning ||Actual Content||</p>

<p><strong>The <code>/spoiler</code> Command</strong></p>

<p>If your client does not support that syntax, check if your client provides a /spoiler command:
in that case you should send a message that details the CW/TW then reply to it using the /spoiler command</p>

<p><strong>Long Text and Other Forms of Media</strong></p>

<p>An excellent way would be to use <a href="https://trggr.link/" rel="nofollow">https://trggr.link/</a> you could write CW/TWs for any kind of media: images, videos, large text, etc.</p>

<p>Although keep in mind that trggr isn&#39;t a file hosting service, it only supports text. To send sensitive media, upload to an external file host, like <a href="https://catbox.moe" rel="nofollow">https://catbox.moe</a> or other file hosting services.</p>

<h2 id="stickers">Stickers</h2>

<p>I am known as the sticker girl, I&#39;ve been mostly collecting images on the internet, cropping them, sometimes editing them slightly to fit my needs. I even drew some stickers. So here&#39;s what I learned:</p>

<p>[This section is under construction]</p>
]]></content:encoded>
      <author>reilyh</author>
      <guid>https://pen.blahaj.zone/read/a/qtk0xmye5t</guid>
      <pubDate>Sat, 25 Apr 2026 15:11:35 +0000</pubDate>
    </item>
    <item>
      <title>FINALLY!</title>
      <link>https://pen.blahaj.zone/reilyhh/finally</link>
      <description>&lt;![CDATA[NO MORE DEALING WITH CSS DEMONS! AAAAAAAH I CAN WRITE STUFF NOW!]]&gt;</description>
      <content:encoded><![CDATA[<p>NO MORE DEALING WITH CSS DEMONS! AAAAAAAH I CAN WRITE STUFF NOW!</p>
]]></content:encoded>
      <author>reilyh</author>
      <guid>https://pen.blahaj.zone/read/a/a2myksf19j</guid>
      <pubDate>Sat, 25 Apr 2026 14:55:00 +0000</pubDate>
    </item>
    <item>
      <title>First Hardware Casualty</title>
      <link>https://pen.blahaj.zone/the-gnu-linux-diary/first-hardware-casualty</link>
      <description>&lt;![CDATA[An excerpt from my my diary, from the 16th of February, 2024.&#xA;&#xA;You know, it’s been a few days since I’ve installed this system, and I only just now realized something: hibernation actually works on my device perfectly. I always, and I mean always, have issues with hibernation on my desktop Windows systems. Clearly it works for a lot of people— because I don’t hear about this being an issue—but for me, across multiple versions and computers, hibernation breaks. I’ve always opted to either leave my stuff running, or turn it off entirely, because I will basically have to restart the device anyway if I try to use hibernation mode. On Pop!_OS though? Oh wow, it works flawlessly, boots back up in a few seconds, and everything is just excellent; I am honestly stunned. !--more--&#xA;&#xA;I figured I’d have to disable it, but it’s worked properly a few times already, and it’s just everything I could ever hope for. Also, can I talk to you about my lord and savior: integrated dark mode? Holy hell, everything is dark, and it is amazing. I was waiting for literally over a decade just for partial integration of dark mode into native Windows apps. I cannot stress enough how much I love this. Everything integrated is dark, everything I download is dark—I am in heaven.&#xA;&#xA;Alright, so I downloaded OBS a couple days ago, right? There’s another bit of hardware I need to set up: my AVerMedia capture card. Let’s plug that bad boy in and set up a scene. Oh wait, nothing is detected; I suppose I need some drivers or something. Let’s do some digging! Several minutes of digging later and...well, shit. This hardware company gives no fucks about GNU/Linux systems, and also has some proprietary nonsense going on I guess. Only lead I have is a GitHub project which is years out of production, that modifies a specific no longer hosted driver, that is related, but not actually for the 4k card I purchased. Okay, let’s check the repository—oh, no releases. I guess I could follow the compilation instructions, it says it should just work. Shocker to no one, the years out of date un-compiled code failed to build, seemingly citing several unaccounted for variables (not missing dependencies).&#xA;&#xA;It did say if it fails to try the Fedora branch. Alright, I’m on Ubuntu, but what the heck, ./build.sh go ahead and make my day. Oh, never mind, it already broke. I’m not in a position to resolve whatever issues these are, and a slightly less out of date fork mentioning kernel changes, makes me even more wary. I’m in way over my head here. For completion sake, I download the fork and see if it compiles, though alas, it also fails. But hey, I tried dang it, that accounts for something right? Man, this card was like $150, I guess I’ll just have to look for something that actually respects my freedom in the future. Considering it was plug and play with Windows though, I’m honestly surprised this was my first hardware casualty. More unconventional stuff I literally had to download drivers for works out of the box, but this was a bridge too far. Honestly, much better this than my audio gear; I’m happy, all things considered. ]]&gt;</description>
      <content:encoded><![CDATA[<p><em>An excerpt from my my diary, from the 16th of February, 2024.</em></p>

<p>You know, it’s been a few days since I’ve installed this system, and I only just now realized something: hibernation actually works on my device perfectly. I always, and I mean <em>always</em>, have issues with hibernation on my desktop Windows systems. Clearly it works for a lot of people— because I don’t hear about this being an issue—but for me, across multiple versions and computers, hibernation breaks. I’ve always opted to either leave my stuff running, or turn it off entirely, because I will basically have to restart the device anyway if I try to use hibernation mode. On Pop!_OS though? Oh wow, it works flawlessly, boots back up in a few seconds, and everything is just excellent; I am honestly stunned. </p>

<p>I figured I’d have to disable it, but it’s worked properly a few times already, and it’s just everything I could ever hope for. Also, can I talk to you about my lord and savior: integrated dark mode? Holy hell, everything is dark, and it is <em>amazing</em>. I was waiting for literally over a decade just for partial integration of dark mode into native Windows apps. I cannot stress enough how much I love this. Everything integrated is dark, everything I download is dark—I am in heaven.</p>

<p>Alright, so I downloaded OBS a couple days ago, right? There’s another bit of hardware I need to set up: my AVerMedia capture card. Let’s plug that bad boy in and set up a scene. Oh wait, nothing is detected; I suppose I need some drivers or something. Let’s do some digging! Several minutes of digging later and...well, shit. This hardware company gives no fucks about GNU/Linux systems, and also has some proprietary nonsense going on I guess. Only lead I have is a GitHub project which is years out of production, that modifies a specific <em>no longer hosted</em> driver, that is related, but not actually for the 4k card I purchased. Okay, let’s check the repository—oh, no releases. I guess I could follow the compilation instructions, it says it should just work. Shocker to no one, the years out of date un-compiled code failed to build, seemingly citing several unaccounted for variables (not missing dependencies).</p>

<p>It did say if it fails to try the Fedora branch. Alright, I’m on Ubuntu, but what the heck, <code>./build.sh</code> go ahead and make my day. Oh, never mind, it already broke. I’m not in a position to resolve whatever issues these are, and a slightly less out of date fork mentioning kernel changes, makes me even more wary. I’m in way over my head here. For completion sake, I download the fork and see if it compiles, though alas, it also fails. But hey, I <em>tried</em> dang it, that accounts for something right? Man, this card was like $150, I guess I’ll just have to look for something that actually respects my freedom in the future. Considering it was plug and play with Windows though, I’m honestly surprised this was my first hardware casualty. More unconventional stuff I literally had to download drivers for works out of the box, but this was a bridge too far. Honestly, much better this than my audio gear; I’m happy, all things considered.</p>
]]></content:encoded>
      <author>The GNU/Linux Diary</author>
      <guid>https://pen.blahaj.zone/read/a/q6wweaokyt</guid>
      <pubDate>Tue, 21 Apr 2026 23:26:40 +0000</pubDate>
    </item>
    <item>
      <title>A Discord Survey Response</title>
      <link>https://pen.blahaj.zone/foxfire/a-discord-survey-response</link>
      <description>&lt;![CDATA[In early January of 2026, the communications tech giant Discord posted a survey regarding various types of AI integration on their platform. The questions posed included several invasive monitoring ideas, such as analysis of audio and video chats, seemingly in real time, with no distinction for private servers—or direct messages.&#xA;&#xA;Seemingly due to overwhelming backlash, the survey was taken down a mere several hours after it initially launched. In the free form section at the end, I wrote a couple paragraphs airing my concerns. While I&#39;ve entirely moved to Matrix now, I still felt it worthwhile to respond, and also to mirror this text elsewhere.!--more--&#xA;&#xA;As a large, centralized corporation housing an enormous amount of personal data of users—including that of minors—I am incredibly concerned with any AI integration into Discord whatsoever. The thought of any person having the ability to offload data, particularly from private servers or private messages, into some other company&#39;s data centers for processing, is a privacy nightmare. With some of the features considered within this very survey, it sounds like even voice and video chats may become rife with direct processing to such companies. I cannot imagine whoever you partnered with would sit idly by while such massive natural human data streams come in, without harvesting them for who knows what.&#xA;&#xA;Even if you hypothetically added an opt-out, and I were to trust that this genuinely prevented the transfer of data, the vast majority of people will leave settings as default—having the effects of this without necessarily even realizing the ramifications. It may also violate the consent of others, dependent on if someone who chooses to have AI highlights or summaries, have information included from participants who have chosen to opt-out. This would defeat the entire purpose of turning it off, beyond a veneer of a few hidden buttons; this would obviously be very problematic.&#xA;&#xA;Additionally, I fundamentally am tied to Discord for communication between people, and only people. AI generated stickers, emoji, messages, or any other sort of non-human output, are directly at odds with the only thing I care about doing on the platform: talking to actual people. Groups of friends or communities create their own in-jokes and memes, and it is this human interaction which spurs the creation of things which we collectively enjoy. When I use a custom emoji or sticker, there is a story as to why it&#39;s there, and who created it. If there are people who wish to use generative models in spite of that, I would encourage them to use a local only, open weight, generative model they have full control over on their own computer.&#xA;&#xA;I certainly don&#39;t want to further platform and normalize the generative models of the multi-trillion dollar AI market bubble, which is almost certainly what would be the case for any AI integration that is done by Discord. This bubble is causing lots of problems currently, and I expect those problems to get worse before they get better. Look no further than the gaming demographic Discord used to be aimed at; SSD and RAM prices are at astronomical levels right now, purely because of backroom AI data center deals. I am appalled by the prospect of further rewarding this behavior as it continues to put strain on the general populace, with deep pocket investors begging us to take part in their self-serving, prospective profiteering.]]&gt;</description>
      <content:encoded><![CDATA[<p><em>In early January of 2026, the communications tech giant Discord posted a survey regarding various types of AI integration on their platform. The questions posed included several invasive monitoring ideas, such as analysis of audio and video chats, seemingly in real time, with no distinction for private servers—or direct messages.</em></p>

<p><em>Seemingly due to overwhelming backlash, the survey was taken down a mere several hours after it initially launched. In the free form section at the end, I wrote a couple paragraphs airing my concerns. While I&#39;ve entirely moved to Matrix now, I still felt it worthwhile to respond, and also to mirror this text elsewhere.</em></p>

<p>As a large, centralized corporation housing an enormous amount of personal data of users—including that of minors—I am incredibly concerned with any AI integration into Discord whatsoever. The thought of any person having the ability to offload data, particularly from private servers or private messages, into some other company&#39;s data centers for processing, is a privacy nightmare. With some of the features considered within this very survey, it sounds like even voice and video chats may become rife with direct processing to such companies. I cannot imagine whoever you partnered with would sit idly by while such massive natural human data streams come in, without harvesting them for who knows what.</p>

<p>Even if you hypothetically added an opt-out, and I were to trust that this genuinely prevented the transfer of data, the vast majority of people will leave settings as default—having the effects of this without necessarily even realizing the ramifications. It may also violate the consent of others, dependent on if someone who chooses to have AI highlights or summaries, have information included from participants who have chosen to opt-out. This would defeat the entire purpose of turning it off, beyond a veneer of a few hidden buttons; this would obviously be very problematic.</p>

<p>Additionally, I fundamentally am tied to Discord for communication between people, and only people. AI generated stickers, emoji, messages, or any other sort of non-human output, are directly at odds with the only thing I care about doing on the platform: talking to actual people. Groups of friends or communities create their own in-jokes and memes, and it is this human interaction which spurs the creation of things which we collectively enjoy. When I use a custom emoji or sticker, there is a story as to why it&#39;s there, and who created it. If there are people who wish to use generative models in spite of that, I would encourage them to use a local only, open weight, generative model they have full control over on their own computer.</p>

<p>I certainly don&#39;t want to further platform and normalize the generative models of the multi-trillion dollar AI market bubble, which is almost certainly what would be the case for any AI integration that is done by Discord. This bubble is causing lots of problems currently, and I expect those problems to get worse before they get better. Look no further than the gaming demographic Discord used to be aimed at; SSD and RAM prices are at astronomical levels right now, purely because of backroom AI data center deals. I am appalled by the prospect of further rewarding this behavior as it continues to put strain on the general populace, with deep pocket investors begging us to take part in their self-serving, prospective profiteering.</p>
]]></content:encoded>
      <author>Foxfire</author>
      <guid>https://pen.blahaj.zone/read/a/kjxrmgkn1n</guid>
      <pubDate>Tue, 21 Apr 2026 22:48:42 +0000</pubDate>
    </item>
    <item>
      <title>A First World (Desktop) Background Problem</title>
      <link>https://pen.blahaj.zone/the-gnu-linux-diary/a-first-world-desktop-background-problem</link>
      <description>&lt;![CDATA[An excerpt from my my diary, from the 15th of February, 2024.&#xA;&#xA;After taking a bit of a break to just watch some videos, and get more comfy with the environment, I figured it was time to get back into it. First off, I still have absolutely no idea if my webcam will work. With no built in way to check, I figure some software off the Pop Shop would work just fine. Grab some program literally just called Camera, which seemed simple enough, but couldn’t recognize the device; no idea why. Maybe it’s expecting a different type of equipment, but regardless, there are other options. Perhaps I needed some controller application first—like the proprietary Logitech software on Windows—but obviously something free instead. !--more--Quickly found Cameractris, which was exactly what I was looking for, and it absolutely recognized my camera! The other Camera app still couldn’t, so I also found Webcamoid...but the package release was from 2016. Alright, well clearly there’s something else up here.&#xA;&#xA;I head over to Github, and find the project does prebuilt releases behind a tiny paywall. Could try my hand at compiling, but I still have no idea what I’m doing. Frankly, neither that, nor sending off my credit card information for something I’ve never used, feels particularly great right now. So, I decide I may as well try out the ancient package, see if it works at all, and if so, if it’s at all useful first. I download it, and it does indeed recognize the webcam, and take pictures! Though, in that moment, I had a pretty obvious reminder that Open Broadcaster Software exists, and I use it rather regularly. Download that, works like a charm instantly, and it has many other uses for local recordings too! Also, now seems like a good time to get dedicated audio editing software, and as I know Audacity had that buyout a while back, I figure now’s a great time to check out Tenacity! No sense in sticking around on my final 2.X version, when I can grab that right this second after all! Boot it up, recording works great, and that’s another problem solved!&#xA;&#xA;Perhaps now it’s time for something more personal: let’s finally change my desktop background! Yeah, I’m gonna throw my Foxfire art on one monitor, and some fan art a super kind person recently made of him on the other monitor! Oh wait, what? I can’t have a unique background for each monitor, seriously‽ Of all the things to have a snag on, this is certainly not one of them I was expecting. It’s really not that big of a deal, but at the same time it was driving me a bit crazy; like, surely I was doing something wrong—right? Well, actually no; after some digging, I find that by default, you legitimately cannot do this action. I checked the System76 FAQ, and did find some info on theme customization through GNOME Tweaks, but it didn’t seem like it covered unique monitor backgrounds. Thankfully, the years old Reddit comment search result history gods provided me with the sweet nectar of a solution...kind of.&#xA;&#xA;I install GNOME Tweaks, and while it has no multi image support, you can set a home and lock screen background with different fit options. For whatever reason, changing the image did nothing, and altering the fit options of the lock screen, changed the fit options of the desktop. Okay, whatever, it was stated it wasn’t exactly supported in System76’s documentation; I can still work with this! The image that comment had showed a spanned fit, which, okay wow, my Foxfire is a WIDE boy now. Excellent, so all I have to do to have two images on my monitors is: create a single image. Straightforward, except the fan art one is not 1920x1080 like the other background. So, it’s time to open Krita, and scale it down so it’s exactly that, for parity with the other image in a 3840x1080 frame. Quick math has that at 72%, so I transform it, save the thing, set it as a background, hit span and—it works! Ah, first world problems, but I solved it! &#xA;&#xA;Two images of foxfire, an anthro fox, as a background for two monitors.&#xA;&#xA;  &#34;Dual monitor backgrounds in Pop!_OS&#34;&#xA;&#xA;Also, as an aside, I love the built in email app Geary. God, it’s so simple and sleek, literally exactly what I need, and nothing more. I was rocking Thunderbird for Windows recently since, well, Mozilla and free software, but I might honestly just stick with Geary on GNU/Linux. Not only that but, wow, the integration if you allow it. You can straight up integrate anything from Google you want, most notable is direct connection to Google drive from within the file explorer. I know I really shouldn’t be excited about proprietary connections, and I didn’t enable anything outside of drive mounting, but it’s just really cool how responsive it is. I still unfortunately use Google drive a lot, and this is legitimately a better way to access it than through Google itself. No extra non-free nonsense needed, aside from the servers themselves, which I’ll accept for now. Only issue seems to be that clicking links in emails takes a long time to open in Firefox. No clue why—it’s not Firefox itself—I can literally copy and paste the link, and load the page instantly; an odd little caveat.]]&gt;</description>
      <content:encoded><![CDATA[<p><em>An excerpt from my my diary, from the 15th of February, 2024.</em></p>

<p>After taking a bit of a break to just watch some videos, and get more comfy with the environment, I figured it was time to get back into it. First off, I still have absolutely no idea if my webcam will work. With no built in way to check, I figure some software off the Pop Shop would work just fine. Grab some program literally just called Camera, which seemed simple enough, but couldn’t recognize the device; no idea why. Maybe it’s expecting a different type of equipment, but regardless, there are other options. Perhaps I needed some controller application first—like the proprietary Logitech software on Windows—but obviously something free instead. Quickly found <a href="https://github.com/soyersoyer/cameractrls" rel="nofollow">Cameractris</a>, which was exactly what I was looking for, and it absolutely recognized my camera! The other Camera app still couldn’t, so I also found Webcamoid...but the package release was from <strong>2016</strong>. Alright, well <em>clearly</em> there’s something else up here.</p>

<p>I head over to Github, and find the project does prebuilt releases behind a tiny paywall. Could try my hand at compiling, but I still have no idea what I’m doing. Frankly, neither that, nor sending off my credit card information for something I’ve never used, feels particularly great right now. So, I decide I may as well try out the ancient package, see if it works at all, and if so, if it’s at all useful first. I download it, and it does indeed recognize the webcam, and take pictures! Though, in that moment, I had a pretty obvious reminder that <a href="https://obsproject.com/" rel="nofollow">Open Broadcaster Software</a> exists, and I use it rather regularly. Download that, works like a charm instantly, and it has many other uses for local recordings too! Also, now seems like a good time to get dedicated audio editing software, and as I know Audacity had that buyout a while back, I figure now’s a great time to check out <a href="https://tenacityaudio.org/" rel="nofollow">Tenacity</a>! No sense in sticking around on my final 2.X version, when I can grab that right this second after all! Boot it up, recording works great, and that’s another problem solved!</p>

<p>Perhaps now it’s time for something more personal: let’s finally change my desktop background! Yeah, I’m gonna throw my Foxfire art on one monitor, and some fan art a super kind person recently made of him on the other monitor! Oh wait, what? I can’t have a unique background for each monitor, <em>seriously</em>‽ Of all the things to have a snag on, this is certainly not one of them I was expecting. It’s really not that big of a deal, but at the same time it was driving me a bit crazy; like, surely <em>I</em> was doing something wrong—<em>right</em>? Well, actually no; after some digging, I find that by default, you legitimately cannot do this action. I checked the System76 FAQ, and did find some info on theme customization through GNOME Tweaks, but it didn’t seem like it covered unique monitor backgrounds. Thankfully, the years old Reddit comment search result history gods provided me with the sweet nectar of a solution...kind of.</p>

<p>I install GNOME Tweaks, and while it has no multi image support, you can set a home and lock screen background with different fit options. For whatever reason, changing the image did nothing, and altering the fit options of the lock screen, changed the fit options of the desktop. Okay, whatever, it was stated it wasn’t exactly <em>supported</em> in System76’s documentation; I can still work with this! The image that comment had showed a spanned fit, which, okay wow, my Foxfire is a <strong>WIDE</strong> boy now. Excellent, so all I have to do to have two images on my monitors is: create a single image. Straightforward, except the fan art one is not 1920x1080 like the other background. So, it’s time to open Krita, and scale it down so it’s <em>exactly</em> that, for parity with the other image in a 3840x1080 frame. Quick math has that at 72%, so I transform it, save the thing, set it as a background, hit span and—it works! Ah, first world problems, but I solved it!</p>

<p><img src="https://b.cgas.io/HU8NEWwMXvt7.jpg" alt="Two images of foxfire, an anthro fox, as a background for two monitors."></p>

<blockquote><p>“Dual monitor backgrounds in Pop!_OS”</p></blockquote>

<p>Also, as an aside, I love the built in email app Geary. God, it’s so simple and sleek, literally exactly what I need, and nothing more. I was rocking Thunderbird for Windows recently since, well, Mozilla and free software, but I might honestly just stick with Geary on GNU/Linux. Not only that but, wow, the integration if you allow it. You can straight up integrate anything from Google you want, most notable is direct connection to Google drive from within the file explorer. I know I really shouldn’t be excited about proprietary connections, and I didn’t enable anything outside of drive mounting, but it’s just really cool how responsive it is. I still unfortunately use Google drive a lot, and this is legitimately a better way to access it than through Google itself. No extra non-free nonsense needed, aside from the servers themselves, which I’ll accept for now. Only issue seems to be that clicking links in emails takes a long time to open in Firefox. No clue why—it’s not Firefox itself—I can literally copy and paste the link, and load the page instantly; an odd little caveat.</p>
]]></content:encoded>
      <author>The GNU/Linux Diary</author>
      <guid>https://pen.blahaj.zone/read/a/1t11el8llx</guid>
      <pubDate>Sun, 19 Apr 2026 18:05:59 +0000</pubDate>
    </item>
    <item>
      <title>Hello world!</title>
      <link>https://pen.blahaj.zone/reilyhh/hello-world</link>
      <description>&lt;![CDATA[I did an oopsie again and forgot my password for &#34;reilyh&#34; for pen.blahaj.zone. Oh well :P&#xA;!--more--]]&gt;</description>
      <content:encoded><![CDATA[<p>I did an oopsie again and forgot my password for “reilyh” for pen.blahaj.zone. Oh well :P
</p>
]]></content:encoded>
      <author>reilyh</author>
      <guid>https://pen.blahaj.zone/read/a/78lfgmtngt</guid>
      <pubDate>Sat, 18 Apr 2026 16:36:42 +0000</pubDate>
    </item>
    <item>
      <title>To The Yellowjacket I Met Today</title>
      <link>https://pen.blahaj.zone/foxfire/to-the-yellowjacket-i-met-today</link>
      <description>&lt;![CDATA[I barely noticed you by the window sill at my workplace. I was surprised a creature as large as you could be so inconspicuous; I&#39;m so used to your vigor and curiosity. You weren&#39;t moving, and I had thought you already passed away. Instead, you were so weak, I accidentally flipped you over from a puff of air, to check that very thing. The inside of a building is an insidious place for insects—a prison beyond understanding. You were succumbing to its uncaring walls, and my guilt weighed more than my fear.!--more--&#xA;&#xA;I found a small piece of wood, and placed it just above you. As if you understood the instruction, you quickly moved your legs upward, and stuck to it. I took you outside to some flowers; you seemed curious, but didn&#39;t wish to leave the wood after a few minutes of facing them. Perhaps you just needed more time to rest, more time away from the sun-baked windows which were cooking you alive. I gave you shade nearby, and found some small rain puddles to coat my hands with, hopefully to give you some hydration. Just some small droplets and flicks of the fingers, hoping you might ingest some beads of water, as you gained more strength. &#xA;&#xA;I wasn&#39;t sure if you&#39;d make it, but I saw you breathing—I saw you holding on. Earnestly, I just hoped that whatever happened was better than the uncaring hand you were dealt until this point. When I checked on you after my lunch, you were nowhere to be seen. I&#39;m holding on to hope that you regained your strength, and eventually flew away. We all live and die, but the pointless cruelty of dehydrating on a window sill is too much. You just wanted to live and forage, and instead we trapped you in a labyrinth of suffering. Who would&#39;ve even cared if your corpse were there instead, had I missed you today? Why do we often feel so little for the countless other inhabitants of our world? &#xA;&#xA;I hope you got your second chance.]]&gt;</description>
      <content:encoded><![CDATA[<p>I barely noticed you by the window sill at my workplace. I was surprised a creature as large as you could be so inconspicuous; I&#39;m so used to your vigor and curiosity. You weren&#39;t moving, and I had thought you already passed away. Instead, you were so weak, I accidentally flipped you over from a puff of air, to check that very thing. The inside of a building is an insidious place for insects—a prison beyond understanding. You were succumbing to its uncaring walls, and my guilt weighed more than my fear.</p>

<p>I found a small piece of wood, and placed it just above you. As if you understood the instruction, you quickly moved your legs upward, and stuck to it. I took you outside to some flowers; you seemed curious, but didn&#39;t wish to leave the wood after a few minutes of facing them. Perhaps you just needed more time to rest, more time away from the sun-baked windows which were cooking you alive. I gave you shade nearby, and found some small rain puddles to coat my hands with, hopefully to give you some hydration. Just some small droplets and flicks of the fingers, hoping you might ingest some beads of water, as you gained more strength.</p>

<p>I wasn&#39;t sure if you&#39;d make it, but I saw you breathing—I saw you holding on. Earnestly, I just hoped that whatever happened was better than the uncaring hand you were dealt until this point. When I checked on you after my lunch, you were nowhere to be seen. I&#39;m holding on to hope that you regained your strength, and eventually flew away. We all live and die, but the pointless cruelty of dehydrating on a window sill is too much. You just wanted to live and forage, and instead we trapped you in a labyrinth of suffering. Who would&#39;ve even cared if your corpse were there instead, had I missed you today? Why do we often feel so little for the countless other inhabitants of our world?</p>

<p>I hope you got your second chance.</p>
]]></content:encoded>
      <author>Foxfire</author>
      <guid>https://pen.blahaj.zone/read/a/icwi08khzc</guid>
      <pubDate>Sat, 18 Apr 2026 00:49:34 +0000</pubDate>
    </item>
    <item>
      <title>The Plunge</title>
      <link>https://pen.blahaj.zone/the-gnu-linux-diary/the-plunge</link>
      <description>&lt;![CDATA[An excerpt from my my diary, from the 13th of February, 2024.&#xA;&#xA;My initial thoughts about switching, was that it would be a bit over my head until I changed my hardware. I have some atypical peripherals, but my biggest concern was my NVIDIA graphics card. I had heard that this was a company notorious for being unfriendly with GNU/Linux development, and that people have problems using their components. I had my heart set on some hypothetical time in the future, where I’d get a new PC with AMD components, and hop to GNU/Linux Mint Debian Edition. I started looking into a distribution I heard about called Pop!OS however, because it seemed like it might be possible for me to install it easily on my current system, without modification. !--more--It’s based on Ubuntu—which I had heard rather mixed things about—but it seemed to deviate a bit in certain places, like utilizing flatpak containers, and having its own shop. I heard Snap was bad I guess; also, proprietary? To reiterate, I have no idea what I’m doing. Anyway, the most important thing, is that this OS has a compiled bundle of proprietary NVIDIA drivers directly in the ISO. I’m not exactly thrilled by the prospect of running to non-free software to get my free software running, but surely some binary blobs are way farther up the freedom ladder, than sitting around twiddling my thumbs on Windows 10 forever. So I decide this is my calling; let’s get it going—today.&#xA;&#xA;Alright, instructions seem simple enough; just download the OS, some free software to create a live disk (balenaEtcher), and reboot to freedom. The first steps did work out that way; popped out my favorite 16gb stick, let Etcher do its thing, and then went to reset the PC. After some silliness with my bios settings, I get to the install screen. Oh man is it slow. I chalk it up to the fact it’s on a USB stick, and just vibe for a bit chugging through the install wizard. Finally, the time comes when it asks me if I want to do a normal or custom install, and of course I want to do a custom one, because I’m a very cool guy. The reality is, I wasn’t in the mood to format one of my storage drives to install a small operating system. I figured I’d simply make a 250GB partition on a drive that Windows wasn’t on, and call it a day. I’ve heard trying to install on the same drive as an existing operating system can cause problems, and Windows could just mess with the boot table which, well—that doesn’t sound like a fun time.&#xA;&#xA;I’m told to make a /home/ directory, which defaults to formatting as...EXT4? Can’t say I’ve ever formatted as anything beyond FAT32 or NTFS before, and I don’t really know if it will be cross compatible, but I suppose that doesn’t matter much. The goal is really just to have a partition large enough to install applications, and handle temporary files. My personal data will be on all my other drives anyway, to prevent issues. Okay, so great! I make the partition, I ask it to use it, I get the option to start the install, and then...it fails, after some files try to copy over. I try again, it fails, and again, then reboot the thing—no dice. Okay, well maybe if I look at the very scary typical clean install button (please don’t format my personal files, god there surely has to be multiple confirmations right) something will come up. It does give me a lead though, all my SSDs are over 2TBs, and apparently that’s a problem. If I try to work around it by mounting them, I get a no object for D-Bus interface error.&#xA;&#xA;Alright, well I at least have some text I can copy, and I figure something out! Apparently, I need to utilize a mode called UEFI in my bios settings, in order to install on drives over 2TB, instead of legacy boot options. I hop into the settings, see a way to force UEFI only and think, “yeah that’s a great idea, let’s close compatibility so it has to go through UEFI,” except now my USB stick isn’t detected at all anymore. Well, crap. Okay, maybe I should grab my more recent 64GB one, which I know is USB 3, and surely should go into forced UEFI no problem right? Boot back into Windows, reopen Etcher, nuke the drive, and get it going, and it is going! Things load up, screen flashed once—oh, back to the command line. Pop!OS instance 5 initiated, instance 20, 45, 70, 100...okay, I think the routine is busted here.&#xA;&#xA;Ctrl+Alt+Del—oh, it fails far before there now despite being a live cd, then again, so I power down the whole thing. Guess something failed with the Etching software? Regardless, I put my settings to on instead of forced, and re-enable some unrelated legacy things. Maybe if the other drives worked properly, I could salvage something. Maybe install somewhere else and move it later? I dunno. But now it decides there are two boot options for the drive, where one is actually UEFI! Okay great, it’s running! Oh god, the command line is huge now, but I’m in, and I can mount the drives! So anyway, back to custom, and I realize something absurd must’ve happened. In tinkering with the on and off boxes for trying to install the OS, I think I must‘ve managed to idiot savant my way through some fail safe. Apparently, I need to at minimum have two partitions for my install, a, /home/, and a /boot/. I make the second partition, I define them as the partitions to use, and timidly hit the install button expecting failure. Installation...successful! Well holy hell, let’s get this show on the road then!&#xA;&#xA;I restart, I have my boot configured incorrectly so it immediately threw me into Windows, I restart again and use the boot menu—ah two Pop!_OS choices! No, I don’t mean one from the stick, they’re both on the drive, but one says UEFI, so I wager it’s just different compatibility for booting? Had enough trouble with not using UEFI, we’re clicking the UEFI version. Wow, that boots fast, very sleek! Now comes my next biggest fear: not having any ability to use my audio equipment. It’s been suspiciously quiet through the entire install, but in actuality, there really were just no sounds playing at all. Sure enough I head to the sounds and, well actually, how the heck do I even change audio devices? Apparently, it’s in a settings context menu; fair enough, and all my devices are surprisingly just already there.&#xA;&#xA;Main speakers, check; external DAC/amp, check. My XLR USB mic input I had to install drivers on Windows for? Yup, working out of the box. Huge weight off my chest there, as that stuff was not cheap, and I use it very often. Next hurdle: I need my VPN. Technically, I could scrap my current VPN provider if I had to, but they have done very well by me with their old lifetime plan, so I’d vastly prefer to keep them. I figured considering it’s a no logs VPN service, that a GNU/Linux package would be far more likely than an average proprietary service. I was right, though it was on their website, as opposed to in Pop’s special store. Easy install, quick to connect and—actually, wow, that connection was way faster than I’m used to. It usually takes like several seconds, yet this gets it done in less than one. Double checked the IPs on web searches because it was so fast, but it’s totally working as expected. Again, another good sized hurdle taken care of rather easily.&#xA;&#xA;Okay, so now I need to resolve the issue of password management. I know there are a number of free software projects based around KeePass, so I’m expecting such a project to exist for GNU/Linux. KeePassXC comes to my rescue on the shop, it works excellently, and now I can begin logging into all of my web services and extensions I need on Firefox. Services are going well, everything seems fine, even watched some videos for good measure! I checked out my files, everything seems good, though I’m not the biggest fan of having to mount my internal SSDs every time I boot my PC, and them being icons on my task bar. Speaking of that taskbar, it’s kind of a big boy, so I guess I should fiddle with the settings. Turns out it’s very configurable; I was going to do a full tiny bar, but then I realized I can hide the taskbar on hover, and went back to the rounded floating one at a small size. Finally, screen real estate is mine again! I can also have it on both monitors, yes please, and it’s very snappy. Now there’s just one more thing to do before I call it a day, I gotta open the terminal and do that thing. All the cool kids show off their operating system with that built in program neofetch! Oh wait, it’s not built in? I just thought because well...okay, I guess it’s not like I can’t just sudo apt get neofetch. Oh hey there we go, it worked! Alright, time to take a screenshot!&#xA;&#xA;Terminal window with a neofetch command shown.&#xA;&#xA;  &#34;Baby&#39;s first Neofetch.&#34;]]&gt;</description>
      <content:encoded><![CDATA[<p><em>An excerpt from my my diary, from the 13th of February, 2024.</em></p>

<p>My initial thoughts about switching, was that it would be a bit over my head until I changed my hardware. I have some atypical peripherals, but my biggest concern was my NVIDIA graphics card. I had heard that this was a company notorious for being unfriendly with GNU/Linux development, and that people have problems using their components. I had my heart set on some hypothetical time in the future, where I’d get a new PC with AMD components, and hop to GNU/Linux Mint Debian Edition. I started looking into a distribution I heard about called <a href="https://system76.com/pop/download/" rel="nofollow">Pop!_OS</a> however, because it seemed like it might be possible for me to install it easily on my current system, without modification. It’s based on Ubuntu—which I had heard rather mixed things about—but it seemed to deviate a bit in certain places, like utilizing flatpak containers, and having its own shop. I heard Snap was bad I guess; also, proprietary? To reiterate, I have <em>no</em> idea what I’m doing. Anyway, the most important thing, is that this OS has a compiled bundle of proprietary NVIDIA drivers directly in the ISO. I’m not exactly <em>thrilled</em> by the prospect of running to non-free software to get my free software running, but surely some binary blobs are way farther up the freedom ladder, than sitting around twiddling my thumbs on Windows 10 forever. So I decide this is my calling; let’s get it going—today.</p>

<p>Alright, instructions seem simple enough; just download the OS, some free software to create a live disk (<a href="https://etcher.balena.io/" rel="nofollow">balenaEtcher</a>), and reboot to freedom. The first steps did work out that way; popped out my favorite 16gb stick, let Etcher do its thing, and then went to reset the PC. After some silliness with my bios settings, I get to the install screen. Oh man is it slow. I chalk it up to the fact it’s on a USB stick, and just vibe for a bit chugging through the install wizard. Finally, the time comes when it asks me if I want to do a normal or custom install, and of course I want to do a custom one, because I’m a very cool guy. The reality is, I wasn’t in the mood to format one of my storage drives to install a small operating system. I figured I’d simply make a 250GB partition on a drive that Windows wasn’t on, and call it a day. I’ve heard trying to install on the same drive as an existing operating system can cause problems, and Windows could just mess with the boot table which, well—that doesn’t sound like a fun time.</p>

<p>I’m told to make a <code>/home/</code> directory, which defaults to formatting as...EXT4? Can’t say I’ve ever formatted as anything beyond FAT32 or NTFS before, and I don’t really know if it will be cross compatible, but I suppose that doesn’t matter much. The goal is really just to have a partition large enough to install applications, and handle temporary files. My personal data will be on all my other drives anyway, to prevent issues. Okay, so great! I make the partition, I ask it to use it, I get the option to start the install, and then...it fails, after some files try to copy over. I try again, it fails, and again, then reboot the thing—no dice. Okay, well <em>maybe</em> if I look at the very scary typical clean install button (please don’t format my personal files, god there surely has to be multiple confirmations right) something will come up. It does give me a lead though, all my SSDs are over 2TBs, and apparently that’s a problem. If I try to work around it by mounting them, I get a <code>no object for D-Bus interface</code> error.</p>

<p>Alright, well I at least have some text I can copy, and I figure something out! Apparently, I need to utilize a mode called UEFI in my bios settings, in order to install on drives over 2TB, instead of legacy boot options. I hop into the settings, see a way to force UEFI only and think, “yeah that’s a great idea, let’s close compatibility so it has to go through UEFI,” except now my USB stick isn’t detected at all anymore. Well, crap. Okay, maybe I should grab my more recent 64GB one, which I know is USB 3, and surely should go into forced UEFI no problem right? Boot back into Windows, reopen Etcher, nuke the drive, and get it going, and it is going! Things load up, screen flashed once—oh, back to the command line. Pop!_OS instance 5 initiated, instance 20, 45, 70, 100...okay, I think the routine is busted here.</p>

<p><code>Ctrl+Alt+Del</code>—oh, it fails far before there now despite being a live cd, then again, so I power down the whole thing. Guess something failed with the Etching software? Regardless, I put my settings to on instead of forced, and re-enable some unrelated legacy things. Maybe if the other drives worked properly, I could salvage something. Maybe install somewhere else and move it later? I dunno. But now it decides there are <em>two</em> boot options for the drive, where one is actually UEFI! Okay great, it’s running! Oh god, the command line is huge now, but I’m in, and I can mount the drives! So anyway, back to custom, and I realize something absurd must’ve happened. In tinkering with the on and off boxes for trying to install the OS, I think I must‘ve managed to idiot savant my way through some fail safe. Apparently, I need to at <em>minimum</em> have two partitions for my install, a, <code>/home/</code>, and a <code>/boot/</code>. I make the second partition, I define them as the partitions to use, and timidly hit the install button expecting failure. Installation...<strong>successful!</strong> Well holy hell, let’s get this show on the road then!</p>

<p>I restart, I have my boot configured incorrectly so it immediately threw me into Windows, I restart again and use the boot menu—ah two Pop!_OS choices! No, I don’t mean one from the stick, they’re both on the drive, but one says UEFI, so I wager it’s just different compatibility for booting? Had enough trouble with not using UEFI, we’re clicking the UEFI version. Wow, that boots fast, very sleek! Now comes my next biggest fear: not having any ability to use my audio equipment. It’s been suspiciously quiet through the entire install, but in actuality, there really were just no sounds playing at all. Sure enough I head to the sounds and, well actually, how the heck do I even change audio devices? Apparently, it’s in a settings context menu; fair enough, and all my devices are surprisingly just already there.</p>

<p>Main speakers, check; external DAC/amp, check. My XLR USB mic input I had to install drivers on Windows for? Yup, working out of the box. Huge weight off my chest there, as that stuff was not cheap, and I use it very often. Next hurdle: I need my VPN. Technically, I could scrap my current VPN provider if I had to, but they have done very well by me with their old lifetime plan, so I’d vastly prefer to keep them. I figured considering it’s a no logs VPN service, that a GNU/Linux package would be far more likely than an average proprietary service. I was right, though it was on their website, as opposed to in Pop’s special store. Easy install, quick to connect and—actually, wow, that connection was <em>way</em> faster than I’m used to. It usually takes like several seconds, yet this gets it done in less than one. Double checked the IPs on web searches because it was so fast, but it’s totally working as expected. Again, another good sized hurdle taken care of rather easily.</p>

<p>Okay, so now I need to resolve the issue of password management. I know there are a number of free software projects based around KeePass, so I’m expecting such a project to exist for GNU/Linux. <a href="https://keepassxc.org/" rel="nofollow">KeePassXC</a> comes to my rescue on the shop, it works excellently, and now I can begin logging into all of my web services and extensions I need on Firefox. Services are going well, everything seems fine, even watched some videos for good measure! I checked out my files, everything seems good, though I’m not the biggest fan of having to mount my internal SSDs every time I boot my PC, and them being icons on my task bar. Speaking of that taskbar, it’s kind of a big boy, so I guess I should fiddle with the settings. Turns out it’s very configurable; I was going to do a full tiny bar, but then I realized I can hide the taskbar on hover, and went back to the rounded floating one at a small size. Finally, screen real estate is mine again! I can also have it on both monitors, yes please, and it’s very snappy. Now there’s just one more thing to do before I call it a day, I gotta open the terminal and do that <em>thing</em>. All the cool kids show off their operating system with that built in program neofetch! Oh wait, it’s not built in? I just thought because well...okay, I guess it’s not like I can’t just <code>sudo apt get neofetch</code>. Oh hey there we go, it worked! Alright, time to take a screenshot!</p>

<p><img src="https://b.cgas.io/IXZzUfelcQFC.png" alt="Terminal window with a neofetch command shown."></p>

<blockquote><p>“Baby&#39;s first Neofetch.”</p></blockquote>
]]></content:encoded>
      <author>The GNU/Linux Diary</author>
      <guid>https://pen.blahaj.zone/read/a/votosni7km</guid>
      <pubDate>Thu, 16 Apr 2026 00:44:42 +0000</pubDate>
    </item>
    <item>
      <title>A Brave GNU World</title>
      <link>https://pen.blahaj.zone/the-gnu-linux-diary/a-brave-gnu-world</link>
      <description>&lt;![CDATA[Diary of my switch to GNU/Linux&#xA;An excerpt from my my diary, from the 12th of February, 2024.&#xA;&#xA;Preface&#xA;I’ve been sent on a journey since the middle of 2023, that has entirely turned my Internet and software habits on their head. My perception of using large, proprietary providers of any service, went from complacent and unquestionably necessary, to incredibly hesitant, and begging for serviceable alternatives. As I sought out more free and open source applications, replaced the proprietary software I could, and began using and financially supporting federated Activity-pub servers, there was still an elephant in the room: Windows. The very operating system I used every single day—for everything—is entirely proprietary.!--more--&#xA;&#xA;Windows is non-free software, which is what my entire life’s understanding of computing and compatible software is based upon. From when I first navigated through Windows ME at home as a small child, to 2000 and XP in schools for computer classes, Vista and 7 at home in my teens, and 10 for the last several years too. This is all to say that I have absolutely zero experience with any GNU/Linux platform, and trying to make a switch that actually mattered seemed very daunting. I have no idea what I’m doing, and I’m not exactly adept at coding either. I’m just a man with the ability to web search, open to some change, and a desire to push through some friction. With that said, this will act as a diary for various days I work on my transition to a freer operating system. Observations, successes, failures, frustrations—all the sort of fun that comes from the voyage.]]&gt;</description>
      <content:encoded><![CDATA[<p><strong>Diary of my switch to GNU/Linux</strong>
<em>An excerpt from my my diary, from the 12th of February, 2024.</em></p>

<p><strong>Preface</strong>
I’ve been sent on a journey since the middle of 2023, that has entirely turned my Internet and software habits on their head. My perception of using large, proprietary providers of any service, went from complacent and unquestionably necessary, to incredibly hesitant, and begging for serviceable alternatives. As I sought out more free and open source applications, replaced the proprietary software I could, and began using and financially supporting federated Activity-pub servers, there was still an elephant in the room: Windows. The very operating system I used every single day—for everything—is entirely proprietary.</p>

<p>Windows is non-free software, which is what my entire life’s understanding of computing and compatible software is based upon. From when I first navigated through Windows ME at home as a small child, to 2000 and XP in schools for computer classes, Vista and 7 at home in my teens, and 10 for the last several years too. This is all to say that I have absolutely zero experience with any GNU/Linux platform, and trying to make a switch that actually mattered seemed very daunting. I have no idea what I’m doing, and I’m not exactly adept at coding either. I’m just a man with the ability to web search, open to some change, and a desire to push through some friction. With that said, this will act as a diary for various days I work on my transition to a freer operating system. Observations, successes, failures, frustrations—all the sort of fun that comes from the voyage.</p>
]]></content:encoded>
      <author>The GNU/Linux Diary</author>
      <guid>https://pen.blahaj.zone/read/a/xzqy3172t4</guid>
      <pubDate>Mon, 13 Apr 2026 22:59:40 +0000</pubDate>
    </item>
    <item>
      <title>Ushering In Darkness With CSS, And Duct Tape</title>
      <link>https://pen.blahaj.zone/foxfire/ushering-in-darkness-with-css-and-duct-tape</link>
      <description>&lt;![CDATA[As I&#39;ve been using WriteFreely, I&#39;ve found that the dark mode support oddly starts—and stops—on the blog writing page. While there is technically a toggle for dark mode on the instance reader page, you can only make out a few sentences before you&#39;re whisked away to another unforgiving flash-bang. While I&#39;m not exactly sure why this is the case, I do know that I have some power to change it; more power than expected, actually. This brings us to where the magic happens, assuming you know what you&#39;re doing: custom CSS rules. The thing is, I have absolutely no idea what I&#39;m doing, and the things I want to do are seemingly uncharted territory. How; genuinely how‽!--more--&#xA;&#xA;My absurd requests:&#xA;&#xA;A simple dark mode layout.&#xA;Justified post body text.&#xA;&#xA;I imagined that doing something like justifying text would be simpler than an entire theme, so I set off looking for answers. Digging through the writer guide brought up nothing, so I fervently clacked away, until I came across a several year old forum post on the matter. Not knowing what I was doing, I was happy to copy what seemed like a complete answer from Matt, the founder of Write.as. There was a warning about single spaces not functioning, but I figured &#34;I separate paragraphs with multiple line breaks anyway, it&#39;ll be fine!&#34; It was not fine; my entire blog post turned into a single rectangular mass. Additional line breaks did not help stave the amalgam, and I was left a bit conflicted. On the one hand, it&#39;s very evident I can justify text, but on the other, I can&#39;t really justify keeping it in this state.&#xA;&#xA;If that was going to give me trouble, perhaps I can spend more time looking into dark themes. The first place I go to check is the Write.as themes page, to where I am greeted with a surprisingly limited selection. Out of everything, only one theme even seemed to resemble a dark palette at all: Painkiller Bullet. It&#39;s in the ballpark, so I do try it out, but gives off a bit of hacker type vibes, which isn&#39;t really the style I want personally. I did try changing some colors, but it feels like there&#39;s a number of things here I don&#39;t understand. Perhaps I could&#39;ve sat with it longer, but I figured that if I was going to understand anything, I&#39;m going to have to throw the baby out with the bathwater, and make changes—one at a time.&#xA;&#xA;Enter: Duct Tape&#xA;Carl Sagan once said, &#34;If you wish to make an apple pie from scratch, you must first invent the universe.&#34; If you want to do that with a dark theme for someone else&#39;s website, I guess you have to stare at inspect element until you can&#39;t keep your eyes open. Between the very basic style info in the writers guide, pulling variables in inspect element, and consulting with W3Schools, I slowly managed to cobble together my custom theme. My vision was heavily inspired by one of the templates from System76&#39;s COSMIC dark mode, which has an umber background, along with yellow links, and an off-white base text. Surprisingly, I was able to get pretty far along, and I feel like I&#39;ve (mostly) gotten to the point where basic stuff is presentable now. I even added some additional rules to match some personal tastes, like having titles be sans-serif, with the body being serif type. Also yes, I&#39;ve fixed my justify problem, and can finally sleep at night knowing my margins are nice and orderly.&#xA;&#xA;That being said, not only have I run into some limitations, but I also have already managed to create quite the mess of code. Things are not ordered in a sensible way, my comments are outdated, and I&#39;m sure I&#39;ll need to add even more rules before I actually begin to clean it up. I intend to use this blog entry to help with figuring that out, since I won&#39;t know something is broken, until I try to actually use it. Once I do manage to clean up everything I feasibly can, my intent is to make variants of this theme for other blogs. Perhaps one inspired by KDE Plasma&#39;s dark breeze theme, or maybe one of the Dracula style dark themes I&#39;ve seen in programs such as Voyager would be a good second version. As for the limitations, there seems to be some oddly hard-coded problems I can&#39;t work around with my custom style sheet. For example, this little bugger is jammed right into the webpage directly, so no matter what I do, it overwrites all style rules:&#xA;&#xA;.post-byline .byline-author {&#xA;display:inline-flex;&#xA;align-items:center;&#xA;gap:0.5rem;&#xA;text-decoration:none;&#xA;color:#666;&#xA;font-size:0.9rem;&#xA;}&#xA;Most of this stuff isn&#39;t too big of a deal, but seriously, I&#39;m forced to have a specific color of gray text for my author name‽ In order to make this not an absolute contrast nightmare, I had to turn my name into a faux button; a button far darker than anything else in the theme too. It doesn&#39;t look awful, but it does absolutely stick out in a way I&#39;m not particularly keen on. I also can&#39;t for the life of me find a way to change my context menu icons from dark to light. Thankfully that&#39;s something only I can see, though I did manage to give them a background, and reduce their opacity to blend it better. Also, I ran into a roadblock you didn&#39;t even notice, despite it still impacting me as of this writing: blog avatars are broken. You might be saying to yourself &#34;but I saw your avatar at the top of this article,&#34; and you&#39;d be fair to say that—but you&#39;re wrong.&#xA;&#xA;Hacking In An Avatar&#xA;Assuming it&#39;s still broken when you read this, try right clicking and opening my avatar in a new tab. You probably noticed it threw a lovely 404 not found error, and tries to find an image called default.png. This is because I am totally unable to upload an avatar, but more than that, the default fallback avatars are broken too. Now, of course I brought this to the attention of the kind hosts of this instance, but in the interim, I was determined to prod at this until I made something happen. I have a feeling that I can hypothetically pull this off, because I can see that images can load through CSS, and there are a few tutorials on it through W3Schools too. Also, I&#39;ll need a reasonably reliable host to service the image as well. I figure since it&#39;s an avatar anyway, that I could just source it from one of several sites I use this exact image for the same purpose. Let&#39;s get a better look at our objective, shall we?&#xA; &#xA;foxfire-pfp-optimised.webp&#xA;&#xA;  &#34;The mission is simple: get me in there.&#34;&#xA;&#xA;I ended up choosing my profile from Etterna Online, a website for a FOSS rhythm game. I went with it because I know the owner, and I know full well this is exactly the place which won&#39;t care whatsoever, that I&#39;m hot-linking a small image to an even smaller blog. When I added it as the background for the the property which controls the avatar, I suddenly see nothing but blue—fantastic! That means it&#39;s loaded the image at full size inside the circle, and now I simply need to reduce it to the correct value. This turned out to be 28px by 28px, and was very simple to append to the image properties. So with that, I managed to hack my way to a faux profile picture, effectively indistinguishable from a normal one. On top of that, I can do this for any blog independently, meaning they can all have different faux avatars for as long as necessary. Realistically, even if it were never resolved, I still won; I feel really good about that.&#xA;&#xA;I suppose I need to test tables too:&#xA;&#xA;| Status | Action |&#xA;|-------|-------|&#xA;| Working | Relax |&#xA;| Broken | Resolve |]]&gt;</description>
      <content:encoded><![CDATA[<p>As I&#39;ve been using WriteFreely, I&#39;ve found that the dark mode support oddly starts—and stops—on the blog writing page. While there is <em>technically</em> a toggle for dark mode on the instance reader page, you can only make out a few sentences before you&#39;re whisked away to another unforgiving flash-bang. While I&#39;m not exactly sure why this is the case, I do know that I have some power to change it; more power than expected, actually. This brings us to where the magic happens, assuming you know what you&#39;re doing: custom CSS rules. The thing is, I have absolutely no idea what I&#39;m doing, and the things I want to do are seemingly uncharted territory. How; genuinely how‽</p>

<p><strong>My absurd requests:</strong></p>
<ul><li>A simple dark mode layout.</li>
<li>Justified post body text.</li></ul>

<p>I imagined that doing something like justifying text would be simpler than an entire theme, so I set off looking for answers. Digging through the <a href="https://writefreely.org/docs/main/writer" rel="nofollow">writer guide</a> brought up nothing, so I fervently clacked away, until I came across a several year old <a href="https://discuss.write.as/t/hyphenate-justify-posts/890" rel="nofollow">forum post</a> on the matter. Not knowing what I was doing, I was happy to copy what seemed like a complete answer from Matt, the founder of Write.as. There was a warning about single spaces not functioning, but I figured “I separate paragraphs with multiple line breaks anyway, it&#39;ll be fine!” It was not fine; my entire blog post turned into a single rectangular mass. Additional line breaks did not help stave the amalgam, and I was left a bit conflicted. On the one hand, it&#39;s very evident I <em>can</em> justify text, but on the other, I can&#39;t really justify keeping it in this state.</p>

<p>If that was going to give me trouble, perhaps I can spend more time looking into dark themes. The first place I go to check is the Write.as <a href="https://write.as/themes/" rel="nofollow">themes page</a>, to where I am greeted with a surprisingly limited selection. Out of everything, only one theme even seemed to resemble a dark palette at all: <a href="https://write.as/themes/painkiller-bullet" rel="nofollow">Painkiller Bullet</a>. It&#39;s in the ballpark, so I do try it out, but gives off a bit of hacker type vibes, which isn&#39;t really the style I want personally. I did try changing some colors, but it feels like there&#39;s a number of things here I don&#39;t understand. Perhaps I could&#39;ve sat with it longer, but I figured that if I <em>was</em> going to understand anything, I&#39;m going to have to throw the baby out with the bathwater, and make changes—one at a time.</p>

<h2 id="enter-duct-tape">Enter: Duct Tape</h2>

<p>Carl Sagan once said, “If you wish to make an apple pie from scratch, you must first invent the universe.” If you want to do that with a dark theme for someone else&#39;s website, I guess you have to stare at inspect element until you can&#39;t keep your eyes open. Between the very basic style info in the writers guide, pulling variables in inspect element, and consulting with <a href="https://www.w3schools.com/w3css/default.asp" rel="nofollow">W3Schools</a>, I slowly managed to cobble together my custom theme. My vision was heavily inspired by one of the templates from System76&#39;s COSMIC dark mode, which has an umber background, along with yellow links, and an off-white base text. Surprisingly, I was able to get pretty far along, and I feel like I&#39;ve (mostly) gotten to the point where basic stuff is presentable now. I even added some additional rules to match some personal tastes, like having titles be sans-serif, with the body being serif type. Also yes, I&#39;ve fixed my justify problem, and can finally sleep at night knowing my margins are nice and orderly.</p>

<p>That being said, not only have I run into some limitations, but I also have already managed to create quite the mess of code. Things are not ordered in a sensible way, my comments are outdated, and I&#39;m sure I&#39;ll need to add even more rules before I actually begin to clean it up. I intend to use this blog entry to help with figuring that out, since I won&#39;t know something is broken, until I try to actually use it. Once I do manage to clean up everything I feasibly can, my intent is to make variants of this theme for other blogs. Perhaps one inspired by <a href="https://kde.org/plasma-desktop/" rel="nofollow">KDE Plasma&#39;s</a> dark breeze theme, or maybe one of the Dracula style dark themes I&#39;ve seen in programs such as <a href="https://getvoyager.app/" rel="nofollow">Voyager</a> would be a good second version. As for the limitations, there seems to be some oddly hard-coded problems I can&#39;t work around with my custom style sheet. For example, this little bugger is jammed right into the webpage directly, so no matter what I do, it overwrites all style rules:</p>

<pre><code class="language-css">.post-byline .byline-author {
display:inline-flex;
align-items:center;
gap:0.5rem;
text-decoration:none;
color:#666;
font-size:0.9rem;
}
</code></pre>

<p>Most of this stuff isn&#39;t too big of a deal, but seriously, I&#39;m <em>forced</em> to have a specific color of gray text for my author name‽ In order to make this not an absolute contrast nightmare, I had to turn my name into a faux button; a button far darker than anything else in the theme too. It doesn&#39;t look <em>awful</em>, but it does absolutely stick out in a way I&#39;m not particularly keen on. I also can&#39;t for the life of me find a way to change my context menu icons from dark to light. Thankfully that&#39;s something only I can see, though I did manage to give them a background, and reduce their opacity to blend it better. Also, I ran into a roadblock you didn&#39;t even notice, despite it still impacting me as of this writing: blog avatars are broken. You might be saying to yourself “but I saw your avatar at the top of this article,” and you&#39;d be fair to say that—but you&#39;re wrong.</p>

<h3 id="hacking-in-an-avatar">Hacking In An Avatar</h3>

<p>Assuming it&#39;s still broken when you read this, try right clicking and opening my avatar in a new tab. You probably noticed it threw a lovely <code>404 not found</code> error, and tries to find an image called <code>default.png</code>. This is because I am totally unable to upload an avatar, but more than that, the default fallback avatars are broken too. Now, of course I brought this to the attention of the kind hosts of this instance, but in the interim, I was determined to prod at this until I made <em>something</em> happen. I have a feeling that I can hypothetically pull this off, because I can see that images can load through CSS, and there are a few tutorials on it through W3Schools too. Also, I&#39;ll need a reasonably reliable host to service the image as well. I figure since it&#39;s an avatar anyway, that I could just source it from one of several sites I use this exact image for the same purpose. Let&#39;s get a better look at our objective, shall we?</p>

<p><img src="https://storage.etternaonline.com/images/494260/conversions/foxfire-pfp-optimised.webp" alt="foxfire-pfp-optimised.webp"></p>

<blockquote><p>“The mission is simple: get me in there.”</p></blockquote>

<p>I ended up choosing my profile from <a href="https://etternaonline.com/users/Foxfire" rel="nofollow">Etterna Online</a>, a website for a FOSS rhythm game. I went with it because I know the owner, and I know full well this is exactly the place which won&#39;t care whatsoever, that I&#39;m hot-linking a small image to an even smaller blog. When I added it as the background for the the property which controls the avatar, I suddenly see nothing but blue—fantastic! That means it&#39;s loaded the image at full size inside the circle, and now I simply need to reduce it to the correct value. This turned out to be 28px by 28px, and was very simple to append to the image properties. So with that, I managed to hack my way to a faux profile picture, effectively indistinguishable from a normal one. On top of that, I can do this for any blog independently, meaning they can all have <em>different</em> faux avatars for as long as necessary. Realistically, even if it were never resolved, I still won; I feel really good about that.</p>

<p>I suppose I need to test tables too:</p>

<table>
<thead>
<tr>
<th>Status</th>
<th>Action</th>
</tr>
</thead>

<tbody>
<tr>
<td>Working</td>
<td>Relax</td>
</tr>

<tr>
<td>Broken</td>
<td>Resolve</td>
</tr>
</tbody>
</table>
]]></content:encoded>
      <author>Foxfire</author>
      <guid>https://pen.blahaj.zone/read/a/du261ru6k7</guid>
      <pubDate>Sun, 12 Apr 2026 05:10:49 +0000</pubDate>
    </item>
    <item>
      <title>Hello World, Under Construction</title>
      <link>https://pen.blahaj.zone/foxfire/hello-world-under-construction</link>
      <description>&lt;![CDATA[Two statements uttered countless times since the dawn of the Internet, and once again at the helm of ushering in an indie web project. As the bells chime, and the customary heavy equipment is waved into position for their role as a two frame GIF, we come together and welcome to the world: another blog. This serves as both an intro and a test post—and before you start carving the headstone—I assure you, I have plenty of writings to the void on the horizon. The thing is, I already do this entirely on my own in LibreOffice, so a lot of this will actually be me reviewing, and posting those words here over time!&#xA;!--more--&#xA;You might be wondering how much I&#39;ve written, and what that&#39;ll translate to as far as blog entries. I can tell you for sure, that I have well over 100 pages of journal entries and notes from the last couple of years, which I imagine would be several dozen blog posts by the time I posted them all. By far, my largest writing is the GNU/Linux diary, which as of this post sits at a beefy 94 pages long. It&#39;s large enough that I created a separate blog for it here, so it&#39;ll be more organized. You might be inclined to think something so large would contain intimate knowledge, or at least something esoteric, but it&#39;s actually the opposite. Back when I started this journal, I always felt like everyone who wrote about GNU/Linux endeavors, actually seemed to know what they were doing. So many folks have absolutely no idea what they&#39;re doing, and also have zero experience. I thought writing from the prospective of someone who&#39;s never touched this stuff their entire life, would be a neat niche to fill, and also help me see how I grow over time. &#xA;&#xA;Beyond that, I intend to purpose this blog (not the GNU/Linux one), with various writings; old, and likely new too. There have been many times where I feel like writing something, but end up succumbing to the combined weight of my unending tiredness, and feeling that the write-up has no place to go anyway. I think what I realistically want is a personal website, but it will take me ages to get one up and running. I let perfect get in the way of good too often, preventing me from getting started on things I actually want to do. That being said, when I happened upon a WriteFreely—a simple FOSS blog platform—my interest was piqued! It&#39;s pretty much what I&#39;m looking for: a simple way to write to no one, on my own little corner of the Internet. Something publicly accessible, but with no metrics, or assumptions that anyone will ever read it. A website, if that website was basically just a markdown file. It&#39;s so simple, so empty; it&#39;s a call to the void—and I&#39;m ready to answer it.]]&gt;</description>
      <content:encoded><![CDATA[<p>Two statements uttered countless times since the dawn of the Internet, and once again at the helm of ushering in an indie web project. As the bells chime, and the customary heavy equipment is waved into position for their role as a two frame GIF, we come together and welcome to the world: another blog. This serves as both an intro and a test post—and before you start carving the headstone—I assure you, I have plenty of writings to the void on the horizon. The thing is, I already do this entirely on my own in LibreOffice, so a lot of this will actually be me reviewing, and posting those words here over time!

You might be wondering how much I&#39;ve written, and what that&#39;ll translate to as far as blog entries. I can tell you for sure, that I have well over 100 pages of journal entries and notes from the last couple of years, which I imagine would be several dozen blog posts by the time I posted them all. By far, my largest writing is the <em>GNU/Linux diary</em>, which as of this post sits at a beefy <strong>94 pages</strong> long. It&#39;s large enough that I created a separate blog for it here, so it&#39;ll be more organized. You might be inclined to think something so large would contain intimate knowledge, or at least something esoteric, but it&#39;s actually the opposite. Back when I started this journal, I always felt like everyone who wrote about GNU/Linux endeavors, actually seemed to know what they were doing. So many folks have absolutely no idea what they&#39;re doing, and also have zero experience. I thought writing from the prospective of someone who&#39;s never touched this stuff their entire life, would be a neat niche to fill, and also help me see how I grow over time.</p>

<p>Beyond that, I intend to purpose <em>this</em> blog (not the GNU/Linux one), with various writings; old, and likely new too. There have been many times where I feel like writing something, but end up succumbing to the combined weight of my unending tiredness, and feeling that the write-up has no place to go anyway. I think what I realistically want is a personal website, but it will take me ages to get one up and running. I let perfect get in the way of good too often, preventing me from getting started on things I actually want to do. That being said, when I happened upon a WriteFreely—a simple FOSS blog platform—my interest was piqued! It&#39;s pretty much what I&#39;m looking for: a simple way to write to no one, on my own little corner of the Internet. Something publicly accessible, but with no metrics, or assumptions that anyone will <em>ever</em> read it. A website, if that website was basically just a markdown file. It&#39;s so simple, so empty; it&#39;s a call to the void—and I&#39;m ready to answer it.</p>
]]></content:encoded>
      <author>Foxfire</author>
      <guid>https://pen.blahaj.zone/read/a/sksqxjd9bl</guid>
      <pubDate>Fri, 10 Apr 2026 00:13:35 +0000</pubDate>
    </item>
    <item>
      <title>I was planning to finish Gojira&#39;s discography.</title>
      <link>https://pen.blahaj.zone/reilyh/i-was-planning-to-finish-gojiras-discography</link>
      <description>&lt;![CDATA[I was planning to finish Gojira&#39;s discography. I may update this page in the future to flesh things out a bit.&#xA;Intro To Metal&#xA;&#xA;So Gojira was my first introduction to metal. I think I was looking for jawharp metal tracks, and &#34;Amazonia&#34; showed up, I said &#34;fuck it we ball&#34; and listened to the whole album. I then listened to &#34;Magma&#34;, and I liked my &#34;Silvera&#34; and my &#34;Stranded&#34;. I also listened to &#34;The Way Of All Flesh&#34; and only liked &#34;Oroborus&#34;. But after a whole year, after I listened to so much more metal, I really like &#34;The Way Of All Flesh&#34;. And so I started to crave earlier Gojira, and I found out about &#34;From Mars To Sirius&#34; &lt;3&#xA;&#xA;!--more--&#xA;!-- rest of the content --&#xA;Favorite Tracks&#xA;&#xA;If I have to to choose ~one~ ~three~ tracks from each album it would be:&#xA;&#xA;From Mars To Sirius:&#xA;This album is great, has beautiful lyrics, I have so much to say about it! Granted I listened to it without reading the lyrics, so my only impression of this album is the riffs.&#xA;&#xA;Ocean Planet: The intro, and especially the part at 3:50, &#34;Whyyyyy do they call me there!!!!&#34; I teared at that part. I kinda feel like that whale being stuck alone.&#xA;&#xA;Backbone.&#xA;Unicron: Because it has really beautiful whale songs, and just a good break for what is to come.&#xA;&#xA;L&#39;Enfant Sauvage:&#xA;&#xA;Explosia: Really shines at 0:35 and and 4:05, especially the ending of the song, with these beautiful, I think they&#39;re called gallops. Anyway they&#39;re cool and I like them.&#xA;The Axe&#xA;Planned Obsolescence&#xA;Pain Is a Master&#xA;Born In Winter&#xA;&#xA;The Way Of All Flesh&#xA;&#xA;This is the album that I a most familiar with.&#xA;&#xA;Oroborus: This track, holy fuck. That haunting part at 3:08? Fucking liquid gold.&#xA;Toxic garbage Island: Other than the bad ass name, the intro is really poweful. Part at 0:52 &lt;3. Also &#34;PLAAAASTIC BAG IN THE SEEAAAAAAA&#34;&#xA;A sight to behold: Now this is a track that deserves a place in the hall of lyrics. I mean:&#xA;The way I see things is so simple&#xA;The fact I&#39;m walking standing on this land&#xA;Exhausted is the realm of nature, friends are dying&#xA;The living creatures on our side&#xA;The way I see myself so confused so sophisticated&#xA;I have to stay away from me&#xA;But I still don&#39;t get the point&#xA;What&#39;s worth destroying all the worlds&#xA;Try not to get it anymore&#xA;&#xA;The way I see things is so simple&#xA;The fact I&#39;m walking standing on this land&#xA;...&#xA;The way I see myself so confused so sophisticated&#xA;&#xA;That right there, is what I will take to my grave.&#xA;&#xA;This track is truley, a sight to behold.&#xA;&#xA;Yama&#39;s messengers: &#34;I&#39;m scared to death when I see them arrive!&#34; Part at 0:46, 2:14. &#34;I&#39;ve killed so many, I don&#39;t want to count&#34;!&#xA;The silver cord: Always love some instrumental metal that I can play loudly and no one would complain.&#xA;Adoration for none: Baddass title, amazing vocal style at the start. The part from 0:54 all the way for like a minute, is fucking, wow. Also:&#xA;Nature is my only master&#xA;I will bow to no one&#xA;...&#xA;Crave for freedom build my own life&#xA;Adoration for none&#xA;&#xA;Words of. Fucking. Power.&#xA;&#xA;And 2:08!&#xA;&#xA;This track is just so differenet from the rest of the album, I adore it so much.&#xA;&#xA;The art of dying: :) sick ass drum work. Really beautiful opening riffs, 4:12?&#xA;Riff goes crazy&#xA;Take no possessions, I would rather travel light&#xA;&#xA;Then &#34;AAAAAAART OF DYING!!!!!!&#34;&#xA;&#xA;Esoteric surgery: &#34;You have the power to heal yourself.&#34;&#xA;Gojira - Vacuity&#xA;Gojira - Wolf down the earth&#xA;The way of all flesh: Is this what dying feels like?&#xA;&#xA;So in search of something more similar to Gojira&#39;s early albums, I turned to the bands that they take their inspiration from: Mastodon and Meshuggah.&#xA;&#xA;But more on that later, as I still have &#34;Magma&#34; and &#34;Fortitude&#34; and I&#39;m not that eager to do them. Don&#39;t get me wrong, &#34;Stranded&#34; was one my favorite earlier metal tracks, and maybe it still is. Idk.&#xA;&#xA;I also need to learn about song structure and general metal terminology, &#34;riff&#34; and &#34;part&#34; are absolutely not a proper way to describe songs.]]&gt;</description>
      <content:encoded><![CDATA[<p>I was planning to finish Gojira&#39;s discography. I may update this page in the future to flesh things out a bit.</p>

<h1 id="intro-to-metal">Intro To Metal</h1>

<p>So Gojira was my first introduction to metal. I think I was looking for jawharp metal tracks, and “Amazonia” showed up, I said “fuck it we ball” and listened to the whole album. I then listened to “Magma”, and I liked my “Silvera” and my “Stranded”. I also listened to “The Way Of All Flesh” and only liked “Oroborus”. But after a whole year, after I listened to so much more metal, I really like “The Way Of All Flesh”. And so I started to crave earlier Gojira, and I found out about “From Mars To Sirius” &lt;3</p>





<h3 id="favorite-tracks">Favorite Tracks</h3>

<p>If I have to to choose ~one~ ~three~ tracks from each album it would be:</p>

<h4 id="from-mars-to-sirius">From Mars To Sirius:</h4>

<p>This album is great, has beautiful lyrics, I have so much to say about it! Granted I listened to it without reading the lyrics, so my only impression of this album is the riffs.</p>
<ul><li><p>Ocean Planet: The intro, and especially the part at 3:50, “Whyyyyy do they call me there!!!!” I teared at that part. I kinda feel like that whale being stuck alone.</p></li>

<li><p>Backbone.</p></li>

<li><p>Unicron: Because it has really beautiful whale songs, and just a good break for what is to come.</p></li></ul>

<h4 id="l-enfant-sauvage">L&#39;Enfant Sauvage:</h4>
<ul><li>Explosia: Really shines at 0:35 and and 4:05, especially the ending of the song, with these beautiful, I think they&#39;re called gallops. Anyway they&#39;re cool and I like them.</li>
<li>The Axe</li>
<li>Planned Obsolescence</li>
<li>Pain Is a Master</li>
<li>Born In Winter</li></ul>

<h4 id="the-way-of-all-flesh">The Way Of All Flesh</h4>

<p>This is the album that I a most familiar with.</p>
<ul><li>Oroborus: This track, holy fuck. That haunting part at 3:08? Fucking liquid gold.</li>
<li>Toxic garbage Island: Other than the bad ass name, the intro is really poweful. Part at 0:52 &lt;3. Also “PLAAAASTIC BAG IN THE SEEAAAAAAA”</li>
<li>A sight to behold: Now this is a track that deserves a place in the hall of lyrics. I mean:
<code>
The way I see things is so simple
The fact I&#39;m walking standing on this land
Exhausted is the realm of nature, friends are dying
The living creatures on our side
The way I see myself so confused so sophisticated
I have to stay away from me
But I still don&#39;t get the point
What&#39;s worth destroying all the worlds
Try not to get it anymore
</code></li></ul>

<pre><code>The way I see things is so simple
The fact I&#39;m walking standing on this land
...
The way I see myself so confused so sophisticated
</code></pre>

<p>That right there, is what I will take to my grave.</p>

<p>This track is truley, a sight to behold.</p>
<ul><li>Yama&#39;s messengers: “I&#39;m scared to death when I see them arrive!” Part at 0:46, 2:14. “I&#39;ve killed so many, I don&#39;t want to count”!</li>
<li>The silver cord: Always love some instrumental metal that I can play loudly and no one would complain.</li>
<li>Adoration for none: Baddass title, amazing vocal style at the start. The part from 0:54 all the way for like a minute, is fucking, wow. Also:
<code>
Nature is my only master
I will bow to no one
...
Crave for freedom build my own life
Adoration for none
</code></li></ul>

<p>Words of. Fucking. Power.</p>

<p>And 2:08!</p>

<p>This track is just so differenet from the rest of the album, I adore it so much.</p>
<ul><li>The art of dying: :) sick ass drum work. Really beautiful opening riffs, 4:12?
<code>I won&#39;t bring no material in the after life
*Riff goes crazy*
Take no possessions, I would rather travel light
</code></li></ul>

<p>Then “AAAAAAART OF DYING!!!!!!”</p>
<ul><li>Esoteric surgery: “You have the power to heal yourself.”</li>
<li>Gojira – Vacuity</li>
<li>Gojira – Wolf down the earth</li>
<li>The way of all flesh: Is this what dying feels like?</li></ul>

<p>So in search of something more similar to Gojira&#39;s early albums, I turned to the bands that they take their inspiration from: Mastodon and Meshuggah.</p>

<p>But more on that later, as I still have “Magma” and “Fortitude” and I&#39;m not that eager to do them. Don&#39;t get me wrong, “Stranded” was one my favorite earlier metal tracks, and maybe it still is. Idk.</p>

<p>I also need to learn about song structure and general metal terminology, “riff” and “part” are absolutely not a proper way to describe songs.</p>
]]></content:encoded>
      <author>reilyh</author>
      <guid>https://pen.blahaj.zone/read/a/ei9f0v5jp4</guid>
      <pubDate>Thu, 12 Mar 2026 02:23:07 +0000</pubDate>
    </item>
    <item>
      <title>Dragons I made in DragonCreator</title>
      <link>https://pen.blahaj.zone/reilyh/dragons-i-made-in-dragoncreator</link>
      <description>&lt;![CDATA[Here&#39;s a cool dragon creator on itch.io&#xA;&#xA;This page will be updated a lot in the future as I make more dragons, or like, find more dragon creators.&#xA;&#xA;Vampire Dragon.png&#xA;Black Hole Dragon.png&#xA;Midnight Carp Dragon.png&#xA;Giraffe Dragon.png&#xA;&#xA;Human Dragon.png&#xA;&#xA;Radioactive Dragon.png&#xA;&#xA;Satan Dragon.png&#xA;&#xA;Snow Dragon.png&#xA;&#xA;Cthulu Dragon.png&#xA;&#xA;Cthulu Dragon - Alt Color.png&#xA;&#xA;Suzie Dragon.png&#xA;&#xA;Kris Dragon.png&#xA;&#xA;4 Color Dragon.png&#xA;&#xA;2 Color Dragon - Black and White.png&#xA;&#xA;Human Dragon - Mark 2.png&#xA;&#xA;---&#xA;&#xA;and here&#39;s the code for these designs: &#xA;&#xA;110q&amp;Nw04J00000200000f0000c08D000068000V00040J001000000000000000000000008gTkTk0000Tk00%%XLX-XzDzDPPPPD-K5D-8fPP00f8PP0000f8PP008gTkTk0000TkD-0000f8PP00TkTk0000TkD-0000f8PP00TkTk0000TkD-PPPP8gTkTk0000Tkf8XL8gTkTk0000Tkf8XLppTkTk0000TkTkTk00 | Vampire Dragon&#xA;12cv&amp;md39MJ0G3kw11110kHX2xx0;mJtV0.4;m3TGV0.w:00fc02h000Jfhh00J0c41JJ40000J?~40000J?00-00NPJ?sg4Nsg~44Nsg8N4Nsg004N~40000f8PP0000sg00000000~400008Nsg00sg00000000~400008Nsg00sg000000008N00jL008NTk0000Tk8Nsg00sgTk0000Tk8Nsg008N000000TkJdsg00 | Black Hole Dragon&#xA;12cd8m051J00000t000000QJ01w0000H41p6&amp;J6nv41r8:003c00JS4w0c003468D20c0J00J5xXxX0000xX44G&amp;9!xX~r~rf8PPPPf8PPPPf8PP00f8PP0000f8PP00J5J5xX0000J544000044PP00J5xX0000J544000044PP00J5xX0000J5J59!c&amp;4444Tk0000Tkf8PP4444Tk0000Tkf8PPJ5xXxX00004444Tk00 | Midnight Carp Dragon&#xA;110c:-0M4J00S600000000Pr00K08009B000hm009B040z053D0N00000000000000000000y,Ddp40000Y04000Y2JLP5%~Dd40PPDd8JPPf8PP00f8PP0000f8PP00y,Y2Nx0000Y0zD0000DJp400Y2Nx0000Y0zD0000DJp400Y2Nx0000Y0f8PPPPy,,8Y20000Nxf8PPy,,8Y20000Nxf8PPppTkTk0000TkTkTk00 | Giraffe Dragon&#xA;1106JN0545S0J40200030f52008080J5D000Nw005D0409w13d0000000000000000000000.R43Jf0000Tk436%%%x5l%~f8PPPP~R~6PPJfNf00NfJf0000f8PP00DKDKDK0000TkzD0000JfPP00DKDK0000TkzD0000JfPP00DKDK0000Tkf8PPPPDK%%.R0000,D80PPDK.R,D0000DK80PPppTkTk0000TkTkTk00 | Human Dragon&#xA;11cc8XK39JS0D34B03030fPX2xn80cS000120004c004J;05Mh0Pk01:M0!D00J0c471yJ00ZhRcRc0000RcRcRcRcx5l%~vlRcRcRcPPRcf8PP00RcRc0000f8PP00VKTkTk0000TkDh0000ZhRc00TkTk0000TkDh0000ZhRc00TkTk0000TkVKPPRcVKZhZh0000RcRcRcVKZhZh0000RcRcRcZhDhRc0000RcTkvl00 | Radioactive Dragon&#xA;110v&amp;Ndv5MSfP5JZ01210f221S;09m1F0064-00TF0048xJ1c7020000LwccL0N0m010J000c0DLc00000DLDzr0r0DPJg,DDLPPDLc0c0DLP00DLPP0000DLP00c0DLTk0000TkP0000DLP00DLTk0000TkP0000DLP00DLTk0000TkDLPPPc0DLw00000,DDLPc0DLDL0000,DDLPppTkTk0000TkTkTk00 | Satan Dragon&#xA;10cs&amp;Sdv43039fVv30300f9X1rd0880FG0m4-:2dFG0rNB030m0D00000000000000000000FZfs8M00008M%:FZFZx5l%~fs%%PPFZfsPPfs%%00f8PP0000f8PP00FZFZFZ0000fsfs0000FZfs00FZFZ0000fsfs0000FZfs00FZFZ0000fsFZPPfszZ%%FZ0000fsf8PPzZ%%FZ0000fsf8PPppTkTk0000TkTkTk00 | Snow Dragon&#xA;11cc:JwhC0S0006.03030pHB04!c0c9t0004:001G0050:J0Md01V&amp;08d0000000080000009PL8L80000TkL8L8L89PL8Ph9PL8Ph9PPPL8f8PP009PL80000f8PP009PL8Tk0000TkzD00009PF.00L8Tk0000TkzD00009PF.00L8Tk0000TkYPhPP9PL8Ph0000Tk9PL89PL8Ph0000Tk9PL89PPhPh0000TkL8Ph00 | Cthulu Dragon&#xA;11cc:JwhC0S0006.03030pHB04!c0c9t0054:00PG0050:J0Md01V&amp;08d000000008000000PhL8L80000TkL8L8L89PL8PhPh9PPhPhPP9Pf8PP009PL80000f8PP00PhYTk0000TkY00009PF.00YTk0000TkY00009PF.00YTk0000TkYPhPPPh9PL80000Tk9PL8Ph9PL80000Tk9PL8PhL8L80000TkL8Ph00 | Cthulu Dragon - Alt Color&#xA;110h:SJK4J81Ggm010100f2S10-c1001G0144:051G041;c17k0400000000000000000000~FhR0d0000~F0d~.0dN:hR~.hRhRPPhRPPhRhRhR00hRPP0000f8PP000d~FhR0000N:N:0000hRhR00~FhR0000N:N:0000hRhR00~FhR0000N:~.PPPP0d~.~F0000~.f8PP0d~.~F0000~.f8PPppTkTk0000TkTkTk00 | Suzie Dragon&#xA;110jN8c080S1Ggm010100f7k08J00800B0k00m2S0B0h0p0B060N000000000000000000004Pb~b~00004P00%000T&amp;:9zv4PPPPP4PPPPP03PP004PPP0000f8PP004PT&amp;030000:9zv00004PPP00T&amp;030000:9zv00004PPP00T&amp;030000:9f8PPPP4Pzvzv0000b~f8PP0303zv0000T&amp;f8PPppTkTk0000TkTkTk00 | Kris Dragon&#xA;110c8hK1NJ1Ggrp12120fQN1fN008J0V0641m0T0V05J&amp;01gw0600000000000000000000XMFlJ70000J7J7KxKxJ7XMKxJ7XMKxf8PPPPJ7XM00J7XM0000f8PP00XMJ7J70000KxKx0000J7XM00J7J70000KxKx0000J7XM00J7J70000KxJ7XMXMXMJ7Fl0000KxJ7XMXMJ7Fl0000KxJ7XMXMTkTk0000TkTkTk00 | 4 Color Dragon&#xA;120smJcg1MJ1Kh0410100fPQ0Mn008JG00K4:015G00QN!013m04lN4c0000000000000000?FDD0000DD?FDD?F?FD?FPPf8PPPPD?F00D?F0000f8PP00D?FD0000?F?F0000D?F00?FD0000?F?F0000D?F00?FD0000?FD?F?F?FDD0000?Ff8PP?FDD0000?Ff8PPD?FD0000DTk?F00 | 2 Color Dragon - Black and White&#xA;1105JJJc8403J4S213230f941w04:80GG004::01GG040;w1gl0600000000000000000000!!!nJJ0000!n00jf%~x5l%~JJPPSdJJSdPPJJSd00f8PP0000f8PP00!!x.JJ0000Sd!n0000JJSd00x.JJ0000Sd!n0000JJSd00x.JJ0000Sdf8PPPP!!jNx.0000?tJJSd!!jNx.0000?tJJSd!!TkTk0000TkTkTk00 | Human Dragon - Mark 2&#xA;`]]&gt;</description>
      <content:encoded><![CDATA[<p>Here&#39;s a cool <a href="https://dragonita.itch.io/dragon-creator" rel="nofollow">dragon creator</a> on itch.io</p>

<p>This page will be updated a lot in the future as I make more dragons, or like, find more dragon creators.</p>

<p><img src="https://l8b5.c11.e2-2.dev/writemedia/4/2026/02/68e8ed19-849e-4a.png" alt="Vampire Dragon.png">
<img src="https://l8b5.c11.e2-2.dev/writemedia/4/2026/02/2f45cc53-a5be-45.png" alt="Black Hole Dragon.png">
<img src="https://l8b5.c11.e2-2.dev/writemedia/4/2026/02/5af966d3-5532-4f.png" alt="Midnight Carp Dragon.png">
<img src="https://l8b5.c11.e2-2.dev/writemedia/4/2026/02/c84e5a4c-20bd-42.png" alt="Giraffe Dragon.png"></p>

<p><img src="https://l8b5.c11.e2-2.dev/writemedia/4/2026/02/63d26741-63d6-49.png" alt="Human Dragon.png"></p>

<p><img src="https://l8b5.c11.e2-2.dev/writemedia/4/2026/02/53921810-d6ad-4e.png" alt="Radioactive Dragon.png"></p>

<p><img src="https://l8b5.c11.e2-2.dev/writemedia/4/2026/02/520fcb52-9aca-44.png" alt="Satan Dragon.png"></p>

<p><img src="https://l8b5.c11.e2-2.dev/writemedia/4/2026/02/25dd9b23-d8b6-49.png" alt="Snow Dragon.png"></p>

<p><img src="https://l8b5.c11.e2-2.dev/writemedia/4/2026/02/af02e8e3-35b8-45.png" alt="Cthulu Dragon.png"></p>

<p><img src="https://l8b5.c11.e2-2.dev/writemedia/4/2026/02/12986e32-9be5-41.png" alt="Cthulu Dragon - Alt Color.png"></p>

<p><img src="https://l8b5.c11.e2-2.dev/writemedia/4/2026/02/b03ef552-79ad-47.png" alt="Suzie Dragon.png"></p>

<p><img src="https://l8b5.c11.e2-2.dev/writemedia/4/2026/02/11fc9b43-17b0-4d.png" alt="Kris Dragon.png"></p>

<p><img src="https://l8b5.c11.e2-2.dev/writemedia/4/2026/02/755991b4-e053-48.png" alt="4 Color Dragon.png"></p>

<p><img src="https://l8b5.c11.e2-2.dev/writemedia/4/2026/02/f79ae0ae-1f5a-43.png" alt="2 Color Dragon - Black and White.png"></p>

<p><img src="https://l8b5.c11.e2-2.dev/writemedia/4/2026/02/077c14d5-0340-4c.png" alt="Human Dragon - Mark 2.png"></p>

<hr>

<p>and here&#39;s the code for these designs:</p>

<pre><code>110q&amp;Nw04J00000200000f0000c08D000068000V00040J001000000000000000000000008gTkTk0000Tk00%%XLX-X_zDzDPPPPD-K5D-8fPP00f8PP0000f8PP008gTkTk0000TkD-0000f8PP00TkTk0000TkD-0000f8PP00TkTk0000TkD-PPPP8gTkTk0000Tkf8XL8gTkTk0000Tkf8XLppTkTk0000TkTkTk00 | Vampire Dragon
12cv&amp;md39MJ0G3kw11110kHX2xx0;mJtV0.4;m3TGV0.w:00fc02h000Jfhh00J0c41JJ40000J?~40000J?00_-00NPJ?sg4Nsg~44Nsg8N4Nsg004N~40000f8PP0000sg00000000~400008Nsg00sg00000000~400008Nsg00sg000000008N00jL008NTk0000Tk8Nsg00sgTk0000Tk8Nsg008N000000TkJdsg00 | Black Hole Dragon
12cd8m051J00000t000000QJ01w0000H41p6&amp;J6nv41r8:003c00JS4w0c003468D20c0J00J5xXxX0000xX44G&amp;9!xX~r~rf8PPPPf8PPPPf8PP00f8PP0000f8PP00J5J5xX0000J544000044PP00J5xX0000J544000044PP00J5xX0000J5J59!c&amp;4444Tk0000Tkf8PP4444Tk0000Tkf8PPJ5xXxX00004444Tk00 | Midnight Carp Dragon
110c:-0M4J00S600000000Pr00K08009B000hm009B040z053D0N00000000000000000000y,Ddp40000Y04000Y2JLP5%~Dd40PPDd8JPPf8PP00f8PP0000f8PP00y,Y2Nx0000Y0zD0000DJp400Y2Nx0000Y0zD0000DJp400Y2Nx0000Y0f8PPPPy,,8Y20000Nxf8PPy,,8Y20000Nxf8PPppTkTk0000TkTkTk00 | Giraffe Dragon
1106JN0545S0J40200030f52008080J5D000Nw005D0409w13d0000000000000000000000.R43Jf0000Tk436%%%x5_l%~f8PPPP~R~6PPJfNf00NfJf0000f8PP00DKDKDK0000TkzD0000JfPP00DKDK0000TkzD0000JfPP00DKDK0000Tkf8PPPPDK%%.R0000,D80PPDK.R,D0000DK80PPppTkTk0000TkTkTk00 | Human Dragon
11cc8XK39JS0D34B03030fPX2xn80cS000120004c004J;05Mh0Pk01:M0!D00J0c471yJ00ZhRcRc0000RcRcRcRcx5_l%~vlRcRcRcPPRcf8PP00RcRc0000f8PP00VKTkTk0000TkDh0000ZhRc00TkTk0000TkDh0000ZhRc00TkTk0000TkVKPPRcVKZhZh0000RcRcRcVKZhZh0000RcRcRcZhDhRc0000RcTkvl00 | Radioactive Dragon
110v&amp;Ndv5MSfP5JZ01210f221S;09m1F0064-00TF0048xJ1c7020000LwccL0N0m010J000c0DLc00000DLDzr0r0DPJg,DDL_P_PDLc0c0DL_P00DLPP0000DL_P00c0DLTk0000Tk_P0000DL_P00DLTk0000Tk_P0000DL_P00DLTk0000TkDLPP_Pc0DLw00000,DDL_Pc0DLDL0000,DDL_PppTkTk0000TkTkTk00 | Satan Dragon
10cs&amp;Sdv43039fVv30300f9X1rd0880FG0m4-:2dFG0rNB030m0D00000000000000000000FZfs8M00008M%:FZFZx5_l%~fs%%PPFZfsPPfs%%00f8PP0000f8PP00FZFZFZ0000fsfs0000FZfs00FZFZ0000fsfs0000FZfs00FZFZ0000fsFZPPfszZ%%FZ0000fsf8PPzZ%%FZ0000fsf8PPppTkTk0000TkTkTk00 | Snow Dragon
11cc:JwhC0S0006.03030pHB04!c0c9t0004:001G0050:J0Md01V&amp;08d0000000080000009PL8L80000TkL8L8L89PL8Ph9PL8Ph9PPPL8f8PP009PL80000f8PP009PL8Tk0000TkzD00009PF.00L8Tk0000TkzD00009PF.00L8Tk0000TkY_PhPP9PL8Ph0000Tk9PL89PL8Ph0000Tk9PL89PPhPh0000TkL8Ph00 | Cthulu Dragon
11cc:JwhC0S0006.03030pHB04!c0c9t0054:00PG0050:J0Md01V&amp;08d000000008000000PhL8L80000TkL8L8L89PL8PhPh9PPhPhPP9Pf8PP009PL80000f8PP00PhY_Tk0000TkY_00009PF.00Y_Tk0000TkY_00009PF.00Y_Tk0000TkY_PhPPPh9PL80000Tk9PL8Ph9PL80000Tk9PL8PhL8L80000TkL8Ph00 | Cthulu Dragon - Alt Color
110h:SJK4J81Ggm010100f2S10-c1001G0144:051G041;c17k0400000000000000000000~FhR0d0000~F0d~.0dN:hR~.hRhRPPhRPPhRhRhR00hRPP0000f8PP000d~FhR0000N:N:0000hRhR00~FhR0000N:N:0000hRhR00~FhR0000N:~.PPPP0d~.~F0000~.f8PP0d~.~F0000~.f8PPppTkTk0000TkTkTk00 | Suzie Dragon
110jN8c080S1Ggm010100f7k08J00800B0k00m2S0B0h0p0B060N000000000000000000004Pb~b~00004P00%000T&amp;:9zv4PPPPP4PPPPP03PP004PPP0000f8PP004PT&amp;030000:9zv00004PPP00T&amp;030000:9zv00004PPP00T&amp;030000:9f8PPPP4Pzvzv0000b~f8PP0303zv0000T&amp;f8PPppTkTk0000TkTkTk00 | Kris Dragon
110c8hK_1NJ1Ggrp12120fQN1fN008J0V0641m0T0V05J&amp;01gw0600000000000000000000XMFlJ70000J7J7KxKxJ7XMKxJ7XMKxf8PPPPJ7XM00J7XM0000f8PP00XMJ7J70000KxKx0000J7XM00J7J70000KxKx0000J7XM00J7J70000KxJ7XMXMXMJ7Fl0000KxJ7XMXMJ7Fl0000KxJ7XMXMTkTk0000TkTkTk00 | 4 Color Dragon
120smJcg1MJ1Kh0410100fPQ0Mn008JG00K4:015G00QN!013m04lN4c0000000000000000?FD_D_0000D_D_?FD_D_?F?FD_?FPPf8PPPPD_?F00D_?F0000f8PP00D_?FD_0000?F?F0000D_?F00?FD_0000?F?F0000D_?F00?FD_0000?FD_?F?F?FD_D_0000?Ff8PP?FD_D_0000?Ff8PPD_?FD_0000D_Tk?F00 | 2 Color Dragon - Black and White
1105JJJc8403J4S213230f941w04:80GG004::01GG040;w1gl0600000000000000000000!!!nJJ0000!n00jf%~x5_l%~JJPPSdJJSdPPJJSd00f8PP0000f8PP00!!x.JJ0000Sd!n0000JJSd00x.JJ0000Sd!n0000JJSd00x.JJ0000Sdf8PPPP!!jNx.0000?tJJSd!!jNx.0000?tJJSd!!TkTk0000TkTkTk00 | Human Dragon - Mark 2
</code></pre>
]]></content:encoded>
      <author>reilyh</author>
      <guid>https://pen.blahaj.zone/read/a/3bqbqi0k0t</guid>
      <pubDate>Sat, 14 Feb 2026 21:47:05 +0000</pubDate>
    </item>
    <item>
      <title>Hello world! This looks so fucking awesome~✨✨✨✨</title>
      <link>https://pen.blahaj.zone/reilyh/hello-world-this-looks-so-fucking-awesome</link>
      <description>&lt;![CDATA[Hello world! This looks so fucking awesome~✨✨✨✨]]&gt;</description>
      <content:encoded><![CDATA[<p>Hello world! This looks so fucking awesome~✨✨✨✨</p>
]]></content:encoded>
      <author>reilyh</author>
      <guid>https://pen.blahaj.zone/read/a/d2vck69urh</guid>
      <pubDate>Fri, 13 Feb 2026 18:35:11 +0000</pubDate>
    </item>
    <item>
      <title>Installing a Patroni cluster on Ubuntu</title>
      <link>https://pen.blahaj.zone/supakaity/installing-a-patroni-cluster-on-ubuntu</link>
      <description>&lt;![CDATA[So I&#39;ve recently been quizzed on the exact process I use to install our Postgres cluster, and after telling everyone how easy it was, I was asked to explain the process.&#xA;&#xA;It&#39;s not procrastination, it&#39;s something else... I swear!&#xA;Unfortunately I just have a bunch of embarrassing text files full of commands to run, so I decided it&#39;s about time I document it.&#xA;Perfect opportunity to install that federated personal blog I&#39;ve been thinking about for 6 months!&#xA;Except it doesn&#39;t work quite the way I want it to and doesn&#39;t support images or profile avatars...&#xA;Perfect opportunity to write an image hosting service that I can integrate with the blog software!&#xA;Except it doesn&#39;t count likes or show replies with my post...&#xA;Perfect opportunity to add the bits and pieces needed to track federated likes and replies!&#xA;Except now how do I let people who are seeing my blog post make likes and replies on their home instances?&#xA;Perfect opportunity to research URI scheme protocol handlers and redirector sites!&#xA;Except none of them work how I want them to work...&#xA;Perfect opportunity to design a new way to implement the draft protocol as a proof of concept/bootstrap project!&#xA;Except I promised to finish this article on the Patroni cluster thing by tonight.&#xA;&#xA;Argh... it&#39;s tough living with my brain, I now have another 3 unfinished projects. I don&#39;t know how Ada puts up with it... she showed me this picture...&#xA;distracted.png&#xA;I hate that I resemble this so much.&#xA;&#xA;Okay, so installing Patroni is really easy, writing about it requires much more effort.&#xA;&#xA;What is Patroni?&#xA;This is a really good question and it gets to the heart of the matter.&#xA;Patroni is a Postgres cluster manager.&#xA;You give it a bunch of hosts and tell it to run a Postgres cluster on them, and it manages the whole thing. Kinda like how a RAID controller manages an array of (not-so-inexpensive) disks.&#xA;If there&#39;s no database there, it&#39;ll start it up, join the cluster, download a copy of the data, and begin replication.&#xA;If there&#39;s a database there but it gets wrecked, it&#39;ll automatically rebuild it for you.&#xA;We&#39;ll also install useful other bits of software like HAProxy which points a certain port at the current primary and another port at the secondary.&#xA;If you&#39;ve ever had the joy of using any of the many Kubernetes operators for Postgres, it&#39;s like that, but for bare metal. When you&#39;re working on a budget, sometimes you can&#39;t afford the overhead of Kubernetes. If this was a project for a client, I&#39;d probably steer them towards the self-healing nature of a Kubernetes cluster + operator.&#xA;&#xA;Installing&#xA;I&#39;m going to take you through the process of setting up a brand new cluster of 3 servers.&#xA;I&#39;ve got these servers on an internal network:&#xA;db-cluster-1 10.19.96.3&#xA;db-cluster-2 10.19.96.4&#xA;db-cluster-3 10.19.96.5&#xA;&#xA;Run on all 3 hosts:&#xA;&#xA;As we&#39;re running Ubuntu, I&#39;m going to do a quick upgrade on them to get all the latest updates first.&#xA;apt update &amp;&amp; apt upgrade -y &amp;&amp; reboot&#xA;&#xA;Now it&#39;s time to make sure all the hosts know how to contact each other, even if/when DNS goes down.&#xA;&#xA;cat &lt;EOF   /etc/hosts&#xA;&#xA;Database hosts&#xA;10.19.96.3 db-cluster-1&#xA;10.19.96.4 db-cluster-2&#xA;10.19.96.5 db-cluster-3&#xA;EOF&#xA;&#xA;for i in 1 2 3; do&#xA;  ping -c 1 db-cluster-$i&#xA;done&#xA;&#xA;If you&#39;re running a firewall (hopefully you are), let&#39;s open up some ports well need:&#xA;for p in 2379 2380 8008; do&#xA;  ufw allow in proto tcp from 10.19.96.0/20 to any port $p&#xA;done&#xA;for p in 5000 5001; do&#xA;  ufw allow in proto tcp from any to any port $p&#xA;done&#xA;ufw status&#xA;NOTE: If you&#39;re putting a load balancer in front, you&#39;ll probably want to lock down the port 5000/5001 to just it, or otherwise just your application&#39;s network. &#xA;&#xA;Let&#39;s now get Percona rocking. Percona is a Postgres database with extra optimizations, this is what we will control with our Patroni controller to turn into a cluster.&#xA;&#xA;curl -O https://repo.percona.com/apt/percona-releaselatest.genericall.deb&#xA;apt install -y gnupg2 lsb-release ./percona-releaselatest.genericall.deb&#xA;apt update&#xA;percona-release setup ppg-16&#xA;&#xA;Now it&#39;s time to install our HAProxy software and configure it. This config will setup a proxy with 3 ports, the stats at port 7000, the primary at port 5000 and the standbys at port 5001.&#xA;&#xA;The standbys will use the health check on http://localhost:8008/replica which will return a 200 OK if that server is currently a replica node.&#xA;&#xA;If there are no replicas available, then it falls back to any available node (even the primary) to service standby nodes as a fail safe so your applications that are configured to talk to a read node don&#39;t get locked out.&#xA;&#xA;apt install -y percona-haproxy&#xA;cat &lt;EOF  /etc/haproxy/haproxy.cfg&#xA;global&#xA;    maxconn 500&#xA;&#xA;defaults&#xA;    log global&#xA;    mode tcp&#xA;    retries 2&#xA;    timeout client 30m&#xA;    timeout connect 4s&#xA;    timeout server 30m&#xA;    timeout check 5s&#xA;&#xA;listen stats&#xA;    mode http&#xA;    bind :7000&#xA;    stats enable&#xA;    stats uri /&#xA;&#xA;listen primary&#xA;    bind :5000&#xA;    option httpchk /primary&#xA;    http-check expect status 200&#xA;    default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions&#xA;    server db-cluster-1 db-cluster-1:5432 maxconn 500 check port 8008&#xA;    server db-cluster-2 db-cluster-2:5432 maxconn 500 check port 8008&#xA;    server db-cluster-3 db-cluster-3:5432 maxconn 500 check port 8008&#xA;&#xA;listen standbys&#xA;    balance roundrobin&#xA;    bind *:5001&#xA;    option httpchk /replica&#xA;    http-check expect status 200&#xA;    default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions&#xA;    server db-cluster-1 db-cluster-1:5432 maxconn 500 check port 8008&#xA;    server db-cluster-2 db-cluster-2:5432 maxconn 500 check port 8008&#xA;    server db-cluster-3 db-cluster-3:5432 maxconn 500 check port 8008&#xA;    server db-cluster-1-standby db-cluster-1:5432 maxconn 500 backup&#xA;    server db-cluster-2-standby db-cluster-2:5432 maxconn 500 backup&#xA;    server db-cluster-3-standby db-cluster-3:5432 maxconn 500 backup&#xA;EOF&#xA;systemctl restart haproxy&#xA;&#xA;Now we&#39;re going to install all the fun bits, and immediately disable them since they&#39;ll need some configuring first.&#xA;&#xA;apt install -y percona-patroni etcd etcd-server etcd-client percona-pgbackrest&#xA;systemctl stop {etcd,patroni,postgresql}&#xA;systemctl disable {etcd,patroni,postgresql}&#xA;&#xA;Also we&#39;ll remove the existing (default) Postgres folder... if this is a new server this should not be a problem, if you&#39;ve got an existing Postgres installed, what the hell are you thinking testing on this server!?&#xA;&#xA;rm -rf /var/lib/postgresql/15/main&#xA;&#xA;We need some token/passwords, so lets generate them now on any machine (even your own) run the following command (once):&#xA;&#xA;cat &lt;&lt;EOF&#xA;&#xA;Run these commands on each server&#xA;export DATADIR=/opt/data&#xA;export ETCDTOKEN=$(openssl rand -hex 16)&#xA;export REPLICATORPASS=$(openssl rand -hex 16)&#xA;export SUPERUSERPASS=$(openssl rand -hex 16)&#xA;export HOST=\$(hostname -s)&#xA;export INTERNALIP=\$(getent hosts \$(hostname -s) | grep -v &#39;^127.0.&#39; | cut -d \  -f 1)&#xA;echo &#34;I am \$HOST at \$INTERNALIP (please check)&#34;&#xA;EOF&#xA;&#xA;Copy the output of that and run it on all 3 servers.&#xA;&#xA;We need to create a Patroni config now so our servers will be able to start up later:&#xA;&#xA;cat &lt;EOF  /etc/patroni/patroni.yml&#xA;namespace: mycompany&#xA;scope: db-cluster&#xA;name: ${HOST}&#xA;&#xA;restapi:&#xA;    listen: 0.0.0.0:8008&#xA;    connectaddress: ${INTERNALIP}:8008&#xA;&#xA;etcd3:&#xA;    host: ${INTERNALIP}:2379&#xA;&#xA;bootstrap:&#xA;  # this section will be written into Etcd:/namespace/scope/config after initializing new cluster&#xA;  dcs:&#xA;      ttl: 30&#xA;      loopwait: 10&#xA;      retrytimeout: 10&#xA;      maximumlagonfailover: 1048576&#xA;&#xA;      postgresql:&#xA;          usepgrewind: true&#xA;          useslots: true&#xA;          parameters:&#xA;              wallevel: replica&#xA;              hotstandby: &#34;on&#34;&#xA;              walkeepsegments: 10&#xA;              maxwalsenders: 5&#xA;              maxreplicationslots: 10&#xA;              walloghints: &#34;on&#34;&#xA;              loggingcollector: &#39;on&#39;&#xA;              maxwalsize: &#39;10GB&#39;&#xA;              archivemode: &#34;on&#34;&#xA;              archivetimeout: 600s&#xA;              archivecommand: &#34;cp -f %p ${DATADIR}/archived/%f&#34;&#xA;&#xA;      recoveryconf:&#xA;            restorecommand: cp ${DATADIR}/archived/%f %p&#xA;&#xA;  # some desired options for &#39;initdb&#39;&#xA;  initdb: # Note: It needs to be a list (some options need values, others are switches)&#xA;      encoding: UTF8&#xA;      locale: enUS.UTF-8&#xA;      data-checksums&#xA;&#xA;postgresql:&#xA;    clustername: cluster1&#xA;    listen: 0.0.0.0:5432&#xA;    connectaddress: ${INTERNALIP}:5432&#xA;    datadir: ${DATADIR}/pg&#xA;    bindir: /usr/lib/postgresql/16/bin&#xA;    pgpass: /tmp/pgpass&#xA;    authentication:&#xA;        replication:&#xA;            username: replicator&#xA;            password: ${REPLICATORPASS}&#xA;        superuser:&#xA;            username: postgres&#xA;            password: ${SUPERUSERPASS}&#xA;    parameters:&#xA;        unixsocketdirectories: &#34;/var/run/postgresql/&#34;&#xA;    createreplicamethods:&#xA;        basebackup&#xA;    basebackup:&#xA;        checkpoint: &#39;fast&#39;&#xA;&#xA;    pghba:&#xA;      local all all  peer&#xA;      local replication all  peer&#xA;      host replication replicator 127.0.0.1/32 trust&#xA;      host replication replicator 0.0.0.0/0 scram-sha-256&#xA;      host all all 0.0.0.0/0 scram-sha-256&#xA;      host all all ::0/0 scram-sha-256&#xA;&#xA;    watchdog:&#xA;      mode: required # Allowed values: off, automatic, required&#xA;      device: /dev/watchdog&#xA;      safetymargin: 5&#xA;&#xA;tags:&#xA;    nofailover: false&#xA;    noloadbalance: false&#xA;    clonefrom: true&#xA;    nosync: false&#xA;EOF&#xA;&#xA;And we want to add a service to prep watchdog etc for Patroni.&#xA;&#xA;cat &lt;EOF  /etc/systemd/system/patroni-prep.service&#xA;[Unit]&#xA;Description=Prepare system for Patroni (softdog, watchdog, postgresql dirs)&#xA;Before=patroni.service&#xA;DefaultDependencies=no&#xA;After=local-fs.target&#xA;&#xA;[Service]&#xA;Type=oneshot&#xA;RemainAfterExit=yes&#xA;ExecStart=/bin/bash -c &#39;/usr/sbin/modprobe softdog; chown postgres /dev/watchdog; mkdir -p /var/run/postgresql; chown postgres /var/run/postgresql&#39;&#xA;&#xA;[Install]&#xA;WantedBy=multi-user.target&#xA;EOF&#xA;systemctl daemon-reload&#xA;systemctl enable patroni-prep&#xA;&#xA;One host at a time now:&#xA;&#xA;Up until now, we&#39;ve been running commands on all hosts (possibly in parallel), but now we&#39;re getting to the bootstrap part where things start deviating.&#xA;&#xA;db-cluster-1&#xA;&#xA;This is our seed server that will initialize and create our cluster. We want to initialize our etcd server here:&#xA;&#xA;cat &lt;EOF  /etc/etcd/etcd.conf.yaml&#xA;name: &#39;db-cluster-1&#39;&#xA;initial-cluster-token: ${ETCDTOKEN}&#xA;initial-cluster-state: new&#xA;initial-cluster: db-cluster-1=http://db-cluster-1:2380&#xA;data-dir: /var/lib/etcd&#xA;initial-advertise-peer-urls: http://db-cluster-1:2380&#xA;listen-peer-urls: http://0.0.0.0:2380&#xA;advertise-client-urls: http://db-cluster-1:2379&#xA;listen-client-urls: http://0.0.0.0:2379&#xA;&#xA;Storage quota (8GB = 8589934592 bytes)&#xA;quota-backend-bytes: 8589934592&#xA;&#xA;Enable automatic compaction every hour&#xA;auto-compaction-mode: periodic&#xA;auto-compaction-retention: &#34;1h&#34;&#xA;auto-defrag-interval: &#34;24h&#34;&#xA;EOF&#xA;sudo systemctl enable --now etcd&#xA;&#xA;After a few seconds lets run these 2 commands:&#xA;&#xA;etcdctl member list -w table&#xA;etcdctl endpoint status -w table&#xA;&#xA;You should see something like this (one member, and it&#39;s the leader):&#xA;root@db-cluster-1:~# etcdctl member list -w fields&#xA;&#34;ClusterID&#34; : 8919193014159237326&#xA;&#34;MemberID&#34; : 17956751917787781469&#xA;&#34;Revision&#34; : 0&#xA;&#34;RaftTerm&#34; : 2&#xA;&#34;ID&#34; : 17956751917787781469&#xA;&#34;Name&#34; : &#34;db-cluster-1&#34;&#xA;&#34;PeerURL&#34; : &#34;http://db-cluster-1:2380&#34;&#xA;&#34;ClientURL&#34; : &#34;http://db-cluster-1:2379&#34;&#xA;&#34;IsLearner&#34; : false&#xA;&#xA;root@db-cluster-1:~# etcdctl endpoint status -w fields&#xA;&#34;ClusterID&#34; : 8919193014159237326&#xA;&#34;MemberID&#34; : 17956751917787781469&#xA;&#34;Revision&#34; : 1&#xA;&#34;RaftTerm&#34; : 2&#xA;&#34;Version&#34; : &#34;3.5.24&#34;&#xA;&#34;DBSize&#34; : 20480&#xA;&#34;Leader&#34; : 17956751917787781469&#xA;&#34;IsLearner&#34; : false&#xA;&#34;RaftIndex&#34; : 4&#xA;&#34;RaftTerm&#34; : 2&#xA;&#34;RaftAppliedIndex&#34; : 4&#xA;&#34;Errors&#34; : []&#xA;&#34;Endpoint&#34; : &#34;127.0.0.1:2379&#34;&#xA;&#xA;We&#39;re now going to add our next member to this cluster so when they start up, the server will know them.&#xA;&#xA;etcdctl member add db-cluster-2 --peer-urls=http://db-cluster-2:2380&#xA;&#xA;db-cluster-2&#xA;&#xA;Lets now join our second etcd to this cluster...&#xA;&#xA;cat &lt;EOF  /etc/etcd/etcd.conf.yaml&#xA;name: &#39;db-cluster-2&#39;&#xA;initial-cluster-token: ${ETCDTOKEN}&#xA;initial-cluster-state: existing&#xA;initial-cluster: db-cluster-1=http://db-cluster-1:2380,db-cluster-2=http://db-cluster-2:2380&#xA;data-dir: /var/lib/etcd&#xA;initial-advertise-peer-urls: http://db-cluster-2:2380&#xA;listen-peer-urls: http://0.0.0.0:2380&#xA;advertise-client-urls: http://db-cluster-2:2379&#xA;listen-client-urls: http://0.0.0.0:2379&#xA;&#xA;Storage quota (8GB = 8589934592 bytes)&#xA;quota-backend-bytes: 8589934592&#xA;&#xA;Enable automatic compaction every hour&#xA;auto-compaction-mode: periodic&#xA;auto-compaction-retention: &#34;1h&#34;&#xA;auto-defrag-interval: &#34;24h&#34;&#xA;EOF&#xA;sudo systemctl enable --now etcd&#xA;&#xA;After a few seconds lets run these 2 commands:&#xA;&#xA;etcdctl member list -w table&#xA;etcdctl endpoint status -w table&#xA;&#xA;You should now see that there&#39;s 2 members, and presumably you&#39;re not the leader.&#xA;&#xA;We&#39;re now going to add our final member to this cluster, from db-cluster-2&#xA;&#xA;etcdctl member add db-cluster-3 --peer-urls=http://db-cluster-3:2380&#xA;&#xA;db-cluster-3&#xA;&#xA;Lets now join our third etcd to this cluster...&#xA;&#xA;cat &lt;EOF  /etc/etcd/etcd.conf.yaml&#xA;name: &#39;db-cluster-3&#39;&#xA;initial-cluster-token: ${ETCDTOKEN}&#xA;initial-cluster-state: existing&#xA;initial-cluster: db-cluster-1=http://db-cluster-1:2380,db-cluster-2=http://db-cluster-2:2380,db-cluster-3=http://db-cluster-3:2380&#xA;data-dir: /var/lib/etcd&#xA;initial-advertise-peer-urls: http://db-cluster-3:2380&#xA;listen-peer-urls: http://0.0.0.0:2380&#xA;advertise-client-urls: http://db-cluster-3:2379&#xA;listen-client-urls: http://0.0.0.0:2379&#xA;&#xA;Storage quota (8GB = 8589934592 bytes)&#xA;quota-backend-bytes: 8589934592&#xA;&#xA;Enable automatic compaction every hour&#xA;auto-compaction-mode: periodic&#xA;auto-compaction-retention: &#34;1h&#34;&#xA;auto-defrag-interval: &#34;24h&#34;&#xA;EOF&#xA;sudo systemctl enable --now etcd&#xA;&#xA;After a few seconds lets run these 2 commands:&#xA;&#xA;etcdctl member list -w table&#xA;etcdctl endpoint status -w table&#xA;&#xA;By this stage you should know what to expect.&#xA;&#xA;db-cluster-1&#xA;&#xA;Back on the first node, it&#39;s time to start up the very first Patroni instance (This will initialize the base database tables etc, and make the server the stand-alone primary).&#xA;&#xA;mkdir -p ${DATADIR}/archived&#xA;chown -R postgres:postgres ${DATADIR}&#xA;systemctl enable --now patroni&#xA;journalctl -f -u patroni&#xA;&#xA;Wait for journal to say something like no action. I am (db-cluster-1), the leader with the lock, then exit and run the following command:&#xA;&#xA;patronictl -c /etc/patroni/patroni.yml list&#xA;&#xA;You should get something that looks like:&#xA;Cluster: db-cluster (7593587474928070257) ---+----+-------------+-----+------------+-----+&#xA;| Member       | Host       | Role   | State   | TL | Receive LSN | Lag | Replay LSN | Lag |&#xA;+--------------+------------+--------+---------+----+-------------+-----+------------+-----+&#xA;| db-cluster-1 | 10.19.96.3 | Leader | running |  1 |             |     |            |     |&#xA;+--------------+------------+--------+---------+----+-------------+-----+------------+-----+&#xA;&#xA;db-cluster-2&#xA;&#xA;Run:&#xA;&#xA;mkdir -p ${DATADIR}/archived&#xA;chown -R postgres:postgres ${DATADIR}&#xA;systemctl enable --now patroni&#xA;journalctl -f -u patroni&#xA;&#xA;Wait for I am (db-cluster-2), a secondary, and following a leader. You can go back to the first server and watch patronictl list command to see progress.&#xA;&#xA;db-cluster-3&#xA;&#xA;Do the same as for db-cluster-2&#xA;&#xA;Testing the connection&#xA;&#xA;root@db-cluster-3:~# PGPASSWORD=$SUPERUSERPASS psql -h db-cluster-2 -p 5000  -U postgres \&#xA;  -c &#39;SELECT CURRENTUSER user, inetserveraddr() ip, inetserverport() port;&#39;&#xA;   user   |     ip     | port&#xA;----------+------------+------&#xA; postgres | 10.19.96.3 | 5432&#xA;(1 row)&#xA;&#xA;root@db-cluster-3:~# PGPASSWORD=$SUPERUSERPASS psql -h db-cluster-2 -p 5001  -U postgres \&#xA;  -c &#39;SELECT CURRENTUSER user, inetserveraddr() ip, inetserverport() port;&#39;&#xA;   user   |     ip     | port&#xA;----------+------------+------&#xA; postgres | 10.19.96.5 | 5432&#xA;(1 row)&#xA;&#xA;Job done&#xA;&#xA;That&#39;s pretty much it. From any server in the cluster you can manage the cluster using the patronictl command.]]&gt;</description>
      <content:encoded><![CDATA[<p>So I&#39;ve recently been quizzed on the exact process I use to install our Postgres cluster, and after telling everyone how easy it was, I was asked to explain the process.</p>

<h2 id="it-s-not-procrastination-it-s-something-else-i-swear">It&#39;s not procrastination, it&#39;s something else... I swear!</h2>

<p>Unfortunately I just have a bunch of embarrassing text files full of commands to run, so I decided it&#39;s about time I document it.
Perfect opportunity to install that federated personal blog I&#39;ve been thinking about for 6 months!
Except it doesn&#39;t work quite the way I want it to and doesn&#39;t support images or profile avatars...
Perfect opportunity to write an image hosting service that I can integrate with the blog software!
Except it doesn&#39;t count likes or show replies with my post...
Perfect opportunity to add the bits and pieces needed to track federated likes and replies!
Except now how do I let people who are seeing my blog post make likes and replies on their home instances?
Perfect opportunity to research URI scheme protocol handlers and redirector sites!
Except none of them work how I want them to work...
Perfect opportunity to design a new way to implement the draft protocol as a proof of concept/bootstrap project!
Except I promised to finish this article on the Patroni cluster thing by tonight.</p>

<p>Argh... it&#39;s tough living with my brain, I now have another 3 unfinished projects. I don&#39;t know how Ada puts up with it... she showed me this picture...
<img src="https://l8b5.c11.e2-2.dev/writemedia/2/2026/01/506631c6-b5b3-48.png" alt="distracted.png">
I hate that I resemble this so much.</p>

<p>Okay, so installing Patroni is really easy, writing about it requires much more effort.</p>

<h2 id="what-is-patroni">What is Patroni?</h2>

<p>This is a really good question and it gets to the heart of the matter.
Patroni is a Postgres cluster manager.
You give it a bunch of hosts and tell it to run a Postgres cluster on them, and it manages the whole thing. Kinda like how a RAID controller manages an array of (not-so-inexpensive) disks.
If there&#39;s no database there, it&#39;ll start it up, join the cluster, download a copy of the data, and begin replication.
If there&#39;s a database there but it gets wrecked, it&#39;ll automatically rebuild it for you.
We&#39;ll also install useful other bits of software like HAProxy which points a certain port at the current primary and another port at the secondary.
If you&#39;ve ever had the joy of using any of the many Kubernetes operators for Postgres, it&#39;s like that, but for bare metal. When you&#39;re working on a budget, sometimes you can&#39;t afford the overhead of Kubernetes. If this was a project for a client, I&#39;d probably steer them towards the self-healing nature of a Kubernetes cluster + operator.</p>

<h2 id="installing">Installing</h2>

<p>I&#39;m going to take you through the process of setting up a brand new cluster of 3 servers.
I&#39;ve got these servers on an internal network:
– db-cluster-1 10.19.96.3
– db-cluster-2 10.19.96.4
– db-cluster-3 10.19.96.5</p>

<h3 id="run-on-all-3-hosts">Run on all 3 hosts:</h3>

<p>As we&#39;re running Ubuntu, I&#39;m going to do a quick upgrade on them to get all the latest updates first.</p>

<pre><code class="language-bash">apt update &amp;&amp; apt upgrade -y &amp;&amp; reboot
</code></pre>

<p>Now it&#39;s time to make sure all the hosts know how to contact each other, even if/when DNS goes down.</p>

<pre><code class="language-bash">cat &lt;&lt;EOF &gt;&gt; /etc/hosts

# Database hosts
10.19.96.3 db-cluster-1
10.19.96.4 db-cluster-2
10.19.96.5 db-cluster-3
EOF

for i in 1 2 3; do
  ping -c 1 db-cluster-$i
done
</code></pre>

<p>If you&#39;re running a firewall (hopefully you are), let&#39;s open up some ports well need:</p>

<pre><code class="language-bash">for p in 2379 2380 8008; do
  ufw allow in proto tcp from 10.19.96.0/20 to any port $p
done
for p in 5000 5001; do
  ufw allow in proto tcp from any to any port $p
done
ufw status
</code></pre>

<p>NOTE: If you&#39;re putting a load balancer in front, you&#39;ll probably want to lock down the port 5000/5001 to just it, or otherwise just your application&#39;s network.</p>

<p>Let&#39;s now get Percona rocking. Percona is a Postgres database with extra optimizations, this is what we will control with our Patroni controller to turn into a cluster.</p>

<pre><code class="language-bash">curl -O https://repo.percona.com/apt/percona-release_latest.generic_all.deb
apt install -y gnupg2 lsb-release ./percona-release_latest.generic_all.deb
apt update
percona-release setup ppg-16
</code></pre>

<p>Now it&#39;s time to install our HAProxy software and configure it. This config will setup a proxy with 3 ports, the stats at port 7000, the primary at port 5000 and the standbys at port 5001.</p>

<p>The standbys will use the health check on <a href="http://localhost:8008/replica" rel="nofollow">http://localhost:8008/replica</a> which will return a 200 OK if that server is currently a replica node.</p>

<p>If there are no replicas available, then it falls back to any available node (even the primary) to service standby nodes as a fail safe so your applications that are configured to talk to a read node don&#39;t get locked out.</p>

<pre><code class="language-bash">apt install -y percona-haproxy
cat &lt;&lt;EOF &gt; /etc/haproxy/haproxy.cfg
global
    maxconn 500

defaults
    log global
    mode tcp
    retries 2
    timeout client 30m
    timeout connect 4s
    timeout server 30m
    timeout check 5s

listen stats
    mode http
    bind *:7000
    stats enable
    stats uri /

listen primary
    bind *:5000
    option httpchk /primary
    http-check expect status 200
    default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions
    server db-cluster-1 db-cluster-1:5432 maxconn 500 check port 8008
    server db-cluster-2 db-cluster-2:5432 maxconn 500 check port 8008
    server db-cluster-3 db-cluster-3:5432 maxconn 500 check port 8008

listen standbys
    balance roundrobin
    bind *:5001
    option httpchk /replica
    http-check expect status 200
    default-server inter 3s fall 3 rise 2 on-marked-down shutdown-sessions
    server db-cluster-1 db-cluster-1:5432 maxconn 500 check port 8008
    server db-cluster-2 db-cluster-2:5432 maxconn 500 check port 8008
    server db-cluster-3 db-cluster-3:5432 maxconn 500 check port 8008
    server db-cluster-1-standby db-cluster-1:5432 maxconn 500 backup
    server db-cluster-2-standby db-cluster-2:5432 maxconn 500 backup
    server db-cluster-3-standby db-cluster-3:5432 maxconn 500 backup
EOF
systemctl restart haproxy
</code></pre>

<p>Now we&#39;re going to install all the fun bits, and immediately disable them since they&#39;ll need some configuring first.</p>

<pre><code class="language-bash">apt install -y percona-patroni etcd etcd-server etcd-client percona-pgbackrest
systemctl stop {etcd,patroni,postgresql}
systemctl disable {etcd,patroni,postgresql}
</code></pre>

<p>Also we&#39;ll remove the existing (default) Postgres folder... if this is a new server this should not be a problem, if you&#39;ve got an existing Postgres installed, what the hell are you thinking testing on this server!?</p>

<pre><code class="language-bash">rm -rf /var/lib/postgresql/15/main
</code></pre>

<p>We need some token/passwords, so lets generate them now on any machine (even your own) run the following command (once):</p>

<pre><code class="language-bash">cat &lt;&lt;EOF

# Run these commands on each server
export DATA_DIR=/opt/data
export ETCD_TOKEN=$(openssl rand -hex 16)
export REPLICATOR_PASS=$(openssl rand -hex 16)
export SUPERUSER_PASS=$(openssl rand -hex 16)
export HOST=\$(hostname -s)
export INTERNAL_IP=\$(getent hosts \$(hostname -s) | grep -v &#39;^127.0.&#39; | cut -d \  -f 1)
echo &#34;I am \$HOST at \$INTERNAL_IP (please check)&#34;
EOF
</code></pre>

<p>Copy the output of that and run it on all 3 servers.</p>

<p>We need to create a Patroni config now so our servers will be able to start up later:</p>

<pre><code class="language-bash">cat &lt;&lt;EOF &gt; /etc/patroni/patroni.yml
namespace: mycompany
scope: db-cluster
name: ${HOST}

restapi:
    listen: 0.0.0.0:8008
    connect_address: ${INTERNAL_IP}:8008

etcd3:
    host: ${INTERNAL_IP}:2379

bootstrap:
  # this section will be written into Etcd:/&lt;namespace&gt;/&lt;scope&gt;/config after initializing new cluster
  dcs:
      ttl: 30
      loop_wait: 10
      retry_timeout: 10
      maximum_lag_on_failover: 1048576

      postgresql:
          use_pg_rewind: true
          use_slots: true
          parameters:
              wal_level: replica
              hot_standby: &#34;on&#34;
              wal_keep_segments: 10
              max_wal_senders: 5
              max_replication_slots: 10
              wal_log_hints: &#34;on&#34;
              logging_collector: &#39;on&#39;
              max_wal_size: &#39;10GB&#39;
              archive_mode: &#34;on&#34;
              archive_timeout: 600s
              archive_command: &#34;cp -f %p ${DATA_DIR}/archived/%f&#34;

      recovery_conf:
            restore_command: cp ${DATA_DIR}/archived/%f %p

  # some desired options for &#39;initdb&#39;
  initdb: # Note: It needs to be a list (some options need values, others are switches)
      - encoding: UTF8
      - locale: en_US.UTF-8
      - data-checksums

postgresql:
    cluster_name: cluster_1
    listen: 0.0.0.0:5432
    connect_address: ${INTERNAL_IP}:5432
    data_dir: ${DATA_DIR}/pg
    bin_dir: /usr/lib/postgresql/16/bin
    pgpass: /tmp/pgpass
    authentication:
        replication:
            username: replicator
            password: ${REPLICATOR_PASS}
        superuser:
            username: postgres
            password: ${SUPERUSER_PASS}
    parameters:
        unix_socket_directories: &#34;/var/run/postgresql/&#34;
    create_replica_methods:
        - basebackup
    basebackup:
        checkpoint: &#39;fast&#39;

    pg_hba:
      - local all all  peer
      - local replication all  peer
      - host replication replicator 127.0.0.1/32 trust
      - host replication replicator 0.0.0.0/0 scram-sha-256
      - host all all 0.0.0.0/0 scram-sha-256
      - host all all ::0/0 scram-sha-256

    watchdog:
      mode: required # Allowed values: off, automatic, required
      device: /dev/watchdog
      safety_margin: 5

tags:
    nofailover: false
    noloadbalance: false
    clonefrom: true
    nosync: false
EOF
</code></pre>

<p>And we want to add a service to prep watchdog etc for Patroni.</p>

<pre><code class="language-bash">cat &lt;&lt;EOF &gt; /etc/systemd/system/patroni-prep.service
[Unit]
Description=Prepare system for Patroni (softdog, watchdog, postgresql dirs)
Before=patroni.service
DefaultDependencies=no
After=local-fs.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/bin/bash -c &#39;/usr/sbin/modprobe softdog; chown postgres /dev/watchdog; mkdir -p /var/run/postgresql; chown postgres /var/run/postgresql&#39;

[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable patroni-prep
</code></pre>

<h3 id="one-host-at-a-time-now">One host at a time now:</h3>

<p>Up until now, we&#39;ve been running commands on all hosts (possibly in parallel), but now we&#39;re getting to the bootstrap part where things start deviating.</p>

<h4 id="db-cluster-1">db-cluster-1</h4>

<p>This is our seed server that will initialize and create our cluster. We want to initialize our etcd server here:</p>

<pre><code class="language-bash">cat &lt;&lt;EOF &gt; /etc/etcd/etcd.conf.yaml
name: &#39;db-cluster-1&#39;
initial-cluster-token: ${ETCD_TOKEN}
initial-cluster-state: new
initial-cluster: db-cluster-1=http://db-cluster-1:2380
data-dir: /var/lib/etcd
initial-advertise-peer-urls: http://db-cluster-1:2380
listen-peer-urls: http://0.0.0.0:2380
advertise-client-urls: http://db-cluster-1:2379
listen-client-urls: http://0.0.0.0:2379

# Storage quota (8GB = 8589934592 bytes)
quota-backend-bytes: 8589934592

# Enable automatic compaction every hour
auto-compaction-mode: periodic
auto-compaction-retention: &#34;1h&#34;
auto-defrag-interval: &#34;24h&#34;
EOF
sudo systemctl enable --now etcd
</code></pre>

<p>After a few seconds lets run these 2 commands:</p>

<pre><code class="language-bash">etcdctl member list -w table
etcdctl endpoint status -w table
</code></pre>

<p>You should see something like this (one member, and it&#39;s the leader):</p>

<pre><code>root@db-cluster-1:~# etcdctl member list -w fields
&#34;ClusterID&#34; : 8919193014159237326
&#34;MemberID&#34; : 17956751917787781469
&#34;Revision&#34; : 0
&#34;RaftTerm&#34; : 2
&#34;ID&#34; : 17956751917787781469
&#34;Name&#34; : &#34;db-cluster-1&#34;
&#34;PeerURL&#34; : &#34;http://db-cluster-1:2380&#34;
&#34;ClientURL&#34; : &#34;http://db-cluster-1:2379&#34;
&#34;IsLearner&#34; : false

root@db-cluster-1:~# etcdctl endpoint status -w fields
&#34;ClusterID&#34; : 8919193014159237326
&#34;MemberID&#34; : 17956751917787781469
&#34;Revision&#34; : 1
&#34;RaftTerm&#34; : 2
&#34;Version&#34; : &#34;3.5.24&#34;
&#34;DBSize&#34; : 20480
&#34;Leader&#34; : 17956751917787781469
&#34;IsLearner&#34; : false
&#34;RaftIndex&#34; : 4
&#34;RaftTerm&#34; : 2
&#34;RaftAppliedIndex&#34; : 4
&#34;Errors&#34; : []
&#34;Endpoint&#34; : &#34;127.0.0.1:2379&#34;
</code></pre>

<p>We&#39;re now going to add our next member to this cluster so when they start up, the server will know them.</p>

<pre><code class="language-bash">etcdctl member add db-cluster-2 --peer-urls=http://db-cluster-2:2380
</code></pre>

<h4 id="db-cluster-2">db-cluster-2</h4>

<p>Lets now join our second etcd to this cluster...</p>

<pre><code class="language-bash">cat &lt;&lt;EOF &gt; /etc/etcd/etcd.conf.yaml
name: &#39;db-cluster-2&#39;
initial-cluster-token: ${ETCD_TOKEN}
initial-cluster-state: existing
initial-cluster: db-cluster-1=http://db-cluster-1:2380,db-cluster-2=http://db-cluster-2:2380
data-dir: /var/lib/etcd
initial-advertise-peer-urls: http://db-cluster-2:2380
listen-peer-urls: http://0.0.0.0:2380
advertise-client-urls: http://db-cluster-2:2379
listen-client-urls: http://0.0.0.0:2379

# Storage quota (8GB = 8589934592 bytes)
quota-backend-bytes: 8589934592

# Enable automatic compaction every hour
auto-compaction-mode: periodic
auto-compaction-retention: &#34;1h&#34;
auto-defrag-interval: &#34;24h&#34;
EOF
sudo systemctl enable --now etcd
</code></pre>

<p>After a few seconds lets run these 2 commands:</p>

<pre><code class="language-bash">etcdctl member list -w table
etcdctl endpoint status -w table
</code></pre>

<p>You should now see that there&#39;s 2 members, and presumably you&#39;re not the leader.</p>

<p>We&#39;re now going to add our final member to this cluster, from db-cluster-2</p>

<pre><code class="language-bash">etcdctl member add db-cluster-3 --peer-urls=http://db-cluster-3:2380
</code></pre>

<h4 id="db-cluster-3">db-cluster-3</h4>

<p>Lets now join our third etcd to this cluster...</p>

<pre><code class="language-bash">cat &lt;&lt;EOF &gt; /etc/etcd/etcd.conf.yaml
name: &#39;db-cluster-3&#39;
initial-cluster-token: ${ETCD_TOKEN}
initial-cluster-state: existing
initial-cluster: db-cluster-1=http://db-cluster-1:2380,db-cluster-2=http://db-cluster-2:2380,db-cluster-3=http://db-cluster-3:2380
data-dir: /var/lib/etcd
initial-advertise-peer-urls: http://db-cluster-3:2380
listen-peer-urls: http://0.0.0.0:2380
advertise-client-urls: http://db-cluster-3:2379
listen-client-urls: http://0.0.0.0:2379

# Storage quota (8GB = 8589934592 bytes)
quota-backend-bytes: 8589934592

# Enable automatic compaction every hour
auto-compaction-mode: periodic
auto-compaction-retention: &#34;1h&#34;
auto-defrag-interval: &#34;24h&#34;
EOF
sudo systemctl enable --now etcd
</code></pre>

<p>After a few seconds lets run these 2 commands:</p>

<pre><code class="language-bash">etcdctl member list -w table
etcdctl endpoint status -w table
</code></pre>

<p>By this stage you should know what to expect.</p>

<h4 id="db-cluster-1-1">db-cluster-1</h4>

<p>Back on the first node, it&#39;s time to start up the very first Patroni instance (This will initialize the base database tables etc, and make the server the stand-alone primary).</p>

<pre><code class="language-bash">mkdir -p ${DATA_DIR}/archived
chown -R postgres:postgres ${DATA_DIR}
systemctl enable --now patroni
journalctl -f -u patroni
</code></pre>

<p>Wait for journal to say something like <code>no action. I am (db-cluster-1), the leader with the lock</code>, then exit and run the following command:</p>

<pre><code class="language-bash">patronictl -c /etc/patroni/patroni.yml list
</code></pre>

<p>You should get something that looks like:</p>

<pre><code>+ Cluster: db-cluster (7593587474928070257) ---+----+-------------+-----+------------+-----+
| Member       | Host       | Role   | State   | TL | Receive LSN | Lag | Replay LSN | Lag |
+--------------+------------+--------+---------+----+-------------+-----+------------+-----+
| db-cluster-1 | 10.19.96.3 | Leader | running |  1 |             |     |            |     |
+--------------+------------+--------+---------+----+-------------+-----+------------+-----+
</code></pre>

<h4 id="db-cluster-2-1">db-cluster-2</h4>

<p>Run:</p>

<pre><code class="language-bash">mkdir -p ${DATA_DIR}/archived
chown -R postgres:postgres ${DATA_DIR}
systemctl enable --now patroni
journalctl -f -u patroni
</code></pre>

<p>Wait for <code>I am (db-cluster-2), a secondary, and following a leader</code>. You can go back to the first server and watch patronictl list command to see progress.</p>

<h4 id="db-cluster-3-1">db-cluster-3</h4>

<p>Do the same as for db-cluster-2</p>

<h2 id="testing-the-connection">Testing the connection</h2>

<pre><code>root@db-cluster-3:~# PGPASSWORD=$SUPERUSER_PASS psql -h db-cluster-2 -p 5000  -U postgres \
&gt; -c &#39;SELECT CURRENT_USER user, inet_server_addr() ip, inet_server_port() port;&#39;
   user   |     ip     | port
----------+------------+------
 postgres | 10.19.96.3 | 5432
(1 row)

root@db-cluster-3:~# PGPASSWORD=$SUPERUSER_PASS psql -h db-cluster-2 -p 5001  -U postgres \
&gt; -c &#39;SELECT CURRENT_USER user, inet_server_addr() ip, inet_server_port() port;&#39;
   user   |     ip     | port
----------+------------+------
 postgres | 10.19.96.5 | 5432
(1 row)
</code></pre>

<h2 id="job-done">Job done</h2>

<p>That&#39;s pretty much it. From any server in the cluster you can manage the cluster using the <code>patronictl</code> command.</p>
]]></content:encoded>
      <author>supakaity</author>
      <guid>https://pen.blahaj.zone/read/a/xfb369it0e</guid>
      <pubDate>Sat, 10 Jan 2026 02:05:13 +0000</pubDate>
    </item>
    <item>
      <title>Pen testing</title>
      <link>https://pen.blahaj.zone/supakaity/pen-testing</link>
      <description>&lt;![CDATA[Pun... intended. Ada told me if the first post on this site isn&#39;t titled &#34;Pen Testing&#34;, we&#39;ll be getting divorced or something like that. It may have just been abject disappointment in me; same thing really!&#xA;&#xA;Anyhow, welcome to the latest mini project in the Blåhaj line of projects. This one is a blog! No, no, no... not like a global fedi-micro-blog-feed-roll thing like Mastodon, Misskey or Sharkey. A personal blog.&#xA;&#xA;You see the thing with microblogs is all your useless musings get lost in time amongst all the other useless musings of all the other random people out there. This site is more about creating a permanent home for your most treasured, slightly less than completely useless ramblings. Where you can pin them up on the internet and be mildly proud of how clever you are and point your friends at them proudly.&#xA;&#xA;Think of this as a federation-first version of Medium, Wordpress or Ghost, all of which are nominally federable, however for them it&#39;s more of a tack-on &#34;look we did federation, more money now?&#34; type deal.&#xA;&#xA;Anyhow we hope you&#39;ll enjoy being here, posting things, reading stuff from other like minded individuals, and will be proud to call this place home.]]&gt;</description>
      <content:encoded><![CDATA[<p>Pun... intended. Ada told me if the first post on this site isn&#39;t titled “Pen Testing”, we&#39;ll be getting divorced or something like that. It may have just been abject disappointment in me; same thing really!</p>

<p>Anyhow, welcome to the latest mini project in the Blåhaj line of projects. This one is a blog! No, no, no... not like a global fedi-micro-blog-feed-roll thing like Mastodon, Misskey or Sharkey. A <strong>personal blog</strong>.</p>

<p>You see the thing with microblogs is all your useless musings get lost in time amongst all the other useless musings of all the other random people out there. This site is more about creating a permanent home for your most treasured, slightly less than completely useless ramblings. Where you can pin them up on the internet and be mildly proud of how clever you are and point your friends at them proudly.</p>

<p>Think of this as a federation-first version of Medium, Wordpress or Ghost, all of which are nominally federable, however for them it&#39;s more of a tack-on “look we did federation, more money now?” type deal.</p>

<p>Anyhow we hope you&#39;ll enjoy being here, posting things, reading stuff from other like minded individuals, and will be proud to call this place home.</p>
]]></content:encoded>
      <author>supakaity</author>
      <guid>https://pen.blahaj.zone/read/a/dsgjv2w8fv</guid>
      <pubDate>Thu, 08 Jan 2026 11:45:54 +0000</pubDate>
    </item>
  </channel>
</rss>