<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Dondon Developments</title><description>A digital garden space for me to share writing, photos, musings, tutorial, and educational materials</description><link>https://dondon.dev</link><item><title>Journal Review #1</title><link>https://dondon.dev/cultivated-thoughtz/2026-02-16-journal-review</link><guid isPermaLink="true">https://dondon.dev/cultivated-thoughtz/2026-02-16-journal-review</guid><description>A collection of common themes and ideas of interest from my analog journal</description><content:encoded>&lt;ul&gt;
&lt;li&gt;[ ] Start making zines
&lt;ul&gt;
&lt;li&gt;[ ] Make one about Edward Bernays because that guy is terrible and relevant to current terribleness&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;[ ] draw more&lt;/li&gt;
&lt;li&gt;Fuck YouTube&lt;/li&gt;
&lt;li&gt;[ ] #seed Make content about being a Staff+ Software Developer/Engineer&lt;/li&gt;
&lt;li&gt;[ ] Make more videos -&amp;gt; which is to say make ANY videos&lt;/li&gt;
&lt;li&gt;[ ] #seed What exactly is TLS?&lt;/li&gt;
&lt;li&gt;[ ] #project Add fake advertising to this website
&lt;ul&gt;
&lt;li&gt;This seems like a fun idea and a good way to make fun/silly art&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;[ ] #seed Core Web Vitals&lt;/li&gt;
&lt;li&gt;Calisthenics is awesome&lt;/li&gt;
&lt;li&gt;&quot;Bias For Action&quot; is a term I heard that I like and I think sounds like a Street Wear brand&lt;/li&gt;
&lt;li&gt;Being a Renaissance Man does not mean being a Jack of all trades
&lt;ul&gt;
&lt;li&gt;Figure out what hobbies you actually enjoy and where you want to dedicate your time so that you actually make progress&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;At the end of January, I moved down 75lbs -&amp;gt; 60lbs on assisted dips/chin-ups
&lt;ul&gt;
&lt;li&gt;I promptly moved back up when I started doing actual pull-ups instead&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;I have been using notebooks more and it&apos;s fantastic
&lt;ul&gt;
&lt;li&gt;Less &quot;polished content&quot;, more thinking on paper&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&quot;My home office is just an elaborate anti-productivity machine&quot;
&lt;ul&gt;
&lt;li&gt;This is a realization I had before I Marie Kondoed my office&lt;/li&gt;
&lt;li&gt;It probably still has some room to be improved but I&apos;ve actually been much more productive in this space since realizing I manifested ADHD in a room&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;I am realizing that I never developed healthy work habits
&lt;ul&gt;
&lt;li&gt;This sucks to realize at 38yo&lt;/li&gt;
&lt;li&gt;But better late than never&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The Dissect Podcast is phenomenal
&lt;ul&gt;
&lt;li&gt;Especially the season dedicated to MF DOOM&lt;/li&gt;
&lt;li&gt;Listen to it again whenever you see this&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;MF DOOM is a fucking genius&lt;/li&gt;
&lt;li&gt;Spending is a problem for me
&lt;ul&gt;
&lt;li&gt;I really like stuff I already have a lot of like multitools and knives&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;I remembered a blog that I used to frequent: &lt;a href=&quot;http://www.them-thangs.com&quot;&gt;Them Thangs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;There is intrinsic value in making art, even if it just makes you smile&lt;/li&gt;
&lt;li&gt;Taking photos just to compose a good shot is so rewarding&lt;/li&gt;
&lt;li&gt;Consume higher quality media
&lt;ul&gt;
&lt;li&gt;Cheap dopamine is bullshit&lt;/li&gt;
&lt;li&gt;Fuck social media&lt;/li&gt;
&lt;li&gt;Fuck YouTube&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;I&apos;ve been on a journey to make my phone dumber
&lt;ul&gt;
&lt;li&gt;One area that was silently still sapping attention was having a search engine literally at my finger tips&lt;/li&gt;
&lt;li&gt;Make using the internet on your phone clunky if you also have this problem&lt;/li&gt;
&lt;li&gt;You don&apos;t need to answer every question that you have when you have it -&amp;gt; sometimes not at all&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;[ ] Read more books about telling stories&lt;/li&gt;
&lt;li&gt;[ ] Listen to the Moth again&lt;/li&gt;
&lt;li&gt;[ ] Journal when you find yourself mindlessly navigating to YT
&lt;ul&gt;
&lt;li&gt;[ ] talk about the stuff you would click on and then reflect on how stupid that is&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Peanut Butter Wolf&lt;/li&gt;
&lt;li&gt;#seed binaries + spectra&lt;/li&gt;
&lt;li&gt;Mndsgn is a musician I found that is v good&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://thelibraryofesoterica.com&quot;&gt;Library of Esoterica&lt;/a&gt; -&amp;gt; SO GOOD
&lt;ul&gt;
&lt;li&gt;The website is awesome too!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;[ ] #seed write longform on my personal thoughts on religion&lt;/li&gt;
&lt;li&gt;YT is a content machine
&lt;ul&gt;
&lt;li&gt;it turns attention into revenue&lt;/li&gt;
&lt;li&gt;It is NOT inspiration&lt;/li&gt;
&lt;li&gt;it IS an entertainment product&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;I very much want to make stickers and t-shirts and &quot;merch&quot; again
&lt;ul&gt;
&lt;li&gt;I used to have a screen printer and make stupid t-shirts in college&lt;/li&gt;
&lt;li&gt;I want to do this again in some capacity&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Learn how to be a photographer again
&lt;ul&gt;
&lt;li&gt;My degree is in photography and I don&apos;t do anything with it anymore&lt;/li&gt;
&lt;li&gt;I miss how I used to use a camera to understand things&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Components, Data Layers, and the Adapter Pattern</title><link>https://dondon.dev/seeds/pre-component-mutation-layers</link><guid isPermaLink="true">https://dondon.dev/seeds/pre-component-mutation-layers</guid><content:encoded>&lt;h2&gt;Rambling Thesis Statement&lt;/h2&gt;
&lt;p&gt;Recently I&apos;ve been thinking about the importance of Component Design with regard to React/NextJS projects. But I think conceptually, this extends to any project that is component based. When you are developing components for an app, there is almost always some data layer that is providing you content. &lt;em&gt;Usually&lt;/em&gt; This comes in the form of some REST API request that returns you some JSON shape that you then plug into a component. What I have very recently conceptually considered, with respect to this relationship, is the Adapter Pattern. This should, in my opinion, ALWAYS come into play when building in this fashion. You should always be thinking of the props of your component as a public interface. The props should describe what the component can do, the component should not be altered to accommodate the props. There should be a layer between the data coming in and the component itself that should be doing the job of making the data fit the component. This is the Adapter Pattern.&lt;/p&gt;
&lt;h2&gt;The Adapter Pattern&lt;/h2&gt;
&lt;p&gt;Instead of giving an in depth explanation on my own, I encourage you to dig into this article instead that does a fantastic job of explaining the Adapter Pattern: &lt;a href=&quot;https://www.geeksforgeeks.org/system-design/adapter-pattern/&quot;&gt;Geeks For Geeks: Adapter Design Pattern&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Example&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Q: This all sounds like you know a whole lot about tech Donny. But what the fuck are you talking about?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I&apos;m glad I asked! I captured this thought so that I would later elaborate on it and now I am just 5 short months later. Let&apos;s organize the problem a bit more and hopefully make more sense of this word soup.&lt;/p&gt;
&lt;h2&gt;The Problem&lt;/h2&gt;
&lt;p&gt;It is really easy to take the type of an API response and plug it directly into a given component as the props:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// ❌ BEFORE: Component tightly coupled to the API response shape

// The API response — you don&apos;t own this, it can change
type ApiProduct = {
  product_id: string;
  display_name: string;
  base_price_cents: number;
  discount_bps: number;        // basis points, e.g. 500 = 5%
  media: { src: string; alt_text: string }[];
  inventory: { in_stock: boolean; qty_remaining: number };
};

// The component consumes the API shape directly — now they&apos;re glued together
function ProductBanner({ product_id, display_name, base_price_cents, discount_bps, media, inventory }: ApiProduct) {
  const price = (base_price_cents / 100).toFixed(2);
  const discount = (discount_bps / 100).toFixed(0);
  const image = media[0];

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;img src={image.src} alt={image.alt_text} /&amp;gt;
      &amp;lt;h2&amp;gt;{display_name}&amp;lt;/h2&amp;gt;
      &amp;lt;p&amp;gt;${price} — {discount}% off&amp;lt;/p&amp;gt;
      {!inventory.in_stock &amp;amp;&amp;amp; &amp;lt;span&amp;gt;Out of stock&amp;lt;/span&amp;gt;}
    &amp;lt;/div&amp;gt;
  );
}

// The problem: if the API renames `display_name` to `title`, or changes
// `base_price_cents` to `price_usd`, your component breaks. The business
// logic (cents → dollars, basis points → %) is also leaking into the UI.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As outlined, this is bad because we have a contract in our codebase that relies on code that we don&apos;t maintain. This is a gigantic red flag.&lt;/p&gt;
&lt;h2&gt;The Solution&lt;/h2&gt;
&lt;p&gt;Instead, we should implement the Adapter Pattern, add a mutation layer to our code, and create a solid interface that describes our component as we expect it to be used.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// ✅ AFTER: Adapter pattern decouples the API from the component

// 1. The API contract — models exactly what the API returns
type ApiProduct = {
  product_id: string;
  display_name: string;
  base_price_cents: number;
  discount_bps: number;
  media: { src: string; alt_text: string }[];
  inventory: { in_stock: boolean; qty_remaining: number };
};

// 2. The component contract — models what the UI actually needs
type ProductBannerProps = {
  id: string;
  name: string;
  formattedPrice: string;       // &quot;$49.99&quot;
  discountPercent: number;      // 5
  image: { src: string; alt: string };
  availability: &quot;in_stock&quot; | &quot;out_of_stock&quot;;
};

// 3. The adapter — owns the mutation logic between the two contracts
function adaptApiProductToBannerProps(product: ApiProduct): ProductBannerProps {
  return {
    id: product.product_id,
    name: product.display_name,
    formattedPrice: `$${(product.base_price_cents / 100).toFixed(2)}`,
    discountPercent: product.discount_bps / 100,
    image: {
      src: product.media[0].src,
      alt: product.media[0].alt_text,
    },
    availability: product.inventory.in_stock ? &quot;in_stock&quot; : &quot;out_of_stock&quot;,
  };
}

// 4. The component — clean, readable, knows nothing about the API
function ProductBanner({ name, formattedPrice, discountPercent, image, availability }: ProductBannerProps) {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;img src={image.src} alt={image.alt} /&amp;gt;
      &amp;lt;h2&amp;gt;{name}&amp;lt;/h2&amp;gt;
      &amp;lt;p&amp;gt;{formattedPrice} — {discountPercent}% off&amp;lt;/p&amp;gt;
      {availability === &quot;out_of_stock&quot; &amp;amp;&amp;amp; &amp;lt;span&amp;gt;Out of stock&amp;lt;/span&amp;gt;}
    &amp;lt;/div&amp;gt;
  );
}

// 5. The call site — adapter runs at the boundary, right after the fetch
async function Page() {
  const data: ApiProduct = await fetch(&quot;/api/products/1&quot;).then(r =&amp;gt; r.json());
  const props = adaptApiProductToBannerProps(data);
  return &amp;lt;ProductBanner {...props} /&amp;gt;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Hopefully this now makes more sense! And now you have a real world example that you can use to discuss a design pattern!&lt;/p&gt;
</content:encoded></item><item><title>Tmux: Getting Started</title><link>https://dondon.dev/seeds/tmux</link><guid isPermaLink="true">https://dondon.dev/seeds/tmux</guid><content:encoded>&lt;h2&gt;What is a TMUX?&lt;/h2&gt;
&lt;p&gt;Tmux is pretty awesome, I&apos;ve heard about it for a long time, and I finally am taking an hour to learn it. If I would have known it was this quick, I would have just learned it forever ago because it is really useful. Tmux is a multiplexer which means nothing because nobody knows what a multiplexer is so it doesn&apos;t give you any reference for what it does. What is a multiplexer? The internet (AI bot) says this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A multiplexer (often abbreviated mux) is a digital circuit that selects one of several input signals and forwards the chosen input to a single output line.&lt;/p&gt;
&lt;p&gt;In essence, it works like a multiple‑to‑single switch controlled by a set of select lines (also called address or control bits). The number of select lines determines how many inputs can be addressed:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is actually helpful with regard to Tmux since Tmux essentially allows you to work with multiple sessions, windows, and panes inside of your terminal environment. So instead of having one terminal window and a bunch of tabs that are hard to navigate around, Tmux gives you a similar performance, allowing you to manage multiple windows, with some really useful commands that make it really easy to do so. The concept of sessions is really cool too because you could do something like run a server, exit (close) the window, and still have access to your running server. This is cool and you should do it.&lt;/p&gt;
&lt;h2&gt;Tmux Elements&lt;/h2&gt;
&lt;h3&gt;Sessions&lt;/h3&gt;
&lt;p&gt;The relationship between sessions, windows, and panes is pretty simple, but here&apos;s a general overview. Sessions are top level. Anything you do in Tmux is gonna happen in a session. These are similar to browser sessions. It&apos;s essentially the 5W&apos;s of whatever you&apos;re doing. Who: you, What: typing stuff: When: now (and later maybe), Where: some file system, Why: Because your life is dope and you do dope shit. Windows&lt;/p&gt;
&lt;h3&gt;Windows&lt;/h3&gt;
&lt;p&gt;Windows are where work actually happens. You can think of windows as individual terminal windows since that is what they are. If you didn&apos;t use Tmux, these would be tabs or multiple terminal windows.&lt;/p&gt;
&lt;h3&gt;Panes&lt;/h3&gt;
&lt;p&gt;Panes are windows inside of windows. Panes allow you to split a screen (window) and perform multiple tasks. I can see where this might be useful, but I think just having multiple windows is gonna suffice for me.&lt;/p&gt;
&lt;h2&gt;Keyboard Shortcuts&lt;/h2&gt;
&lt;p&gt;There are a bunch of cool shortcuts in Tmux because, obviously there are. That&apos;s what makes it useful. Here are some of the really useful ones based on what they correspond to.&lt;/p&gt;
&lt;p&gt;One important thing to note, Tmux relies on a &quot;prefix&quot; for it&apos;s keyboard shortcuts. This is to prevent collision between Tmux&apos;s shortcuts and other terminal shortcuts. The default prefix is &lt;code&gt;ctrl + b&lt;/code&gt; but you can change this if you would like. I don&apos;t like so it&apos;s just &lt;code&gt;ctrl + b&lt;/code&gt; for me.&lt;/p&gt;
&lt;h3&gt;Windows&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Create a new window - &lt;code&gt;&amp;lt;prefix&amp;gt; + c&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Cycle between previous and next windows respectively - &lt;code&gt;&amp;lt;prefix&amp;gt; + p/n&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Choose a specific window - &lt;code&gt;&amp;lt;prefix&amp;gt; + [index]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The index will be next to the name of the window in the bottom bar&lt;/li&gt;
&lt;li&gt;List all windows - &lt;code&gt;&amp;lt;prefix&amp;gt; + w&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Rename a window - &lt;code&gt;&amp;lt;prefix&amp;gt; + ,&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Panes&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Split screen horizontal - &lt;code&gt;&amp;lt;prefix&amp;gt; + &quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Split screen vertically - &lt;code&gt;&amp;lt;prefix&amp;gt; + %&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Move around panes - &lt;code&gt;&amp;lt;prefix&amp;gt; + [arrow keys]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Cycle through panes - &lt;code&gt;&amp;lt;prefix&amp;gt; + o&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;close a pane - &lt;code&gt;&amp;lt;prefix&amp;gt; + x&lt;/code&gt; or type &lt;code&gt;exit&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;rearrange panes - &lt;code&gt;&amp;lt;prefix&amp;gt; + SPACE&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Commands&lt;/h2&gt;
&lt;p&gt;Tmux also has built in commands. These are really useful for scripting. Scripting is awesome. You should do that too. Also use NeoVim with Lua. Anyway, to start command mode, type &lt;code&gt;&amp;lt;prefix&amp;gt; + :&lt;/code&gt; then you can type stuff like &lt;code&gt;list-windows&lt;/code&gt; and Tmux will list all windows in this session or &lt;code&gt;split-windows&lt;/code&gt; with the &lt;code&gt;-v/-h&lt;/code&gt; flag for vertical or horizontal. There are more. I will not list them.&lt;/p&gt;
&lt;h2&gt;Configuration&lt;/h2&gt;
&lt;p&gt;You can add a Tmux configuration file and you want to do this. Add a configuration file at &lt;code&gt;~/.config/tmux/tmux.conf&lt;/code&gt;.&lt;/p&gt;
</content:encoded></item><item><title>NeoVim Thoughtz</title><link>https://dondon.dev/seeds/nvim</link><guid isPermaLink="true">https://dondon.dev/seeds/nvim</guid><content:encoded>&lt;h2&gt;Inserting Characters with Visual Block&lt;/h2&gt;
&lt;p&gt;I recently wanted to prepended dashes to a couple of lines to turn this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Structure and Interpretation of Computer Programs by Gerald Jay Sussman
Computer Systems: A Programmer’s Perspective by Randal E. Bryant
Designing Data-Intensive Applications by Martin Kleppmann
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;into this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;- Structure and Interpretation of Computer Programs by Gerald Jay Sussman
- Computer Systems: A Programmer’s Perspective by Randal E. Bryant
- Designing Data-Intensive Applications by Martin Kleppmann
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And I super forgot how. Here&apos;s a quick guide for when I forget again.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Enter &lt;code&gt;VISUAL BLOCK&lt;/code&gt; - &lt;code&gt;ctrl + v&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;select rows - &lt;code&gt;j/k&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Enter VB &lt;code&gt;INSERT&lt;/code&gt; - &lt;code&gt;shift + I&lt;/code&gt; (THIS IS WHAT GOT ME! CAPITAL I!)&lt;/li&gt;
&lt;li&gt;Enter characters - &lt;code&gt;- &lt;/code&gt; in this case&lt;/li&gt;
&lt;li&gt;Indicate that you are finished - &lt;code&gt;esc&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;That&apos;s it! Your prepend is applied to all lines!&lt;/p&gt;
</content:encoded></item><item><title>TypeScript Patterns</title><link>https://dondon.dev/seeds/typescript-patterns</link><guid isPermaLink="true">https://dondon.dev/seeds/typescript-patterns</guid><content:encoded>&lt;p&gt;I recently read a &lt;a href=&quot;https://nagibaba.medium.com/typescript-patterns-that-made-my-code-self-documenting-3c0fe8bcd002&quot;&gt;very good article&lt;/a&gt; discussing TypeScript Patterns that &quot;self-document&quot; your code. There is some really good stuff here and this is definitely something that I&apos;ll be digging deeper into. One of the concepts that really stood out is the idea of &quot;branding&quot; types in TS. This is not something that I have seen before but I think it is a really good idea. It doesn&apos;t do much for the code itself but it makes things more readable as far as intent for developers.&lt;/p&gt;
&lt;h2&gt;Branded Types&lt;/h2&gt;
&lt;p&gt;This is largely superfluous as it doesn&apos;t change anything about how the code functions. But it labels things better. The article does a good job of illustrating exactly how this works so I will give a quick example but then talk more about what is happening.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;type UserBirthdate = Date &amp;amp; { readonly __brand: &apos;UserBirthdate&apos; };
type UserEmail = string &amp;amp; { readonly __brand: &apos;UserEmail&apos; };
type UserName = string &amp;amp; { readonly __brand: &apos;UserName&apos; };

interface User {
  birthdate: UserBirthdate;
  email: UserEmail;
  name: UserName;
}

const user1: User = {
  birthdate: new Date(&apos;3056-08-08&apos;),
  email: &apos;me@dondon.dev&apos;,
  name: &apos;Dondon&apos;,
};
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Thought Work Organization Strategy</title><link>https://dondon.dev/seeds/personal-work-organization-strategy</link><guid isPermaLink="true">https://dondon.dev/seeds/personal-work-organization-strategy</guid><content:encoded>&lt;p&gt;I have been feeling a lot more productive lately. I feel like that is thanks to nailing down a more structured approach to thinking externally. Both on paper and in digital spaces. I wanted to get a seed started for this because I think that it is going to continue to grow as it gets more use.&lt;/p&gt;
&lt;p&gt;I&apos;ve been actively trying to make my daily notebooks more useful instead of just being a glorified journal. I can&apos;t overstate how much I value journaling. So even if that was the only use for it, it&apos;s still plenty valuable. But I&apos;ve gotten a lot better in recent months about making various lists and taking fleeting notes just to get thoughts out of my head and on paper. This has proved to be crazy useful just in and of itself. Writing, I&apos;m learning, has so many benefits even if the only thing you do is write the things that you&apos;re thinking. But, by following the process that I&apos;ll describe next, it becomes infinitely more useful.&lt;/p&gt;
&lt;p&gt;My current process is as follows:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Fleeting Note Capture - For this I have two notebooks. One is a big A4 sized notebook that I take active time to sit down and write in. The second is a pocket-sized notebook that doubles as a wallet. I use both of these to varying degrees to write down pretty much anything that comes into my head. Even if it&apos;s just something that I want to remember to do later. Sometimes the things that I write in either of these books is valuable and I either expand on whatever I wrote right there in the notebook or I migrate it to step two immediately. Either way, when I find value in a fleeting note, it eventually makes it&apos;s way to step 2. A lot of fleeting notes never make it past step 1 though and that&apos;s ok. I&apos;ve learned that most of this process is about revising and removing.&lt;/li&gt;
&lt;li&gt;Permanent Notes - I&apos;m very much in the beginnings of adoption with this step. But once you start doing it, you see the benefits immediately. Once I can really visualize a fleeting note in the context of other notes from my day, especially if that note is about a book or an article or with relevance to something important, I can distill it and rewrite it into something more permanent. In this step, I can also relate it to other notes by linking it. This step is made way easier by using a digital counterpart. I use Obsidian but there are other tools out there. I prefer Obsidian because I watched a bunch of videos about Zettelkasten before I had any sort of structure or practice with taking notes and I wanted to be cool and use what all of the other cool people were using to take notes. Having used it for a while now, though, I really do appreciate the way that it works. I think the biggest caveat for me for a digital note system is Markdown though. I use markdown for every piece of digital writing I do unless I am absolutely forced to use something else. Markdown is awesome because, as a software developer, it follows me everywhere. I can use it in Git and GitHub, Obsidian, my personal website, Slack, Confluence, NextCloud, etc. You get the picture. It really is a write once, use everywhere solution for me. The more I can avoid context switching, the more I can focus on the information instead of the process.&lt;/li&gt;
&lt;li&gt;Artifact Creation - One issue that I ran into with Obsidian in my early attempts at note taking was digital clutter. Now as a high-level concept, good luck with removing the cluttered feeling entirely. If you are writing and recording enough to make anything useful, you are almost definitely going to have a bunch of notes and artifacts in various stages of complete. I&apos;m honestly starting to embrace that as part of the process. Figuring out how to organize the things that I make helps me organize how I think about them a lot of times. This is actually kind of a core tenet of the Zettelkasten system. Anyway, the problem I needed to solve for this step was removing artifacts that aren&apos;t notes from Obsidian thus giving me a clear boundary for resources to aid in writing and the written assets themselves. For this I&apos;m using NextCloud. Bonus nerd points because I self-host my NextCloud instance (Long Live Digital Autonomy).&lt;/li&gt;
&lt;li&gt;Dissemination - Some stuff actually is functional enough that I want to share it. At this point, I&apos;m using the thing that you&apos;re looking at right now if you are not me and you are reading this, my personal website. This is where using markdown through the whole process really shines. I use AstroJS (at least as of the time I&apos;m writing this) to host my content. AstroJS uses markdown to process content. I&apos;m sure I could make my site way more complicated and add an API layer and a data layer and make expensive fetches to get my assets but I&apos;m a simple man with simple taste. I like markdown and you can go fuck yourself if you think I need all of that other business to maintain a successful digital presence.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I&apos;m really happy to have a system in place to help me manage the things that I think about because I have a lot of different topics that I really enjoy pursuing and for far too long I have just forgotten things that I think are really cool and probably could have proved to be useful in some way. With this sort of a system in place, I can literally work with my thoughts in a more tangible way and that helps me feel better. I hope that if you are reading this, I have given you a path to do the same and hopefully saved you some measure of time because I think it is important to know what you think and to do something with it. I wasted far too much time keeping everything in the fleeting step one phase and I think I probably lost a lot of good ideas to time. But now I don&apos;t lose track of the things that I care about and you don&apos;t have to either. So best of luck. And if this isn&apos;t something that interests you, thanks for reading! Just forget that you read it anyway. Just kidding sort of...&lt;/p&gt;
</content:encoded></item><item><title>Working With AI Tools</title><link>https://dondon.dev/seeds/working-with-ai-tools</link><guid isPermaLink="true">https://dondon.dev/seeds/working-with-ai-tools</guid><content:encoded>&lt;p&gt;I&apos;ve recently been working a lot more with Claude Sonnet 4. I have a lot of conflicting feelings about AI. But I have been working with this tool in an effort to understand exactly what it does well and see if there is anything beneficial that I can incorporate into my workflow. It turns out, I have definitely found useful applications. I&apos;m going to list anything I find useful here.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;I have been using Claude Sonnet 4 as sort of a glorified search engine. Most recently, I have been trying to use Obsidian more effectively. I have been trying to use Obsidian as a complementary tool to my analog notebooks. I ran up against an issue where Obsidian was becoming more of a hindrance than a helper. I was using the daily notes feature of Obsidian. The problem is that I started to feel obligated to fill out my daily note, which had grown quite lengthy with &quot;helpful&quot; sections. It got to the point that I was taking time away from more productive efforts to keep my daily note streak going. Once I realized that this is what I was actually doing, I abandoned the digital note platform all together. I was actually able to have a conversation with Claude and develop a new strategy for using Obsidian along side my analog notes system as well as an all new Obsidian daily note template. I count this as a beneficial use case.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Artifacts&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/cultivated-thoughtz/my-obsidian-methodology/&quot;&gt;My Obsidian + Analog Journal Methodology&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;New Obsidian Daily Note Template&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# &amp;lt;% tp.date.now(&quot;YYYY-MM-DD&quot;) %&amp;gt; - &amp;lt;% tp.date.now(&quot;dddd&quot;) %&amp;gt;

## 📊 Habits

| Habit             | ✓   | Notes |
| ----------------- | --- | ----- |
| Exercise          |     |       |
| Reading           |     |       |
| Water (8 glasses) |     |       |
| Sleep (7+ hours)  |     |       |
| Zettelkasten work |     |       |

## 🔗 Digital Thoughts

_Quick captures when I&apos;m already here_

## 📝 From My Journal

## _Key insights worth linking/connecting later_

## 🎯 Today&apos;s Intention

_One simple focus_

## 📋 Logs

- _Notes started today_

---

**Quick Links:** [[Yesterday|←]] | [[Tomorrow|→]] | [[Weekly Review]]

&amp;lt;% tp.date.now(&quot;yyyyMMDDHHmmss&quot;) %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;hr /&gt;
&lt;p&gt;AI is also really helpful with mundane tasks like writing K8S Kustomize files and corresponding manifests. You do need to know what they should look like so that you can verify that they are correct. It is unadvisable to trust any AI tool to just write you something and then just use it in your infrastructure. But it generally does a good job. I have noticed that it &lt;strong&gt;can&lt;/strong&gt; hallucinate with larger jobs though. But I built out a whole projects Kustomize infra with Claude:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/donhamiltoniii/project-acorn&quot;&gt;Project Acorn&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;base/deployment.yaml&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apiVersion: apps/v1
kind: Deployment
metadata:
  name: project-acorn
  namespace: project-acorn
  annotations:
    argocd-image-updater.argoproj.io/image-list: website=ghcr.io/donhamiltoniii/project-acorn
    argocd-image-updater.argoproj.io/write-back-method: git
    argocd-image-updater.argoproj.io/git-branch: main
spec:
  replicas: 2
  selector:
    matchLabels:
      app: project-acorn
  template:
    metadata:
      labels:
        app: project-acorn
    spec:
      imagePullSecrets:
        - name: ghcr-secret
      containers:
        - name: website
          image: project-acorn-image # This will be replaced by Kustomize
          ports:
            - containerPort: 80
          resources:
            requests:
              memory: &apos;64Mi&apos;
              cpu: &apos;100m&apos;
            limits:
              memory: &apos;128Mi&apos;
              cpu: &apos;200m&apos;
          livenessProbe:
            httpGet:
              path: /
              port: 80
            initialDelaySeconds: 30
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /
              port: 80
            initialDelaySeconds: 5
            periodSeconds: 5
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;base/ingress.yaml&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: project-acorn-ingress
  namespace: project-acorn
  annotations:
    kubernetes.io/ingress.class: &apos;traefik&apos;
spec:
  rules:
    - host: project-acorn.local
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: project-acorn-service
                port:
                  number: 80
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;base/namespace.yaml&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apiVersion: v1
kind: Namespace
metadata:
  name: project-acorn
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;base/service.yaml&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apiVersion: v1
kind: Service
metadata:
  name: project-acorn-service
  namespace: project-acorn
spec:
  selector:
    app: project-acorn
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 80
  type: ClusterIP
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;base/kustomization.yaml&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
  - namespace.yaml
  - deployment.yaml
  - service.yaml
  - ingress.yaml

commonLabels:
  app: project-acorn
  version: v1.0.0

images:
  - name: project-acorn-image
    newName: ghcr.io/donhamiltoniii/project-acorn
    newTag: latest
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;overlays/dev/deployment-patch.yaml&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apiVersion: apps/v1
kind: Deployment
metadata:
  name: project-acorn
  namespace: project-acorn
spec:
  template:
    spec:
      containers:
        - name: website
          resources:
            requests:
              memory: &apos;32Mi&apos;
              cpu: &apos;50m&apos;
            limits:
              memory: &apos;64Mi&apos;
              cpu: &apos;100m&apos;
          env:
            - name: ENVIRONMENT
              value: &apos;development&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;overlays/dev/ingress-patch.yaml&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: project-acorn-ingress
  namespace: project-acorn
spec:
  rules:
    - host: dev.project-acorn.local
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: project-acorn-service # Kustomize will transform this
                port:
                  number: 80
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;overlays/dev/kustomization.yaml&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: project-acorn-dev

resources:
  - ../../base

namePrefix: dev-
nameSuffix: -dev

commonLabels:
  environment: dev

patchesStrategicMerge:
  - deployment-patch.yaml
  - ingress-patch.yaml

images:
  - name: project-acorn-image
    newTag: dev-latest

replicas:
  - name: project-acorn
    count: 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;overlays/prod/deployment-patch.yaml&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apiVersion: apps/v1
kind: Deployment
metadata:
  name: project-acorn
  namespace: project-acorn
spec:
  template:
    spec:
      containers:
        - name: website
          resources:
            requests:
              memory: &apos;128Mi&apos;
              cpu: &apos;200m&apos;
            limits:
              memory: &apos;256Mi&apos;
              cpu: &apos;500m&apos;
          env:
            - name: ENVIRONMENT
              value: &apos;production&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;overlays/prod/ingress-patch.yaml&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: project-acorn-ingress
  namespace: project-acorn
spec:
  rules:
    - host: project-acorn.k3s.syntaxandsymbols.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: project-acorn-service # Kustomize will transform this
                port:
                  number: 80
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;overlays/prod/kustomization.yaml&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: project-acorn-prod

resources:
  - ../../base

namePrefix: prod-
nameSuffix: -prod

commonLabels:
  environment: prod

patchesStrategicMerge:
  - deployment-patch.yaml
  - ingress-patch.yaml

images:
  - name: project-acorn-image
    newTag: latest

replicas:
  - name: project-acorn
    count: 3
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>My Obsidian + Analog Journal Methodology</title><link>https://dondon.dev/cultivated-thoughtz/my-obsidian-methodology</link><guid isPermaLink="true">https://dondon.dev/cultivated-thoughtz/my-obsidian-methodology</guid><content:encoded>&lt;h2&gt;The Problem I Solved&lt;/h2&gt;
&lt;p&gt;I was using Obsidian daily notes that required too much maintenance - I found myself serving the system instead of it serving me. This led me to abandon Obsidian entirely and return to pure analog journaling.&lt;/p&gt;
&lt;h2&gt;The Solution: Obsidian as Digital Companion&lt;/h2&gt;
&lt;h3&gt;Core Principle&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Obsidian complements my analog journal, it doesn&apos;t replace it.&lt;/strong&gt; My physical notebook remains my primary thinking space. Obsidian handles what digital does best while respecting my analog workflow.&lt;/p&gt;
&lt;h2&gt;What Each System Handles&lt;/h2&gt;
&lt;h3&gt;Analog Journal (Primary Thinking Space)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Ad hoc thoughts and ideas&lt;/li&gt;
&lt;li&gt;Deep thinking and reflection&lt;/li&gt;
&lt;li&gt;Daily journaling&lt;/li&gt;
&lt;li&gt;Free-form creativity&lt;/li&gt;
&lt;li&gt;Problem-solving&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Obsidian (Digital Companion)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Linking and Connections&lt;/strong&gt; - Connect ideas across time and topics&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Habit Tracking&lt;/strong&gt; - Digital excels at patterns and data&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Portable Reference&lt;/strong&gt; - Access knowledge from any device&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Knowledge Synthesis&lt;/strong&gt; - Distill and organize key insights&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Research Hub&lt;/strong&gt; - Store articles, literature notes, references&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Daily Note Philosophy&lt;/h2&gt;
&lt;h3&gt;What It&apos;s NOT&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A comprehensive life management system&lt;/li&gt;
&lt;li&gt;A replacement for journaling&lt;/li&gt;
&lt;li&gt;Something that demands daily attention&lt;/li&gt;
&lt;li&gt;A productivity guilt machine&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;What It IS&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;A 30-second habit tracker&lt;/li&gt;
&lt;li&gt;A landing pad for digital thoughts when I&apos;m already in Obsidian&lt;/li&gt;
&lt;li&gt;A bridge to capture analog insights worth digitizing&lt;/li&gt;
&lt;li&gt;A simple intention setter (when it feels natural)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;The Workflow&lt;/h2&gt;
&lt;h3&gt;Morning (Optional)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Set simple daily intention if it feels natural&lt;/li&gt;
&lt;li&gt;Skip if analog journal feels more appropriate&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Throughout the Day&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Physical journal for all real thinking&lt;/li&gt;
&lt;li&gt;Obsidian only when already on computer and something occurs to me&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Evening (30 seconds)&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Quick habit checkbox update&lt;/li&gt;
&lt;li&gt;Note any analog insights worth linking later&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Weekly/Monthly Reviews&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Review habit patterns and trends&lt;/li&gt;
&lt;li&gt;Create permanent notes from recurring insights&lt;/li&gt;
&lt;li&gt;Build knowledge graph based on what&apos;s actually important&lt;/li&gt;
&lt;li&gt;Connect themes across daily notes&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Key Rules&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;No obligation&lt;/strong&gt; - If I don&apos;t feel like updating Obsidian, I don&apos;t&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Analog first&lt;/strong&gt; - When in doubt, reach for pen and paper&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Digital enhancement&lt;/strong&gt; - Obsidian amplifies my thinking, doesn&apos;t drive it&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Connection focus&lt;/strong&gt; - Use Obsidian&apos;s linking power to see patterns over time&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Data over diary&lt;/strong&gt; - Daily notes capture data points, not narratives&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Success Metrics&lt;/h2&gt;
&lt;p&gt;I know this system is working when:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I&apos;m not feeling guilty about &quot;incomplete&quot; daily notes&lt;/li&gt;
&lt;li&gt;Obsidian feels like a helpful tool, not a demanding master&lt;/li&gt;
&lt;li&gt;I&apos;m naturally making connections between ideas across time&lt;/li&gt;
&lt;li&gt;My habit data is helping me see patterns&lt;/li&gt;
&lt;li&gt;The system supports rather than interrupts my thinking flow&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Remember&lt;/h2&gt;
&lt;p&gt;The goal isn&apos;t perfect digital capture - it&apos;s having a digital companion that enhances my analog thinking practice without disrupting its natural flow.&lt;/p&gt;
&lt;p&gt;20250821184951&lt;/p&gt;
</content:encoded></item><item><title>How to Approach New Topics</title><link>https://dondon.dev/seeds/universal-approach-to-new-topics</link><guid isPermaLink="true">https://dondon.dev/seeds/universal-approach-to-new-topics</guid><content:encoded>&lt;p&gt;I&apos;ve been listening to the audio version of How to Take Smart Notes as I do chores around my house and take care of my newborn daughter. Really just as a way to keep my sanity. I didn&apos;t have any expectation of really getting the full value of this book on this first listen/read (depending on how you view the process of listening to an audiobook). But one observation had a profound impact on me immediately.&lt;/p&gt;
&lt;p&gt;In chapter 10, section 3, there is a quote about Richard Feynman and how he considered himself to be understanding a new topic when he could give an introductory lecture on it. That hit me hard.&lt;/p&gt;
&lt;p&gt;For a long time, I&apos;ve been trying to recapture a feeling that I had since I was a Software Development Boot Camp Instructor at We Can Code IT. I thought that it is a passion for teaching, and that may very well be present. But this quote made me realize that what I really miss is the opportunity to make content with the intent of teaching others. That was what was really rewarding and fun about that job.&lt;/p&gt;
&lt;p&gt;The key take away, approach every new topic like you are going to teach it to a class:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Take notes&lt;/li&gt;
&lt;li&gt;Refine the notes&lt;/li&gt;
&lt;li&gt;Build outlines&lt;/li&gt;
&lt;li&gt;Make slide decks&lt;/li&gt;
&lt;li&gt;Build example projects&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Looking forward to exploring this more!&lt;/p&gt;
</content:encoded></item><item><title>Linux Directory Structure Reference Guide</title><link>https://dondon.dev/code/linux-directory-reference-guide</link><guid isPermaLink="true">https://dondon.dev/code/linux-directory-reference-guide</guid><description>Simple reference guide for Linux directories and their use</description><content:encoded>&lt;p&gt;&lt;em&gt;* AI Generated&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;Overview&lt;/h2&gt;
&lt;p&gt;The Linux filesystem follows a hierarchical structure defined by the Filesystem Hierarchy Standard (FHS). Understanding this structure is essential for system administration, software deployment, and general Linux usage.&lt;/p&gt;
&lt;h2&gt;Root Directory Structure&lt;/h2&gt;
&lt;h3&gt;&lt;code&gt;/&lt;/code&gt; (Root Directory)&lt;/h3&gt;
&lt;p&gt;The top-level directory that contains all other directories and files in the system.&lt;/p&gt;
&lt;hr /&gt;
&lt;h2&gt;Essential System Directories&lt;/h2&gt;
&lt;h3&gt;&lt;code&gt;/bin&lt;/code&gt; - Essential User Binaries&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: Contains essential command-line utilities needed by all users&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Availability&lt;/strong&gt;: Must be available even in single-user mode&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Examples&lt;/strong&gt;: &lt;code&gt;ls&lt;/code&gt;, &lt;code&gt;cp&lt;/code&gt;, &lt;code&gt;mv&lt;/code&gt;, &lt;code&gt;cat&lt;/code&gt;, &lt;code&gt;bash&lt;/code&gt;, &lt;code&gt;grep&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Note&lt;/strong&gt;: These are commands you&apos;d expect to work on any Linux system&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;/sbin&lt;/code&gt; - System Binaries&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: Essential system administration commands&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Access&lt;/strong&gt;: Typically used by root/administrators&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Examples&lt;/strong&gt;: &lt;code&gt;mount&lt;/code&gt;, &lt;code&gt;umount&lt;/code&gt;, &lt;code&gt;fsck&lt;/code&gt;, &lt;code&gt;iptables&lt;/code&gt;, &lt;code&gt;systemctl&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Note&lt;/strong&gt;: &quot;s&quot; stands for &quot;system&quot; or &quot;superuser&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;/lib&lt;/code&gt; - Essential Libraries&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: Shared libraries required by programs in &lt;code&gt;/bin&lt;/code&gt; and &lt;code&gt;/sbin&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Contents&lt;/strong&gt;: Dynamic linking libraries (.so files)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Importance&lt;/strong&gt;: Critical for system boot and basic functionality&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;User and Application Directories&lt;/h2&gt;
&lt;h3&gt;&lt;code&gt;/usr&lt;/code&gt; - User System Resources&lt;/h3&gt;
&lt;p&gt;Secondary hierarchy containing the majority of user utilities and applications.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Key subdirectories:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/usr/bin&lt;/code&gt; - Non-essential user commands and applications&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/usr/sbin&lt;/code&gt; - Non-essential system administration binaries&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/usr/lib&lt;/code&gt; - Libraries for &lt;code&gt;/usr/bin&lt;/code&gt; and &lt;code&gt;/usr/sbin&lt;/code&gt; programs&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/usr/local&lt;/code&gt; - Local software installations (not from package manager)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/usr/share&lt;/code&gt; - Architecture-independent shared data&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;/opt&lt;/code&gt; - Optional Software Packages&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: Self-contained third-party software packages&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Structure&lt;/strong&gt;: Each package gets its own subdirectory (e.g., &lt;code&gt;/opt/google/chrome&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use Cases&lt;/strong&gt;:
&lt;ul&gt;
&lt;li&gt;Commercial software&lt;/li&gt;
&lt;li&gt;Large application suites&lt;/li&gt;
&lt;li&gt;Proprietary applications&lt;/li&gt;
&lt;li&gt;Software that prefers to keep all files together&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Examples&lt;/strong&gt;: Oracle Database, VMware, Google Chrome, custom enterprise applications&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;/home&lt;/code&gt; - User Home Directories&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: Personal directories for regular users&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Structure&lt;/strong&gt;: &lt;code&gt;/home/username&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Contents&lt;/strong&gt;: User files, personal configurations, documents&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;/root&lt;/code&gt; - Root User Home&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: Home directory specifically for the root user&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Location&lt;/strong&gt;: Separate from &lt;code&gt;/home&lt;/code&gt; for security and availability reasons&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Configuration and Data Directories&lt;/h2&gt;
&lt;h3&gt;&lt;code&gt;/etc&lt;/code&gt; - System Configuration&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: System-wide configuration files&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Format&lt;/strong&gt;: Text-based configuration files&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Examples&lt;/strong&gt;: &lt;code&gt;/etc/passwd&lt;/code&gt;, &lt;code&gt;/etc/hosts&lt;/code&gt;, &lt;code&gt;/etc/apache2/&lt;/code&gt;, &lt;code&gt;/etc/ssh/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scope&lt;/strong&gt;: Affects entire system, not individual users&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;/var&lt;/code&gt; - Variable Data&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: Files that change during normal system operation&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Key subdirectories:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/var/log&lt;/code&gt; - System and application log files&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/var/mail&lt;/code&gt; - User mailboxes&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/var/tmp&lt;/code&gt; - Temporary files preserved between reboots&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/var/lib&lt;/code&gt; - Application state data&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/var/cache&lt;/code&gt; - Application cache data&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Temporary and Runtime Directories&lt;/h2&gt;
&lt;h3&gt;&lt;code&gt;/tmp&lt;/code&gt; - Temporary Files&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: Temporary files for applications and users&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cleanup&lt;/strong&gt;: Often cleared on system reboot&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Access&lt;/strong&gt;: World-writable with sticky bit set&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Usage&lt;/strong&gt;: Short-term storage during program execution&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Boot and Hardware Directories&lt;/h2&gt;
&lt;h3&gt;&lt;code&gt;/boot&lt;/code&gt; - Boot Files&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: Files required for system startup&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Contents&lt;/strong&gt;: Kernel images, initial RAM disk, bootloader configuration&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Examples&lt;/strong&gt;: &lt;code&gt;vmlinuz&lt;/code&gt;, &lt;code&gt;initrd.img&lt;/code&gt;, GRUB configuration&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;/dev&lt;/code&gt; - Device Files&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: Special files representing hardware devices&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Type&lt;/strong&gt;: Character and block device files&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Examples&lt;/strong&gt;: &lt;code&gt;/dev/sda&lt;/code&gt; (hard drive), &lt;code&gt;/dev/null&lt;/code&gt;, &lt;code&gt;/dev/random&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Management&lt;/strong&gt;: Usually managed automatically by &lt;code&gt;udev&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Virtual Filesystems&lt;/h2&gt;
&lt;h3&gt;&lt;code&gt;/proc&lt;/code&gt; - Process Information&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: Virtual filesystem exposing kernel and process information&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Contents&lt;/strong&gt;: Process directories (numbered by PID), system information&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Examples&lt;/strong&gt;: &lt;code&gt;/proc/cpuinfo&lt;/code&gt;, &lt;code&gt;/proc/meminfo&lt;/code&gt;, &lt;code&gt;/proc/1/&lt;/code&gt; (init process)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Note&lt;/strong&gt;: Files exist only in memory, not on disk&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;/sys&lt;/code&gt; - System Information&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: Virtual filesystem for modern kernel object information&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Contents&lt;/strong&gt;: Hardware device information, kernel modules, power management&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Usage&lt;/strong&gt;: Used by modern system management tools&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Note&lt;/strong&gt;: More structured than &lt;code&gt;/proc&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Mount Point Directories&lt;/h2&gt;
&lt;h3&gt;&lt;code&gt;/mnt&lt;/code&gt; - Manual Mount Point&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: Temporary mount point for manually mounted filesystems&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Usage&lt;/strong&gt;: System administrators mount filesystems here temporarily&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Examples&lt;/strong&gt;: Mounting external drives for maintenance&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;/media&lt;/code&gt; - Removable Media&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Purpose&lt;/strong&gt;: Automatic mount points for removable media&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Management&lt;/strong&gt;: Usually handled by desktop environments&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Examples&lt;/strong&gt;: &lt;code&gt;/media/usb-drive&lt;/code&gt;, &lt;code&gt;/media/cdrom&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr /&gt;
&lt;h2&gt;Quick Reference Summary&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Directory&lt;/th&gt;
&lt;th&gt;Primary Purpose&lt;/th&gt;
&lt;th&gt;Key Characteristics&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/bin&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Essential user commands&lt;/td&gt;
&lt;td&gt;Available in single-user mode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/sbin&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;System administration&lt;/td&gt;
&lt;td&gt;Root/admin tools&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/usr&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;User programs and data&lt;/td&gt;
&lt;td&gt;Secondary hierarchy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/opt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Third-party packages&lt;/td&gt;
&lt;td&gt;Self-contained installations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/etc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;System configuration&lt;/td&gt;
&lt;td&gt;Text-based config files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/var&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Changing data&lt;/td&gt;
&lt;td&gt;Logs, mail, temporary files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/home&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;User directories&lt;/td&gt;
&lt;td&gt;Personal user spaces&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/tmp&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Temporary files&lt;/td&gt;
&lt;td&gt;Often cleared on boot&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr /&gt;
&lt;h2&gt;Best Practices for Students&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Exploration&lt;/strong&gt;: Use &lt;code&gt;ls -la&lt;/code&gt; to explore directory contents and permissions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Documentation&lt;/strong&gt;: Check &lt;code&gt;man hier&lt;/code&gt; for detailed filesystem hierarchy information&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Respect&lt;/strong&gt;: Be cautious when working in system directories (especially as root)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Understanding&lt;/strong&gt;: Learn the logic behind the structure - it makes navigation intuitive&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Practice&lt;/strong&gt;: Set up a virtual machine to safely explore the filesystem structure&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;h2&gt;Common Confusion Points&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;/usr&lt;/code&gt; vs &lt;code&gt;/usr/local&lt;/code&gt;&lt;/strong&gt;: &lt;code&gt;/usr&lt;/code&gt; is for package-managed software, &lt;code&gt;/usr/local&lt;/code&gt; is for manually compiled/installed software&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;/bin&lt;/code&gt; vs &lt;code&gt;/usr/bin&lt;/code&gt;&lt;/strong&gt;: &lt;code&gt;/bin&lt;/code&gt; is for essential commands, &lt;code&gt;/usr/bin&lt;/code&gt; is for additional user programs&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;/tmp&lt;/code&gt; vs &lt;code&gt;/var/tmp&lt;/code&gt;&lt;/strong&gt;: &lt;code&gt;/tmp&lt;/code&gt; may be cleared on reboot, &lt;code&gt;/var/tmp&lt;/code&gt; should persist across reboots&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;/opt&lt;/code&gt; vs &lt;code&gt;/usr/local&lt;/code&gt;&lt;/strong&gt;: Both for additional software, but &lt;code&gt;/opt&lt;/code&gt; is for packaged applications, &lt;code&gt;/usr/local&lt;/code&gt; follows standard hierarchy&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This structure has evolved over decades and represents a balance between organization, tradition, and practical system administration needs.&lt;/p&gt;
</content:encoded></item><item><title>Dad Thoughtz</title><link>https://dondon.dev/seeds/dad-thoughtz</link><guid isPermaLink="true">https://dondon.dev/seeds/dad-thoughtz</guid><content:encoded>&lt;ul&gt;
&lt;li&gt;Be the person you want to raise your child to be, don&apos;t dictate it. Enforcing rules is certainly important. Telling your kid no is gonna happen. But don&apos;t become a voice of discouragement. Offer explanations and alternatives instead of &apos;no&apos;. Lead by example not orders.&lt;/li&gt;
&lt;li&gt;Your kids (or really anyone you love) don&apos;t need to &quot;make you proud&quot;
&lt;ul&gt;
&lt;li&gt;Don&apos;t ever use that as motivation&lt;/li&gt;
&lt;li&gt;Don&apos;t be a parental tyrant&lt;/li&gt;
&lt;li&gt;Don&apos;t CONTROL your kids -&amp;gt; they will hate you&lt;/li&gt;
&lt;li&gt;Don&apos;t dictate to them&lt;/li&gt;
&lt;li&gt;Instill values, show them how to be good people, trust them to make the right decisions, and teach them when they inevitably don&apos;t make the right decision&lt;/li&gt;
&lt;li&gt;Work with them&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content:encoded></item><item><title>Seeds, Not Articles</title><link>https://dondon.dev/seeds/planting-the-first-seed</link><guid isPermaLink="true">https://dondon.dev/seeds/planting-the-first-seed</guid><content:encoded>&lt;p&gt;So I think I had a breakthrough with digital gardening today. I was talking about my personal site with a friend and I was talking about being frustrated with my lack of content. I realized that I&apos;m struggling with something adjacent to perfectionism. It&apos;s not necessarily that I feel like I need to have a perfectly polished essay or anything to be able to write. But I&apos;ve been trying to make these big posts. Something that I spend a lot of time on. Something that is complete.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;That&apos;s not the point of digital gardening!&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I&apos;m supposed to come back to these things! Grow them! Like plants in a garden! Maybe that should&apos;ve been more obvious... But I eventually found myself here! So now I&apos;m gonna do my best to post often and revisit the stuff I post. This is where I imagine most of my content will live until it grows enough to fit somewhere else.&lt;/p&gt;
</content:encoded></item><item><title>2025 Quarter Two Goals</title><link>https://dondon.dev/cultivated-thoughtz/2025-quarter-two-goals</link><guid isPermaLink="true">https://dondon.dev/cultivated-thoughtz/2025-quarter-two-goals</guid><description>This is the outline for my quarterly quests in Q2 of 2025</description><content:encoded>&lt;h2&gt;Previous Quarter Review&lt;/h2&gt;
&lt;h2&gt;Fitness Goal&lt;/h2&gt;
&lt;p&gt;I think that I did well here. I wish that I would&apos;ve started Strength Side one fucking week earlier so that I would&apos;ve finished the program with the quarter. But that&apos;s fine. I&apos;m going to continue doing this program for the next quarter anyway. So this time, I actually will end with the quarter. But as far as progress, I&apos;ve made quite a bit. I&apos;m pretty excited for how my push ups are looking and my pull ups are coming along too&lt;/p&gt;
&lt;h2&gt;Artistic Goal&lt;/h2&gt;
&lt;p&gt;This was a fail. Straight up and down. There&apos;s no way around it. Insofar as I did not even approach my goal of &quot;actively and intentionally capturing images in my day to day&quot;. I did, however, learn a lot about my process through the other goals that I made for myself. So I think I have a good plan for this coming quarter. I need to play into the things that I&apos;m inherentlt driven to do. So if I can make a self-hosting project out of photography and build hardware around it (like a dedicated work station for photo editing), I&apos;m going to be more successful. I think this is going to be a good way to combine both of these efforts.&lt;/p&gt;
&lt;h2&gt;Creative Goal&lt;/h2&gt;
&lt;p&gt;I crushed this shit. I&apos;m so fucking passionate about this part. Learning to self host and use server environments more efficiently to the point that I can actually build tools that I can use in personal projects is awesome. I have a K8S homelab setup that I built following MVDB&apos;s Skool course. I&apos;m in the process of going through another, in-depth Docker/Kubernetes course. And then, once I have a better handle on K8S itself, I&apos;m gonna go through another course (or maybe courses? IDR) for K8S and FluxCD. So I can get more hands on experience with working with K8S with YAML manifests. But I think working more hands on first is going to be beneficial. Learn the tool before you automate the boring stuff. Oh yea: &lt;a href=&quot;https://linkding.dondon.wtf&quot;&gt;My self-hosted LinkDing instance&lt;/a&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;h1&gt;This Quarter&lt;/h1&gt;
&lt;h2&gt;Scope&lt;/h2&gt;
&lt;p&gt;Week 14 to Week 26 of 2025. So from [[2025-03-30]] - [[2025-06-28]].&lt;/p&gt;
&lt;h2&gt;Areas of Focus&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Body::&lt;/strong&gt; Do Strength Side again
&lt;strong&gt;Right Brain::&lt;/strong&gt; Setup a workstation for photo editing and document the rest of this pregnancy
&lt;strong&gt;Left Brain::&lt;/strong&gt; Be better at Docker and Kubernetes&lt;/p&gt;
&lt;h2&gt;Body&lt;/h2&gt;
&lt;p&gt;Last quarter, &lt;a href=&quot;https://strengthside.com/apps/my/courses/list?course=movestrongnow&amp;amp;lesson=Schedule_114287&quot;&gt;Strength Side&lt;/a&gt; went so well that I am going to continue down this calisthenics path this quarter as well. I may start trying to lift again in Q3 but we&apos;ll see what happens. That&apos;s a conversation with myself that will need to be had later. Similar goal though, try to go through the whole Strength Side 3 months and do the harder variations of each exercise. I feel way better and I definitely feel like I&apos;m moving around better.&lt;/p&gt;
&lt;h3&gt;DoD&lt;/h3&gt;
&lt;p&gt;I will consider this goal complete if I do at least 3 workouts a week for this quarter and document my findings.&lt;/p&gt;
&lt;h2&gt;Right Brain&lt;/h2&gt;
&lt;p&gt;Last quarter I fell flat on my face with this goal. But in trying to pursue it, I learned a lot about myself and my process. I am fully into self-hosting and trying to make my own services on my home network. I need to incorporate that into my Art goal. Not let it steal the show or anything. But play into my current interests. I broke down and spent money in a way that I was trying to avoid doing. But, tbh, I think it&apos;s gonna be good for me as it applies to this goal. I bought myself a &lt;a href=&quot;https://www.amazon.com/dp/B08LM9BLN2&quot;&gt;Ricoh GR III Street Edition&lt;/a&gt;. I do not need a new camera but I really do think this is gonna help me take more photos. Because of the size of this camera as well as the settings available in such a small package, I think I&apos;m gonna be able to have this camera with me in more scenarios than my Nikon Z5. And that&apos;s definitely a lesson I&apos;ve learned about myself over time. I need to have tools available to use them. I am inherently lazy and I will actively not do something if there are too many barriers to entry. So while this is a superfluous purchase, I think it&apos;s gonna end up being really worthwhile.&lt;/p&gt;
&lt;h3&gt;DoD&lt;/h3&gt;
&lt;p&gt;This goal will be complete if I am taking photos more regularly and publishing them to a self-hosted blog or something similar. I don&apos;t want to constrain myself too much here as my next goal will inform what my publishing platform will be&lt;/p&gt;
&lt;h2&gt;Left Brain&lt;/h2&gt;
&lt;p&gt;So I feel like I was REALLY taken by &lt;a href=&quot;https://gomakethings.com/the-joy-of-digital-gardening/&quot;&gt;Chris Ferdinandi&apos;s post about digital gardening&lt;/a&gt;. This shit speaks to me like viscerally. This is what excites me about the web. This is what made me want to be a designer and illustrator as a kid, it&apos;s what gave me any interest in &quot;building web sites&quot; and later programming. In a lot of ways, this sort of early web mentality of like the DIY or punk web or whatever you want to call it, shaped me as a person. And I want so badly to get back to that. Just build shit because it makes me happy and it gives me a creative way to interact with the people around me. And it gives me a reason to learn different technologies and processes. So I want to continue on this journey that I&apos;m on to learn and use Docker and Kubernetes more so that I can build whatever I want and deliver it to the people that I care about.&lt;/p&gt;
&lt;h3&gt;Definition of Done&lt;/h3&gt;
&lt;p&gt;I have done more learning on Docker and K8S, I have a more robust homelab/home network, and I am self-hosting more services for my own consumption, thereby reducing the number of services I use from large toxic tech companies, but also serving my own digital spaces for my own creative work.&lt;/p&gt;
&lt;p&gt;20250330055219&lt;/p&gt;
</content:encoded></item><item><title>How to set up an SSH connection between machines</title><link>https://dondon.dev/code/how-to-set-up-an-ssh-connection-between-machines</link><guid isPermaLink="true">https://dondon.dev/code/how-to-set-up-an-ssh-connection-between-machines</guid><description>A quick walkthrough detailing how to link two machines via SSH</description><content:encoded>&lt;ol&gt;
&lt;li&gt;generate an ssh key from the work station machine: &lt;code&gt;ssh-keygen -f ~/.ssh/&amp;lt;your-key-name&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;copy the new key from the work station machine to the agent machine: &lt;code&gt;ssh-copy-id -i ~/.ssh/&amp;lt;your-key-name&amp;gt; &amp;lt;ip addr of agent machine&amp;gt;&lt;/code&gt;
&lt;ol&gt;
&lt;li&gt;example: &lt;code&gt;ssh-copy-id -i ~/.ssh/home-lab-key 192.168.0.10&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;make sure ssh-agent is running on workstation machine: &lt;code&gt;eval $(ssh-agent -s)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;add ssh key to registry for use: &lt;code&gt;ssh-add ~/.ssh/&amp;lt;your-key-name&amp;gt;&lt;/code&gt;
&lt;ol&gt;
&lt;li&gt;example: &lt;code&gt;ssh-add ~/.ssh/home-lab-key&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;you should now be able to run: &lt;code&gt;ssh &amp;lt;ip addr of agent machine&amp;gt;&lt;/code&gt; and connect to that machine
&lt;ol&gt;
&lt;li&gt;example: &lt;code&gt;ssh 192.168.0.10&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>Adding Last Modified Support to Astro Blog Posts</title><link>https://dondon.dev/code/adding-last-modified-support-to-astro-blog-posts</link><guid isPermaLink="true">https://dondon.dev/code/adding-last-modified-support-to-astro-blog-posts</guid><description>A quick account of implementing a programmatic solution to modifying dates in blog posts</description><content:encoded>&lt;p&gt;This morning I set out to update my &lt;a href=&quot;https://dondon.dev/&quot;&gt;Personal Blog&lt;/a&gt; powered by &lt;a href=&quot;https://astro.build/&quot;&gt;Astro&lt;/a&gt;. In an effort to do more writing, I am trying to make sure the platform that I&apos;m using for said writing is as accommodating as possible. My posts have had a &quot;Last Updated&quot; field for a while and it&apos;s just been the same as the publish date. So I looked into automating the process so that any time I make an update to a post, the &quot;Last Updated&quot; field is programmatically updated. This way I don&apos;t have to trust myself to do it as I&apos;ve proven incredibly unreliable for this task.&lt;/p&gt;
&lt;p&gt;Since I took the time to do it, I figured I&apos;d recap the process. To begin, I actually found that Astro includes a &lt;a href=&quot;https://docs.astro.build/en/recipes/modified-time/&quot;&gt;&quot;Recipe&quot;&lt;/a&gt; for this in their docs. This actually made me super happy because the other solutions that I came across involved pre-commit hooks and shell scripts and a bunch of other config that is definitely interesting and fun. But it&apos;s also a giant pain in the ass when you just want one specific outcome.&lt;/p&gt;
&lt;p&gt;I won&apos;t bog down this post with code examples as I pretty much just followed the &lt;a href=&quot;https://docs.astro.build/en/recipes/modified-time/&quot;&gt;recipe from Astro&lt;/a&gt;. But what is really cool to learn is that I can make my own plugins for the purposes of pre-processing. Being able to programmatically manipulate data like this open up some pretty cool doors because it allows me to let the computer do the jobs that the computer does well and allows me to focus on what I really care about which is building cool shit and writing about it.&lt;/p&gt;
</content:encoded></item><item><title>My 2025 Quarter One Goals</title><link>https://dondon.dev/cultivated-thoughtz/2025-quarter-one-goals</link><guid isPermaLink="true">https://dondon.dev/cultivated-thoughtz/2025-quarter-one-goals</guid><description>This is a list of goals that I am going to make myself accountable for in the first quarter of 2025.</description><content:encoded>&lt;h2&gt;Scope&lt;/h2&gt;
&lt;p&gt;Week 1 to Week 13 of 2025. So from 2024-12-29 - 2025-03-29.&lt;/p&gt;
&lt;h2&gt;Areas of Focus&lt;/h2&gt;
&lt;p&gt;For this quarter, I want to focus on narrowing the scope of my focus to a fitness goal, an artistic goal, and a creative goal. I will also start writing weekly updates of my progress and maybe publishing them?&lt;/p&gt;
&lt;h2&gt;Fitness Goal&lt;/h2&gt;
&lt;p&gt;For my fitness goal, I want to go through the &lt;a href=&quot;https://strengthside.com/apps/my/courses/list?course=movestrongnow&amp;amp;lesson=Schedule_114287&quot;&gt;Strength Side course that I bought&lt;/a&gt;. I will keep track of each day by writing about my progress in my daily note and then writing a comprehensive summary of my experience at the end. I plan to stop lifting weights for this period and see how it affects my body. At the end of this 90 days, I can assess if this is working better or worse for me and go from there.&lt;/p&gt;
&lt;h3&gt;Definition of Done&lt;/h3&gt;
&lt;p&gt;I will consider this goal complete if I do at least 3 workouts a week for this quarter and document my findings.&lt;/p&gt;
&lt;h2&gt;Artistic Goal&lt;/h2&gt;
&lt;p&gt;For my artistic goal, I want to get back into actively photographing things again. Maybe this means getting outside and shooting images for an hour. Maybe it means editing photos I&apos;ve taken for an hour. It could be reading photo theory and applying it to my process. Either way, make some art and put it somewhere. If you make prints, hang them in the house or give them away as gifts. I would like to come up with a project or two in this quarter but I would like to let that happen more organically. Maybe that will be my sort of quarterly thesis project or something like that. Spend the last month or so focused on a project and make something specific to show.&lt;/p&gt;
&lt;h3&gt;Definition of Done&lt;/h3&gt;
&lt;p&gt;I will consider this goal complete if I am more actively and intentionally capturing images in my day to day and if I have produced something that I am proud of in a way that I make prints and present it as a project by the end of the quarter.&lt;/p&gt;
&lt;h2&gt;Creative Goal&lt;/h2&gt;
&lt;p&gt;I struggled with classifying this goal because creative feels like a cop out. I was gonna call this a logic goal or a computer goal but I realized it encompasses more than that. I want to get better at Linux administration. Ultimately this is going to be part of a larger goal of working with Kubernetes in a more regular capacity. Also this is the foundation of my homelab and knowledge base therein. So I feel like this goal is a bit more ambiguous. I want to finish this Udemy course: &lt;a href=&quot;https://www.udemy.com/course/linux-administration-build-hands-on-linux-projects/&quot;&gt;Linux Sysadmin:Build 5 Hands-On Linux Projects for Real Jobs&lt;/a&gt;. But my Goal is to use what I learn in this course to host something on my existing server environment and make it accessible from the public internet. I think everything in this course will cover that and get me to that end. But if it doesn&apos;t, I will still use the skills from this course to build the things I am going to host and then explore past it to figure out how to successfully expose my apps to the internet at large without making myself vulnerable to attacks.&lt;/p&gt;
&lt;h3&gt;Definition of Done&lt;/h3&gt;
&lt;p&gt;I will consider this goal complete if I have completed the course and have at least one application running and hosted on my local server that I can somehow access from any device via the public internet.&lt;/p&gt;
</content:encoded></item><item><title>Running Docker Containers Locally</title><link>https://dondon.dev/code/running-docker-containers-locally</link><guid isPermaLink="true">https://dondon.dev/code/running-docker-containers-locally</guid><description>A working document with instructions and tips for how to setup a local Ubuntu server with Docker installed and run your own applications</description><content:encoded>&lt;p&gt;In an effort to learn more about Linux for the purposes of running a homelab and self hosting applications built by me as well as others, I am going through &lt;a href=&quot;https://www.udemy.com/course/linux-administration-build-hands-on-linux-projects/&quot;&gt;this wonderful course on Udemy&lt;/a&gt;. In an effort to better remember everything I learned, I&apos;m documenting some of the processes that I learned to implement a custom &lt;a href=&quot;https://astro.build/&quot;&gt;Astro&lt;/a&gt; application.&lt;/p&gt;
&lt;h2&gt;Initial Setup&lt;/h2&gt;
&lt;p&gt;The first thing you need to do is provision a server. There are a whole bunch of ways to achieve this goal and I will leave that to you to decide. My existing home lab environment is running &lt;a href=&quot;https://www.proxmox.com/en/&quot;&gt;Proxmox&lt;/a&gt; which I highly recommend. Especially if you are new to virtualization. Proxmox is a hypervisor that makes provisioning new servers simple and easy. The biggest benefit of a hypervisor like Proxmox is that you can create and delete servers at will without having to re-provision the same machine over and over and over. This is super convenient if you&apos;re learning and will be creating lots of short lived servers frequently for the purposes of learning something new.&lt;/p&gt;
&lt;h2&gt;Setup Ubuntu&lt;/h2&gt;
&lt;p&gt;After installing Ubuntu (by &lt;a href=&quot;https://ubuntu.com/server/docs/basic-installation&quot;&gt;following the docs&lt;/a&gt;), you should &lt;a href=&quot;https://www.linuxtechi.com/static-ip-address-on-ubuntu-server/&quot;&gt;setup a static IP address&lt;/a&gt;. This is an important step because it gives you a reliable IP by which you can reach your server. It&apos;s also a good idea to go to your router settings a restrict the range of IP addresses that your router can use to assign to new devices. Your static IP should exist outside of the range you set in your router to avoid duplicate assignments. Now it&apos;s time to install some stuff!&lt;/p&gt;
&lt;h3&gt;Setup SSH&lt;/h3&gt;
&lt;p&gt;First, make sure that OpenSSH is installed. Run the following to check the status:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;service ssh status
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you see something that looks like the following, you&apos;re all set:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;● ssh.service - OpenBSD Secure Shell server
     Loaded: loaded (/usr/lib/systemd/system/ssh.service; disabled; preset: enabled)
     Active: active (running) since Sun 2024-12-29 20:47:38 UTC; 3 days ago
TriggeredBy: ● ssh.socket
       Docs: man:sshd(8)
             man:sshd_config(5)
   Main PID: 1442 (sshd)
      Tasks: 1 (limit: 2276)
     Memory: 2.8M (peak: 4.5M swap: 608.0K swap peak: 608.0K)
        CPU: 267ms
     CGroup: /system.slice/ssh.service
             └─1442 &quot;sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you see a message indicating that there is no SSH service, then run the following commands to get it installed and running:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt install ssh
service ssh start
service ssh status
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After running those commands you should see that the service is indeed active.&lt;/p&gt;
&lt;h3&gt;Install Docker&lt;/h3&gt;
&lt;p&gt;Next we need to have Docker running in order to have an environment to run containers. As a prerequisite, we need to make sure there are a couple of other packages we need to make sure are installed. Run the following commands:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt update
sudo apt install apt-transport-https curl
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This ensures that we can download the next piece that will actually allow us to download and install Docker.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now run the following command to add the docker repository to our system:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;echo &quot;deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release &amp;amp;&amp;amp; echo &quot;$VERSION_CODENAME&quot;) stable&quot; | sudo tee /etc/apt/sources.list.d/docker.list &amp;gt; /dev/null
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, we can run the last command that will install docker on our Ubuntu server:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt update &amp;amp;&amp;amp; sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once everything is installed we can check first to make sure that the service is running&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;service docker status
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You should see something that looks similar to the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;● docker.service - Docker Application Container Engine
     Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; preset: enabled)
     Active: active (running) since Sun 2024-12-29 21:21:54 UTC; 3 days ago
TriggeredBy: ● docker.socket
       Docs: https://docs.docker.com
   Main PID: 3035 (dockerd)
      Tasks: 17
     Memory: 673.7M (peak: 722.1M swap: 3.9M swap peak: 3.9M)
        CPU: 59.400s
     CGroup: /system.slice/docker.service
             └─3035 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;BONUS:&lt;/strong&gt; To run docker without having to type &lt;code&gt;sudo&lt;/code&gt; all of the time, run the following command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo usermod -aG docker ${USER}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once docker is running, run the following to make sure that everything is functioning correctly and then we&apos;re good to move on!&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker container run hello-world
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Install NVM and Node&lt;/h3&gt;
&lt;p&gt;The next step is to install support for NVM, Node, and Git to pass projects back and forth so that we can develop them on a work machine and then pull them on this server environment for deployment. So let&apos;s get started. First, we need to install &lt;a href=&quot;https://github.com/nvm-sh/nvm&quot;&gt;Node Version Manager&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then start NVM with the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export NVM_DIR=&quot;$([ -z &quot;${XDG_CONFIG_HOME-}&quot; ] &amp;amp;&amp;amp; printf %s &quot;${HOME}/.nvm&quot; || printf %s &quot;${XDG_CONFIG_HOME}/nvm&quot;)&quot;
[ -s &quot;$NVM_DIR/nvm.sh&quot; ] &amp;amp;&amp;amp; \. &quot;$NVM_DIR/nvm.sh&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You should be able to run &lt;code&gt;nvm -v&lt;/code&gt; now and see &lt;code&gt;v0.39.7&lt;/code&gt; printed back to you.&lt;/p&gt;
&lt;p&gt;Next, it&apos;s time to install Node. This is super easy with NVM.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;nvm install --lts
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once NVM finishes up, run &lt;code&gt;node -v&lt;/code&gt; and you should see a version printed out. So long as you do, Node is installed properly.&lt;/p&gt;
&lt;h2&gt;Create new Astro app and push to git&lt;/h2&gt;
&lt;p&gt;Now that our server is setup to handle Node applications, let&apos;s bootstrap an example application that you can work with and grow as you see fit.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm create astro@latest -- --template satnaing/astro-paper
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this example, we are using the &lt;a href=&quot;https://github.com/satnaing/astro-paper&quot;&gt;astro-paper theme&lt;/a&gt;, but feel free to pick whatever you would like. I like starting with a blog. Even if you don&apos;t publish what you write, having a place to record and document the things you build is a good thing to have.&lt;/p&gt;
&lt;p&gt;Once you have your project setup, push it up to git so that you can pull it down on your work machine and develop.&lt;/p&gt;
&lt;h2&gt;Create Docker file&lt;/h2&gt;
&lt;p&gt;One of the reasons we are using the astro-paper theme is that we get a static build from it. This is helpful for the actual deployment process because it makes it easier to stand up a proper web server like &lt;a href=&quot;https://www.f5.com/go/product/welcome-to-nginx&quot;&gt;NGINX&lt;/a&gt; to serve our app. This isn&apos;t a necessity, but it is recommended. First, let&apos;s create a Dockerfile so that we can build an image of our application to soon run it in our docker instance. At the root of your project, create a new file called &lt;code&gt;Dockerfile&lt;/code&gt; and paste the following values:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;FROM node:lts AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

FROM nginx:alpine AS runtime
COPY ./nginx/nginx.conf /etc/nginx/nginx.conf
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 8080
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since we are using NGINX, we will need to include a configuration file for it. At the root of your project, add a directory called &lt;code&gt;nginx&lt;/code&gt; and then create a new file &lt;code&gt;nginx/nginx.conf&lt;/code&gt; and inside of that new file, paste the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;worker_processes  1;

events {
  worker_connections  1024;
}

http {
  server {
    listen 8080;
    server_name   _;

    root   /usr/share/nginx/html;
    index  index.html index.htm;
    include /etc/nginx/mime.types;

    gzip on;
    gzip_min_length 1000;
    gzip_proxied expired no-cache no-store private auth;
    gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;

    error_page 404 /404.html;
    location = /404.html {
            root /usr/share/nginx/html;
            internal;
    }

    location / {
            try_files $uri $uri/index.html =404;
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With these files added, we have all pieces in place to build our application for production deployment. At this point it would be a good idea to make sure that we can see a functional version of our application. The following steps will make that happen.&lt;/p&gt;
&lt;h3&gt;Build Docker Image&lt;/h3&gt;
&lt;p&gt;In order to run our application, we&apos;ll need a Docker image. One simple command will provide that for us from the existing application code. Run the following to generate the Docker image.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker build . -t application-name:latest
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the previous command, replace &lt;code&gt;application-name&lt;/code&gt; with whatever you want to call your application. This is how you will reference it to run it in Docker. If you plan to push this image up to &lt;a href=&quot;https://hub.docker.com/&quot;&gt;DockerHub&lt;/a&gt; you should amend the previous command slightly.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker build . -t dockerhub-username/application-name:latest
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this case, substitute &lt;code&gt;dockerhub-username&lt;/code&gt; with your actual DockerHub username. If you just plan to run your application in this singular location, you can forgo that extended name. If you decide later that you want to push your image to DockerHub, you can always build a new image with a new tag.&lt;/p&gt;
&lt;p&gt;If you want to copy-pasta the exact command, use the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker build . -t astro-blog-example:latest
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Run Docker Image&lt;/h3&gt;
&lt;p&gt;With our new Docker image built, let&apos;s run it and make sure that it works.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker container run -d -p port-on-server:port-exposed-from-image tag-name
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Replace these values with values that actually make sense for your specific application:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;port-on-server&lt;/code&gt;: The port number that you this application will be accessible from on your actual server.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;port-exposed-from-image&lt;/code&gt;: The port exposed in the Dockerfile. In this example, &lt;code&gt;8080&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tag-name&lt;/code&gt;: Whatever you named your application in the previous step.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Again, if you want to copy-pasta directly, use the following command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker container run -d -p 80:8080 astro-blog-example:latest
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That command will run an instance of our application on port 80 of our server. Run the following command to confirm that this new instance is running without error:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker container ls -a
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You should see an output similar to the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;CONTAINER ID   IMAGE                       COMMAND                  CREATED         STATUS         PORTS                                   NAMES
20ad93fe6224   astro-blog-example:latest   &quot;/docker-entrypoint.…&quot;   6 seconds ago   Up 6 seconds   0.0.0.0:80-&amp;gt;8080/tcp, :::80-&amp;gt;8080/tcp   pedantic_clarke
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So long as your output looks similar to that, your application should be running. You should be able to go to your favorite browser on your dev machine, type the ip address of your server, and see the landing page of your application running! Congrats!&lt;/p&gt;
&lt;h2&gt;Dev vs Prod&lt;/h2&gt;
&lt;p&gt;Now that we know that our application is capable of getting all the way to our production environment, we can start making it our own! It&apos;s a real challenge to develop in this environment though. Now there are certainly ways that we could develop this application here on the server, but it&apos;s not the best idea. Mixing your production environment and development environment can get messy really quickly as you can make changes to one that may affect the other.&lt;/p&gt;
&lt;p&gt;For this reason, the net step is to use git to commit all of the existing changes (at this point just the initialization of the app), connect to a remote repository on GitHub, and push. For that, I will assume that you are familiar with this process and have a GitHub account.&lt;/p&gt;
&lt;h2&gt;Make updates to Astro app&lt;/h2&gt;
&lt;p&gt;With your application pushed to GitHub, you can now pull the repository down to any machine on which you would like to develop. Astro provides a rich developer experience out of the box but I encourage you to explore and see what you can make!&lt;/p&gt;
&lt;h2&gt;Push to GitHub&lt;/h2&gt;
&lt;p&gt;Once you have your application in a state that you feel comfortable with and are ready to deploy, push this new version of your code up to GitHub from your dev environment.&lt;/p&gt;
&lt;h2&gt;Deploy!&lt;/h2&gt;
&lt;p&gt;The final step is to deploy again! You can repeat this process ad infinitum. Any time you make a new version of your application, go to your server environment, pull the version you wish to deploy, rebuild your docker image (or build with a new version tag), stop your previous example, and run the new one!&lt;/p&gt;
&lt;p&gt;At this point, you have a running application! Congratulations! You have deployed an application in your local network completely from scratch! This is a huge accomplishment. But this can also be just another starting point if you&apos;d like. There are plenty of improvements that can be made to this process.&lt;/p&gt;
&lt;h2&gt;Challenges&lt;/h2&gt;
&lt;p&gt;If you want to take this a step further, here are a couple of suggestions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Look into setting up a CI/CD pipeline with something like Jenkins or Github Actions. This will eliminate the need for you to manually pull new versions of your app and make new deploys in Docker.&lt;/li&gt;
&lt;li&gt;Use Docker Compose to make more complex deploys. For example you could run another container alongside this application with a database so that you can manage persistent data in your application.&lt;/li&gt;
&lt;li&gt;Add authentication so that your application can support multiple users.&lt;/li&gt;
&lt;li&gt;Use a service like DuckDNS or some other DNS provider to get a static IP, or some other similar solution, and expose your application to the public internet.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Hopefully this walkthrough has been beneficial and you have a running application somewhere other than your development machine. This is a huge step toward understanding full-stack development. The process and environment that you&apos;ve just put in place exists as the foundation for many web applications. Granted, most processes are more complex than this. But the general principles remain the same. Continue to make changes and test the limits of Docker to see all of possibilities that exist!&lt;/p&gt;
</content:encoded></item><item><title>Bash Terminal Shortcuts</title><link>https://dondon.dev/code/bash-terminal-shortcuts</link><guid isPermaLink="true">https://dondon.dev/code/bash-terminal-shortcuts</guid><description>This is a short list of helpful terminal keyboard shortcuts that I recently came across in a Udemy class I am going through</description><content:encoded>&lt;ol&gt;
&lt;li&gt;&lt;code&gt;ctrl + L&lt;/code&gt; - Clears the terminal&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ctrl + D&lt;/code&gt; - Closes the terminal. Same as the &lt;code&gt;exit&lt;/code&gt; command&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ctrl + A&lt;/code&gt; - Returns cursor to the beginning of the terminal line&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ctrl + E&lt;/code&gt; - Move the cursor to the end of the line&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ctrl + U&lt;/code&gt; - Cuts everything before the cursor. This is a great way to clear the line if you&apos;ve written something that you want to delete&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ctrl + C&lt;/code&gt; - Stops the current command&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ctrl + Z&lt;/code&gt; - Puts the current running program to sleep&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ctrl + alt + T&lt;/code&gt; - Opens a new terminal&lt;/li&gt;
&lt;/ol&gt;
</content:encoded></item><item><title>Learning in Public: Implementing Signals</title><link>https://dondon.dev/code/learning-in-public-implementing-signals</link><guid isPermaLink="true">https://dondon.dev/code/learning-in-public-implementing-signals</guid><description>Following an article that explains how to implement signals, hopefully successfully, and then giving feedback about the result.</description><content:encoded>&lt;p&gt;In this post, I&apos;ll be going through &lt;a href=&quot;https://www.freecodecamp.org/news/learn-javascript-reactivity-build-signals-from-scratch/&quot;&gt;this article&lt;/a&gt; to understand creating signals.&lt;/p&gt;
&lt;p&gt;What I build will live &lt;a href=&quot;https://github.com/donhamiltoniii/creating-signals-from-scratch&quot;&gt;in this repository&lt;/a&gt;. Feel free to check it out if you would like!&lt;/p&gt;
&lt;h2&gt;Findings&lt;/h2&gt;
&lt;p&gt;Signals are really cool and are going to be a big part of the web moving forward I think. This sort of pub/sub architecture has always been a big part of the web. So it&apos;s increasingly important to be familiar with it. So let&apos;s dive into some of what I found interesting and applicable on a broader scale as well as some things that I will do differently in the future.&lt;/p&gt;
&lt;h2&gt;The &lt;code&gt;Signal&lt;/code&gt; Class&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;class Signal {
  constructor(value) {
    this.value = value;
    this.subscribers = [];
  }

  getValue() {
    return this.value;
  }

  setValue(newValue) {
    this.value = newValue;
    this.emit();
  }

  emit() {
    this.subscribers.forEach(subscriber =&amp;gt; subscriber(this.value));
  }

  subscribe(callback) {
    this.subscribers.push(callback);
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Encapsulating this logic into it&apos;s own class is a great idea. The real meat of what&apos;s happening here though is in that &lt;code&gt;subscribers&lt;/code&gt; property.&lt;/p&gt;
&lt;h2&gt;&lt;code&gt;createSignal&lt;/code&gt;&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;export const createSignal = value =&amp;gt; {
  const signal = new Signal(value);

  return [
    function value() {
      if (effectCallback) {
        signal.subscribe(effectCallback);
      }
      return signal.getValue();
    },
    function setValue(newVal) {
      signal.setValue(newVal);
    },
  ];
};
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;&lt;code&gt;createEffect&lt;/code&gt;&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;export const createEffect = callback =&amp;gt; {
  effectCallback = callback;
  callback();
  effectCallback = null;
};
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I am starting a series on building a reactive frontend framework similar to React and probably based more heavily on Chris Ferdinandi&apos;s &lt;a href=&quot;https://reefjs.com/&quot;&gt;Reef&lt;/a&gt; than I want it to be. But that is the matrerial through which I am going to be learning. So that&apos;s wont to happen.&lt;/p&gt;
</content:encoded></item><item><title>VS Code Balance Out</title><link>https://dondon.dev/code/vs-code-balance-out</link><guid isPermaLink="true">https://dondon.dev/code/vs-code-balance-out</guid><description>Reminding myself what balance out is in VS Code. I&apos;m happy if this helps you too.</description><content:encoded>&lt;p&gt;This article is more of a reminder than anything. &lt;a href=&quot;https://www.youtube.com/shorts/NwqhFb4B5LU&quot;&gt;This video&lt;/a&gt; explains everything about this command and how to implement it.&lt;/p&gt;
&lt;p&gt;Essentially this is a way to select an entire HTML element with a key binding instead of having to hunt through the document on your own for an opening and closing tag. Super useful.&lt;/p&gt;
</content:encoded></item><item><title>How to Structure a React Project</title><link>https://dondon.dev/code/how-to-structure-a-react-project</link><guid isPermaLink="true">https://dondon.dev/code/how-to-structure-a-react-project</guid><description>How to organize React components and projects</description><content:encoded>&lt;p&gt;One of the biggest problems we face as developers is project or directory structure. It&apos;s important to have a set structure for your projects so that as they grow, your code is well organized and easy to navigate. I recently found a way to organize React projects that I personally believe is so good that I want to share it.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Disclaimer: This sort of organization can be used in pretty much any project with minor changes based on the project.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Here is the &lt;a href=&quot;https://github.com/donhamiltoniii/how-to-structure-react-apps&quot;&gt;repo&lt;/a&gt; if you want to explore everything.&lt;/p&gt;
&lt;h2&gt;Components&lt;/h2&gt;
&lt;p&gt;Starting at the component level, what I like to do is continue to use principles of OOP in all of my JS/TS applications. But This doesn&apos;t mean we have to use Classes, Methods, and Properties. If you would like to do that and create instances in a more traditional way, that&apos;s fine. But I think that it ignores all of the great things that we get from modern JS/TS. We can still follow SOLID principles without Classes.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;component
  |-- component.tsx
  |-- hooks.ts
  |-- index.ts
  |-- styles.css
  |-- test.tsx
  |-- utils.ts
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What do each of these files do?&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;component.tsx&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Houses everything that is going to be rendered on screen by React. This file should contain as little logic as possible. If you can eliminate it entirely, all the better. Obviously that&apos;s not always popular but it should be the goal to keep the component as close to just markup as possible.&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;hooks.ts&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;For any hooks in the component that are only used in this component. Any hooks that are shared with other components should be pulled up higher into a hooks directory at the root directory or &lt;code&gt;src&lt;/code&gt; depending on how your project is structured.&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;index.ts&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Is solely our public interface for our component. Anything meant to be exported from this component gets exported from here. For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export * from &apos;./component&apos;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Those sorts of exports are all that we include here&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;styles.css&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Should be fairly self explanitory. This is where we keep styles related to our component. This can also be a JS/TS file if you&apos;re using styled components or SASS or anything else so long as it&apos;s related to styling.&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;test.tsx&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Is where we house the unit tests for our component.&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;utils.ts&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Should contain utility functions related specifically to this component. Similar to the hooks file, anything that would be shared between components should be hoisted higher.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This is by no means doctrine and if your codebase dictates something different, go for it. But the idea of encapsulating component logic into a single directory has proven to be extremely helpful in many codebases that I&apos;ve worked in. The big takeaway here is that OOP doesn&apos;t mean Classes. It is a paradigm of the craft of writing code and should be practiced to keep code clean.&lt;/p&gt;
</content:encoded></item><item><title>Proper (Re)Factoring</title><link>https://dondon.dev/code/factor-code-properly</link><guid isPermaLink="true">https://dondon.dev/code/factor-code-properly</guid><description>How to think about refactoring</description><content:encoded>&lt;p&gt;Don&apos;t factor your code too early! There are plenty of organizational patterns that are essentially universal in an application.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Having a &lt;code&gt;src&lt;/code&gt; directory&lt;/li&gt;
&lt;li&gt;&lt;code&gt;components&lt;/code&gt; - React/Next&lt;/li&gt;
&lt;li&gt;&lt;code&gt;utils&lt;/code&gt; - every project&lt;/li&gt;
&lt;li&gt;&lt;code&gt;routes&lt;/code&gt;/&lt;code&gt;views&lt;/code&gt; - web anything&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These will &lt;em&gt;probably&lt;/em&gt; exist in all of your applications/projects/whatever. Dont be afraid of using them. But let your applicaiton be abstract in the beginning. Don&apos;t rush to set a structure for how things should be organized, what should constitues a module, what should be a class (or shouldn&apos;t), making hooks, making utilities, etc. Just write the code, make the application work, WRITE THE TESTS (re-read that 1000x, get it tattooed on your body, paint it on the walls. Please. Write. Tests.), write documentation, know what it all does.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;🚨🚨🚨 BEFORE YOU COMMIT YOUR CODE!, REFACTOR!!! 🚨🚨🚨&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Or, when you do it the first time, factor. This is why testing is sooooo important. If you have tests in place for your application, you know that your code functions. If you break tests, you messed up. That&apos;s ok. You should mess up. That means you&apos;re making progress. Just make sure you don&apos;t leave anything messed up.&lt;/p&gt;
&lt;p&gt;This is the stage in the development process where you make sure things are organized properly. This is the part where you focus on &lt;strong&gt;CODE READABILITY&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Split logic out into the tiniest possible pieces. Make new functions/methods, organize modules differently, split things into utilities. But only in a way that makes sense. And let your code tell you what makes sense. Things to consider:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;WTF is this code doing? - Can you answer that quickly? Can you make a TikTok that would allow someone to confidently implement your function?&lt;/li&gt;
&lt;li&gt;Is this repetative? - Is this logic (Or similar logic) happening anywhere else? If so, combine it. Pull it into a function. Move that function up the directory tree wherever it makes sense.&lt;/li&gt;
&lt;li&gt;Is it verbose? - Can you clean it up at all? Are you over-engineering?&lt;/li&gt;
&lt;li&gt;Do my tests still reflect what I want them to? - This is &lt;em&gt;sort of&lt;/em&gt; an after refactoring thing. I say sort of because it very much &lt;strong&gt;IS&lt;/strong&gt; refactoring. But, refactoring your tests tend to happen after you refactor the corresponding code. For example:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;// Code
function camelCaseToCapitalSnakeCase(str: string): string {
  return str.replace(/[A-Z]/g, letter =&amp;gt; `_${letter}`).toUpperCase();
}

// Test
describe(&apos;camelCaseToCapitalSnakeCase&apos;, () =&amp;gt; {
  test(&apos;should convert string to capital snake case&apos;, () =&amp;gt; {
    const testString = &apos;hereIsMyCamelCaseString&apos;;
    const expected = expect(&apos;HERE_IS_MY_CAMEL_CASE_STRING&apos;);
    const result = camelCaseToCapitalSnakeCase(testString);

    expected.toBe(result);
  });
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;REFACTOR&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// Code
function camelToSnakeCase(str: string): string {
  return str.replace(/[A-Z]/g, letter =&amp;gt; `_${letter}`);
}

function capitalize(str: string): string {
  return str.toUpperCAse();
}

// Test
describe(&apos;camelToSnakeCase&apos;, () =&amp;gt; {
  test(&apos;should convert camel to snake case&apos;, () =&amp;gt; {
    const testString = &apos;hereIsMyCamelCaseString&apos;;
    const expected = expect(&apos;here_is_my_camel_case_string&apos;);
    const result = camelToSnakeCase(testString);

    expected.toBe(result);
  });
});

describe(&apos;capitalize&apos;, () =&amp;gt; {
  test(&apos;should capitalize given string&apos;, () =&amp;gt; {
    const testString = &apos;example&apos;;
    const expected = expect(&apos;EXAMPLE&apos;);
    const result = capitalize(testString);

    expected.toBe(result);
  });
});
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;While this refactoring essentially happens at the same time (or should), usually the work to the code is done, the initial test fails, the tests are updated to reflect the change to the code.&lt;/p&gt;
&lt;p&gt;Refactoring is such an important step in the development of a code base. Mostly because tech debt has a strange way of going unpaid. There are so many minor things that we convince ourselves as devs that we will come back to, or someone will, to &quot;clean up&quot; or &quot;clarify&quot;. But that rarely happens. The reality of writing code, especially new code, is that you have more context right now than anyone else, including yourself in a month, is ever going to have again. You know exactly what problem you&apos;re trying to solve and why you&apos;re doing it the way that you are. So it is your responsibility to try to capture that as much as possible for people in the future, including you. So don&apos;t let deadlines get in the way of doing the right thing. Take the extra hour or 4 or 8 to make sure this step happens. Because if you&apos;re in an environment that tracks tech debt, great. But the harsh reality is that those tickets will probably get stale before they get played. So do the work now.&lt;/p&gt;
</content:encoded></item><item><title>Accessing Next Data in Browser</title><link>https://dondon.dev/code/next-data</link><guid isPermaLink="true">https://dondon.dev/code/next-data</guid><description>Understanding data in a NEXT application</description><content:encoded>&lt;p&gt;Today&apos;s is just a quick post of a discovery from a colleague. On the project that I&apos;m currently assigned to, we are using NextJS to build some pretty amazing tech. One thing that we are constantly running up against is checking the data that we are receiving from one of the handful of APIs from which we are sourcing.&lt;/p&gt;
&lt;p&gt;Usually this involves all sorts of looking around inside of the network tab or console logging or all kinds of other work-around, hacky shit to see wtf we&apos;re getting. Which is both just bad form and, in most cases, ineffective.&lt;/p&gt;
&lt;p&gt;Until this wonderful, beautiful, simple, little one line of code came into all of our lives.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JSON.parse(document.getElementById(&apos;__NEXT_DATA__&apos;));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It turns out that next provides you the data that is being provided as props to the page in a serialized JSON object. Just another reason to love tf out of this framework. Here&apos;s an example payload that I get from my recipe site:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
  &quot;props&quot;: {
    &quot;pageProps&quot;: {
      &quot;recipes&quot;: [
        {
          &quot;title&quot;: &quot;Bacon Wrapped Jalapeño Poppers&quot;,
          &quot;prepTime&quot;: &quot;15 minutes&quot;,
          &quot;cookTime&quot;: &quot;15 minutes&quot;,
          &quot;servings&quot;: 8,
          &quot;imgUrl&quot;: &quot;/img/jalapeno-poppers.jpg&quot;,
          &quot;description&quot;: &quot;Jalapeños stuffed with cheese and wrapped with bacon.&quot;,
          &quot;notes&quot;: &quot;Mad easy. Mad delicious. Perfect side dish.&quot;,
          &quot;tags&quot;: [&quot;keto&quot;, &quot;jalapeño&quot;, &quot;cheese&quot;, &quot;cream cheese&quot;, &quot;bacon&quot;, &quot;appetizer&quot;, &quot;side dish&quot;],
          &quot;content&quot;: &quot;\n### Ingredients\n\n- 8 Jalapeños, hollowed\n- 8oz Cream Cheese\n- 8oz shredded cheese of your choice\n- 8 slices bacon\n\n### Instructions\n\n1. Cut a \&quot;T\&quot; into one side of your Jalapeños and scoop out the seeds.\n1. In a bowl, mix cream cheese and shredded cheese until throughly mixed.\n1. Preheat air frier for 10 minutes at 400°\n1. Stuff each pepper with cheese mixture and wrap with one slice of bacon. Wrap the ends of the bacon underneath so they stay together.\n1. Cook for 15 minutes at 350°\n1. Eat them all in one sitting.\n&quot;,
          &quot;slug&quot;: &quot;bacon-wrapped-jalapeño-poppers&quot;
        }
      ]
    },
    &quot;__N_SSG&quot;: true
  },
  &quot;page&quot;: &quot;/&quot;,
  &quot;query&quot;: {},
  &quot;buildId&quot;: &quot;development&quot;,
  &quot;isFallback&quot;: false,
  &quot;gsp&quot;: true,
  &quot;scriptLoader&quot;: []
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I truncated the recipe list for readability but you get the idea. Look at how easy and pretty that is! Keep this in mind whenever you&apos;re dealing with Next data. This is a game changer folx.&lt;/p&gt;
</content:encoded></item><item><title>React 18 Third Party Component Rendering Issue</title><link>https://dondon.dev/code/react-component-issue</link><guid isPermaLink="true">https://dondon.dev/code/react-component-issue</guid><description>Quick solve to an issue in React 18</description><content:encoded>&lt;p&gt;If you ever run into a build error with any package that looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;12:06:28 PM: $ yarn build
12:06:28 PM: yarn run v1.22.10
12:06:28 PM: $ next build
12:06:28 PM: info  - Checking validity of types...
12:06:32 PM: Failed to compile.
12:06:32 PM:
12:06:32 PM: ./pages/_app.tsx:6:11
12:06:32 PM: Type error: &apos;Component&apos; cannot be used as a JSX component.
12:06:32 PM:   Its element type &apos;ReactElement&amp;lt;any, any&amp;gt; | Component&amp;lt;{}, any, any&amp;gt; | null&apos; is not a valid JSX element.
12:06:32 PM:     Type &apos;Component&amp;lt;{}, any, any&amp;gt;&apos; is not assignable to type &apos;Element | ElementClass | null&apos;.
12:06:32 PM:       Type &apos;Component&amp;lt;{}, any, any&amp;gt;&apos; is not assignable to type &apos;ElementClass&apos;.
12:06:32 PM:         The types returned by &apos;render()&apos; are incompatible between these types.
12:06:32 PM:           Type &apos;React.ReactNode&apos; is not assignable to type &apos;import(&quot;/opt/build/repo/node_modules/@types/react-syntax-highlighter/node_modules/@types/react/index&quot;).ReactNode&apos;.
12:06:32 PM:             Type &apos;{}&apos; is not assignable to type &apos;ReactNode&apos;.
12:06:32 PM:   4 |
12:06:32 PM:   5 | export default function MyApp({ Component, pageProps }: AppProps) {
12:06:32 PM: &amp;gt; 6 |   return &amp;lt;Component {...pageProps} /&amp;gt;;
12:06:32 PM:     |           ^
12:06:32 PM:   7 | }
12:06:32 PM:   8 |
12:06:32 PM: error Command failed with exit code 1. (https://ntl.fyi/exit-code-1)
12:06:32 PM: info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The current fix is to add the following to your &lt;code&gt;package.json&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;}
  // ...
  &quot;resolutions&quot;: {
    &quot;@types/react&quot;: &quot;17.0.40&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>Base Path in TypeScript</title><link>https://dondon.dev/code/base-path-ts</link><guid isPermaLink="true">https://dondon.dev/code/base-path-ts</guid><description>How to update the base path in TS to reference files more easily</description><content:encoded>&lt;p&gt;Whenever working in TypeScript, we deal with importing and exporting modules in our project. This quick post is just a reminder/tutorial for how to set up a base path so that we may reference these modules in a more organized fashion.&lt;/p&gt;
&lt;p&gt;Let&apos;s begin by creating a new project. We could just create a basic TypeScript app but let&apos;s create something a little more practical. We&apos;ll be creating a simple NextJS app that uses TypeScript. This is a pretty popular stack these days since it provides a full stack environment with the (current) most popular view library.&lt;/p&gt;
&lt;p&gt;To start, let&apos;s navigate to a directory to make our project and run the following command.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npx create-next-app base-path-example --ts
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will build out a new Next app called &lt;code&gt;base-path-example&lt;/code&gt; with a directory structure that looks like this:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Inside of this project, we&apos;re going to include a deeply nested path by adding a few directories inside of pages.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;This is going to illustrate what happens when we have to bring in a component from way higher up in the directory tree. Here&apos;s what our deeply nested page looks like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { Counter } from &apos;../../../../components/counter&apos;;

export default function CounterPage() {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;Counter /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Notice that we&apos;re bringing in this &lt;code&gt;Counter&lt;/code&gt; component from the &lt;code&gt;components&lt;/code&gt; directory which is four levels up. While this certainly works, it&apos;s a little difficult to read and in an app with dozens, or even hundreds of pages, these &lt;code&gt;../&lt;/code&gt; pieces get annoying to deal with.&lt;/p&gt;
&lt;p&gt;To solve this issue, we can make a quick and easy update to our &lt;code&gt;tsconfig.json&lt;/code&gt; file which will simplify our imports throughout our entire app. Inside of &lt;code&gt;tsconfig.json&lt;/code&gt;, add the following:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;// tsconfig.json

&quot;compilerOptions&quot;: {
  // ...
  &quot;baseUrl&quot;: &quot;.&quot;,
  &quot;paths&quot;: {
      &quot;@/*&quot;: [&quot;./src/*&quot;]
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This gives us a shorthand to reference the &lt;code&gt;src&lt;/code&gt; directory. So now on any of our imports, we can just start with &lt;code&gt;@&lt;/code&gt;. Now we can revisit that deeply nested page and make the following change:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import { Counter } from &apos;@/components/counter&apos;;

export default function CounterPage() {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;Counter /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now we can reference all directories and files relative to the &lt;code&gt;src&lt;/code&gt; directory! This avoids all of the backtracking with &lt;code&gt;../&lt;/code&gt;! As small of a change as this may be, it will save TONS of time with imports and help your code look a lot cleaner in the process.&lt;/p&gt;
&lt;h2&gt;SIDE NOTE FOR FULL-STACK/API PROJECTS&lt;/h2&gt;
&lt;p&gt;If you are building something with &lt;code&gt;ts-node&lt;/code&gt; or &lt;code&gt;nodemon&lt;/code&gt;, you also need to follow &lt;a href=&quot;https://typestrong.org/ts-node/docs/paths/&quot;&gt;this section&lt;/a&gt; of the &lt;code&gt;ts-node&lt;/code&gt; docs.&lt;/p&gt;
</content:encoded></item><item><title>CSS Centering</title><link>https://dondon.dev/code/css-centering</link><guid isPermaLink="true">https://dondon.dev/code/css-centering</guid><description>How to handle centering in CSS</description><content:encoded>&lt;p&gt;Today we&apos;re going to be looking at the different ways in which you can center content in CSS. We&apos;re gonna go through a bit of a history lesson as well to illustrate just how amazing modern tools are in comparison to the shit we used to have to write as developers to achieve the same goal. We are going to be looking at examples of centering both horizontally and vertically but all of these examples can be used to accomplish each task individually.&lt;/p&gt;
&lt;p&gt;* &lt;em&gt;Only the SCSS related to positioning is included. You will see more in the CodePen.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;iframe
height=&quot;300&quot;
style=&quot;width: 100%;&quot;
scrolling=&quot;no&quot;
title=&quot;Centering Content in CSS&quot;
src=&quot;https://codepen.io/donhamiltoniii/embed/bGpxQKd?default-tab=html%2Cresult&quot;
frameborder=&quot;no&quot;
loading=&quot;lazy&quot;
allowtransparency=&quot;true&quot;
allowfullscreen=&quot;true&quot;&lt;/p&gt;
&lt;blockquote&gt;&lt;/blockquote&gt;
&lt;p&gt;See the Pen
&amp;lt;a href=&quot;https://codepen.io/donhamiltoniii/pen/bGpxQKd&quot;&amp;gt;
Centering Content in CSS
&amp;lt;/a&amp;gt;
by Don Hamilton III (
&amp;lt;a href=&quot;https://codepen.io/donhamiltoniii&quot;&amp;gt;@donhamiltoniii&amp;lt;/a&amp;gt;) on
&amp;lt;a href=&quot;https://codepen.io&quot;&amp;gt;CodePen&amp;lt;/a&amp;gt;.
&amp;lt;/iframe&amp;gt;&lt;/p&gt;
&lt;h3&gt;Centering using &lt;code&gt;display: table&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Let&apos;s take a look at the code:&lt;/p&gt;
&lt;p&gt;HTML:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;table class=&quot;table-centering&quot;&amp;gt;
  &amp;lt;tr class=&quot;table-centering__row&quot;&amp;gt;
    &amp;lt;td class=&quot;table-centering__content&quot;&amp;gt;:( why?&amp;lt;/td&amp;gt;
  &amp;lt;/tr&amp;gt;
&amp;lt;/table&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;SCSS:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.table-centering {
  &amp;amp;__row {
    text-align: center;
    vertical-align: center;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As we can see, this achieves what we want. But this is clunky and it violates a few golden rules. First of all, this isn&apos;t tabular data so our markup (HTML) isn&apos;t semantic. It&apos;s also violating separation of concerns as we&apos;re using our content layer to handle styling. In older web infrastructure, this method of styling isn&apos;t uncommon to see. Though it is &lt;em&gt;INCREDIBLY&lt;/em&gt; frowned upon. So, moving on to better options.&lt;/p&gt;
&lt;h3&gt;Centering using &lt;code&gt;transform&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Now we&apos;ll explore a better (still not best) option. This one came about once we got the &lt;code&gt;transform&lt;/code&gt; property available in browsers (2009ish). This is definitely a better way to achieve our centered goal than the previous as it allows us to semantically markup our content as well as abide by separation of concerns by keeping the positioning solely to the style (SCSS) layer. Let&apos;s take a look at the code and then go over the pros and cons:&lt;/p&gt;
&lt;p&gt;HTML:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;section class=&quot;transform-centering&quot;&amp;gt;
  &amp;lt;p class=&quot;transform-centering__content&quot;&amp;gt;:| slightly less why?&amp;lt;/p&amp;gt;
&amp;lt;/section&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;SASS:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.transform-centering {
  position: relative;

  &amp;amp;__content {
    left: 50%;
    position: absolute;
    top: 50%;
    transform: translateX(-50%) translateY(-50%);
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The first notable difference here is the markup. We only have a containing element and a contained element. Honestly, this is all we should have since we&apos;re centering one thing inside of something else. Second, it&apos;s semantic. We have a &lt;code&gt;section&lt;/code&gt;, which is properly descriptive of what it is/does and the content is enclosed in a &lt;code&gt;p&lt;/code&gt; tag which also accurtately describes what we&apos;re dealing with. These might seem like trivial details, but I assure you, for many reasons, they are not. This will be beneficial to other developers looking at your code and it will be much more descriptive for screen readers and robots (read Google bots) crawling your page to index it inside of their search algorithms.&lt;/p&gt;
&lt;p&gt;Next, let&apos;s examine the styling. There are a few more lines of code here to achieve our goal, but what is better about this solution is that everything about the positioning is encapsulated in the style layer.&lt;/p&gt;
&lt;p&gt;What I personally dislike (you should too) about this method is that it forces us to alter the &lt;code&gt;position&lt;/code&gt; attribute of both of these elements. While this isn&apos;t strictly taboo, it can cause unforeseen consequences with other style rules. It is general best practice to avoid manipulating position, &lt;strong&gt;BUT&lt;/strong&gt;, this does work. The quick explanation is that we are pushing the paragraph 50% the width and height of the container. The problem is we are pushing relative to the top left corner of the contained element. So then we are manipulating the contained element to move half of its own width and height up and to the left respectively. In so doing, we center the paragraph in the section.&lt;/p&gt;
&lt;h3&gt;Centering using &lt;code&gt;flex&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Finally, we arrive at &lt;strong&gt;THE&lt;/strong&gt; definitive answer for centering in modern web development. The answer is for sure using Flexbox. We need look no further than the code to understand why:&lt;/p&gt;
&lt;p&gt;HTML:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;section class=&quot;flexbox-centering&quot;&amp;gt;
  &amp;lt;p class=&quot;flexbox-centering__content&quot;&amp;gt;:) very much zero why?&amp;lt;/p&amp;gt;
&amp;lt;/section&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;SCSS:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.flexbox-centering {
  align-items: center;
  display: flex;
  justify-content: center;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So this technique combines all of the good parts of the previous examples while omitting all of the bad parts. First, our markup is succinct and semantic. Next, our styling is encapsulated and only needs 3 lines of code to work.&lt;/p&gt;
&lt;p&gt;This is partially why flexbox exists. It&apos;s all about positioning and ordering elements without having to worry about the content layer. This is exactly how we want our code to work. That is textbook definition of proper separation of concerns.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;BONUS&lt;/strong&gt; Centering using &lt;code&gt;grid&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;It is possible to center content inside of grid containers as well. Though, I would argue that you should use &lt;code&gt;flex&lt;/code&gt; by default, sometimes that adds superfluous code which should &lt;strong&gt;ALWAYS&lt;/strong&gt; be avoided if possible. So let&apos;s take a look at how we can achieve our goal in grid.&lt;/p&gt;
&lt;p&gt;HTML:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;section class=&quot;grid-centering&quot;&amp;gt;
  &amp;lt;p class=&quot;grid-centering__content&quot;&amp;gt;:) very much zero why? #2&amp;lt;/p&amp;gt;
&amp;lt;/section&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;SCSS:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.grid-centering {
  align-content: center;
  display: grid;
  justify-items: center;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Not much more to review here aside from the fact that we&apos;re using a different display value. The only notable difference here is the usage of &lt;code&gt;align-content&lt;/code&gt; and &lt;code&gt;justify-items&lt;/code&gt; as opposed to their Flexbox counterparts.&lt;/p&gt;
&lt;h3&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;We&apos;ve gone through a bit of a history lesson as far as how we deal with layout and positioning in our web sites/applications. The first two are here for historical reference only. Going forward, we should all be using Flexbox and Grid whenever we&apos;re dealing with layout and positioning.&lt;/p&gt;
</content:encoded></item></channel></rss>