<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ian McCall</title>
    <description>The latest articles on DEV Community by Ian McCall (@ianmcodes).</description>
    <link>https://dev.to/ianmcodes</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2661707%2Fa6094f8c-7756-411e-8356-5626c0697286.png</url>
      <title>DEV Community: Ian McCall</title>
      <link>https://dev.to/ianmcodes</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ianmcodes"/>
    <language>en</language>
    <item>
      <title>Crustacean Migration: Moving OpenClaw from Desktop to Home Lab</title>
      <dc:creator>Ian McCall</dc:creator>
      <pubDate>Tue, 24 Mar 2026 05:00:00 +0000</pubDate>
      <link>https://dev.to/ianmcodes/crustacean-migration-moving-openclaw-from-desktop-to-home-lab-4bo0</link>
      <guid>https://dev.to/ianmcodes/crustacean-migration-moving-openclaw-from-desktop-to-home-lab-4bo0</guid>
      <description>&lt;h2&gt;
  
  
  Introduction: Why Move OpenClaw to a Home Lab?
&lt;/h2&gt;

&lt;p&gt;As a personal assistant, my OpenClaw instance is a part of my daily workflow. Initially, it ran on my desktop PC, which was convenient for initial setup and testing. However, I quickly realized a limitation: my desktop doesn’t run 24/7. To save power, I typically shut it down at night, which meant my OpenClaw assistant went offline with it.&lt;/p&gt;

&lt;p&gt;My home server, which runs TrueNAS Scale, on the other hand, runs continuously. This makes it the ideal candidate for hosting services that I need available around the clock, like OpenClaw. The goal was simple: move OpenClaw from my desktop to my home server to ensure uninterrupted access and reliability.&lt;/p&gt;

&lt;h2&gt;
  
  
  My OpenClaw Setup
&lt;/h2&gt;

&lt;p&gt;Before diving into the migration, a quick overview of my OpenClaw setup. I primarily use it as a personal assistant. Its primary interface for me is Slack, allowing seamless interaction from any device where I have Slack installed.&lt;/p&gt;

&lt;h2&gt;
  
  
  Options for Running OpenClaw on TrueNAS Scale
&lt;/h2&gt;

&lt;p&gt;When considering how to host OpenClaw on TrueNAS Scale, two main options came to mind:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;App/Docker Container:&lt;/strong&gt; TrueNAS Scale has excellent support for Docker containers via its “Apps” feature. 

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pros:&lt;/strong&gt; Lightweight, easy to deploy and manage, leverages existing container infrastructure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cons:&lt;/strong&gt; Might be more complex for custom networking or specific OpenClaw dependencies that aren’t easily contained. Configuration management within a container might also require more thought.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Virtual Machine (VM):&lt;/strong&gt; Running a full-fledged operating system in a VM. 

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pros:&lt;/strong&gt; Provides a completely isolated environment, familiar setup process (like installing on a regular server), full control over the OS and network stack.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cons:&lt;/strong&gt; More resource-intensive than a container, requires managing a separate OS.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I opted for the &lt;strong&gt;Virtual Machine&lt;/strong&gt; approach. While slightly heavier on resources, it offered the greatest flexibility and control, which I felt was important for a complex application like OpenClaw that interacts with many parts of my digital life.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up the Virtual Machine
&lt;/h2&gt;

&lt;p&gt;The first step was to prepare the virtual machine on my TrueNAS Scale host. TrueNAS makes this easy to do from the admin UI.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Create the VM:&lt;/strong&gt; When setting up the network I attached it to the same interface the NAS uses for communication on my home network. This allows the VM to get it’s own IP on the network so I can ssh into it from my desktop. One side effect of this however is that it can’t route to the TrueNAS host without a separate bridge interface.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Install OS (Debian):&lt;/strong&gt; I created a new VM and installed a minimal Debian instance. Debian is a stable and lightweight choice, and I already had an ISO downloaded.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Setting Up a Network Bridge:&lt;/strong&gt; To allow the VM to communicate directly with services on the host, I configured a network bridge on the TrueNAS host. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the network configuration I created a new interface with the type “Bridge” and named it &lt;code&gt;br0&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Importantly, I didn’t add any other network interfaces as bridge members. Because I want this to just be for communication between the VM and the host&lt;/li&gt;
&lt;li&gt;Under aliases, I added the IP address &lt;code&gt;10.0.0.1/24&lt;/code&gt;. This sets the IP of the host and the subnet mask for the network.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Adding the Bridge to the VM:&lt;/strong&gt; From the host I added a new NIC device to the VM, configured to attach to &lt;code&gt;br0&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Network Configuration:&lt;/strong&gt; Inside the VM, I reconfigured the networking so that the interface attached to the bridge used a static IP (&lt;code&gt;10.0.0.2&lt;/code&gt;), and the interface attached to my home network used DHCP.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Install Dependencies:&lt;/strong&gt; Once the network was solid, I installed all the necessary dependencies for OpenClaw (Node.js, Python, git, etc.) within the Debian VM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Install OpenClaw:&lt;/strong&gt; Finally, I installed OpenClaw with &lt;code&gt;npm i -g openclaw&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Moving the Configuration
&lt;/h2&gt;

&lt;p&gt;With the new OpenClaw instance installed and the network ready, it was time to migrate my existing configuration and memory.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Copy Config Folder to NAS:&lt;/strong&gt; I copied the entire &lt;code&gt;.openclaw&lt;/code&gt; folder from the old desktop instance to a shared folder on my NAS. That folder is shared using both SMB (Windows file sharing) and NFS.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;NFS Mount:&lt;/strong&gt; On the Debian VM, I set up the NFS mount to access the shared folder on the NAS (using the bridge ip).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Copy Config Folder to VM:&lt;/strong&gt; I then copied the &lt;code&gt;.openclaw&lt;/code&gt; folder from the NAS to my home directory on the VM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Fixing Paths:&lt;/strong&gt; The &lt;code&gt;openclaw.json&lt;/code&gt; config file had some hardcoded paths. I updated these to reflect the new directory structure on the Debian VM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Setting Up Allowed Origins:&lt;/strong&gt; For the web UI and API to function correctly, I updated the &lt;code&gt;gateway.controlUi.allowedOrigins&lt;/code&gt; setting in OpenClaw’s configuration to include the new Nginx reverse proxy URL (e.g., &lt;code&gt;https://claw.truenas.local:30022&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Call the Doctor:&lt;/strong&gt; I then used &lt;code&gt;openclaw doctor --fix&lt;/code&gt; to try to catch and fix any configuration issues I might have missed.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Nginx Reverse Proxy to Expose Web UI
&lt;/h2&gt;

&lt;p&gt;OpenClaw’s web UI requires that you connect to it either using localhost or a secure (https) context.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Nginx Proxy Manager App:&lt;/strong&gt; I leveraged the Nginx Proxy Manager app available on TrueNAS Scale. This makes managing reverse proxies and SSL certificates incredibly easy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Self-Signed Certificate:&lt;/strong&gt; Because I’m only using the web UI on my home network I opted for a self-signed certificate over using LetsEncrypt. I generated a self-signed SSL certificate on my desktop and uploaded it to the Nginx Proxy Manager.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Setup the Proxy Host:&lt;/strong&gt; In the Nginx Proxy Manager I setup a proxy host. I chose the domain name &lt;code&gt;claw.truenas.local&lt;/code&gt; and configured it to forward to the OpenClaw web UI on the VM over the bridge (&lt;code&gt;10.0.0.2:18798&lt;/code&gt;)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Hosts File Entry:&lt;/strong&gt; To make &lt;code&gt;claw.truenas.local&lt;/code&gt; resolve correctly, I added an entry to my local machine’s &lt;code&gt;hosts&lt;/code&gt; file, mapping the domain to the TrueNAS host’s IP address.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Starting the Gateway and Verification
&lt;/h2&gt;

&lt;p&gt;The moment of truth!&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Starting the Gateway:&lt;/strong&gt; I started the OpenClaw gateway service on the Debian VM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Checking That Everything Works:&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Migrating my OpenClaw instance to my TrueNAS Scale home server has been a significant upgrade. My personal assistant is now available 24/7, providing consistent support without relying on my desktop being powered on. While the VM approach required a bit more setup initially, the flexibility and reliability it offers are well worth the effort. Now, OpenClaw is truly a persistent companion in my home lab ecosystem.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>openclaw</category>
      <category>vm</category>
    </item>
    <item>
      <title>Using ChatGPT to Improve My Personal Brand</title>
      <dc:creator>Ian McCall</dc:creator>
      <pubDate>Wed, 11 Mar 2026 05:00:00 +0000</pubDate>
      <link>https://dev.to/ianmcodes/using-chatgpt-to-improve-my-personal-brand-1ia0</link>
      <guid>https://dev.to/ianmcodes/using-chatgpt-to-improve-my-personal-brand-1ia0</guid>
      <description>&lt;p&gt;My personal branding sucked. My banner was just a picture of me at a conference from about 10 years ago and my “logo” was just some angle brackets and a slash in a hexagon. It’s not bad, but it’s old, tired, and I want something that just looks a lot cooler. Something with some more energy and more professional and polished.&lt;/p&gt;

&lt;p&gt;The problem is that I’m not an artist or designer, I’m an engineer. I could hire a professional to create some assets for me. But that would cost money, and my personal blog and social media don’t generate any money. I just wouldn’t make any sense for me to spend a lot of money on something that isn’t going to make any money.&lt;/p&gt;

&lt;p&gt;&lt;a href="/assets/images/banner_old.jpg"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiybgbnkwzvq5eity8vbw.jpg" alt="Old Banner" width="800" height="369"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Computer, Make It For Me
&lt;/h2&gt;

&lt;p&gt;Enter the power of AI image generation (specifically ChatGPT in my case). In just a few prompts I was able to get a brand new cool, modern logo and banner I could use for my website and LinkedIn! And here are the exact prompts I used!&lt;/p&gt;

&lt;p&gt;&lt;a href="/assets/images/ChatGPT%20Image%20Mar%201,%202026,%2011_17_57%20PM.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4gt2i6zovv56timadste.png" alt="Brand Board" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;p&gt;In the first prompt I’m telling ChatGPT&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Who I am, professionally&lt;/li&gt;
&lt;li&gt;What I want&lt;/li&gt;
&lt;li&gt;How I am going to use it&lt;/li&gt;
&lt;li&gt;And to ASK ME QUESTIONS!&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;I’m a full-stack software engineer, and I have a personal website, &lt;a href="https://ianmccall.codes" rel="noopener noreferrer"&gt;https://ianmccall.codes&lt;/a&gt;. I want to create some new logos and banners that I can use on my website and social media for my personal brand. Generate a new logos for me. Ask any questions you need to make the best results.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As anybody that has used LLMs will tell you, telling it to ask questions / make a plan, will get you a much better result. And I think the questions it asked were good. It asked me 6 questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What “Brand vibe” I wanted.&lt;/li&gt;
&lt;li&gt;“Name style”. Basically whether I wanted to emphasize my name, initials, URL, etc.&lt;/li&gt;
&lt;li&gt;“Color direction”&lt;/li&gt;
&lt;li&gt;Symbol Ideas&lt;/li&gt;
&lt;li&gt;Usage (which social media sites I planed to use it on.)&lt;/li&gt;
&lt;li&gt;“Personality”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And for each it was able to give me some examples to help me understand what it was asking.&lt;/p&gt;

&lt;p&gt;After answering the questions, it was able to generate the branding image above! And for me, that was perfect, way better than I could have done on my own! Could a professional designer or artist have done better? Probably yes! But that would have cost me a not insignificant about of money and time. And this was quick, easy, and cheap.&lt;/p&gt;

&lt;h2&gt;
  
  
  Refinements
&lt;/h2&gt;

&lt;p&gt;The next thing to do was to try to get the AI to extract the banner and a logo from the image so I could use them. I wasn’t sure how this part would go, because there was no guarantee that it would be the same as what it just generated. So I asked it:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Please generate a larger version of the banner that I can upload to LinkedIn&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And I was pleasantly surprised to see that it did!&lt;/p&gt;

&lt;p&gt;&lt;a href="/assets/images/banner_2026.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0lkk92vnirwqh6oo894e.png" alt="New Banner" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then I wanted to extract one of the icons&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Please generate a PNG of the pure circuit icon, that can be uploaded to LinkedIn&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="/assets/images/logo_2026_color.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff5iohku6yqpsx87fde6n.png" alt="Full Color Logo" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One note about the icon: I should have asked it to generate it with a transparent background. I ended up using GIMP to remove the background, because I ran out of tokens and didn’t want to wait or pay for plus.&lt;/p&gt;

&lt;p&gt;I also had it generate a version without the gradient:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Good, now generate a version without the gradient. Just black lines&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="/assets/images/logo_2026_bw.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj9ozm6sfj1n85br4c51y.png" alt="BW Logo" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then I also had it generate CSS so I could replicate the colors and gradient on my website. It was even able to generate a pure CSS animation of the gradient that I applied to the navigation bar on my site.&lt;/p&gt;

&lt;h2&gt;
  
  
  It’s Ok. We all make mistakes
&lt;/h2&gt;

&lt;p&gt;However not everything worked quite so easily. I also asked it to generate SVG versions of the logos. The results were far from accurate.&lt;/p&gt;

&lt;p&gt;&lt;a href="/assets/images/logo_post/svg_fail.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs6h95fqluiwxk998ezgr.png" alt="SVG Fail" width="512" height="512"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I suspect that it’s because, the image generation is handled by a stable diffusion type model where as creating the SVG is handled by a code generation model. I also tried taking the black and white image, starting a new chat, uploaded the image and asked it to generate an SVG. It got closer, but still far from accurate. I even asked Gemini to give it a go, and it just straight up refused to try.&lt;/p&gt;

&lt;p&gt;Also, some time later after updating my site and LinkedIn, I decided I wanted to extract one of the monogram logos that it had generated before.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Can you generate a png of the IM monogram icon, with a transparent background?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="/assets/images/logo_post/Monogram.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbtiegzpu2m8ri9xkteik.png" alt="Monogram" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You may notice that it looks similar to, but not exactly what it generated before. This is likely that the way the image generation model works is non deterministic. Even if you pick up the same session, or branch the conversation from when you first generated the sample image, the sate of the image generator is not preserved.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaways?
&lt;/h2&gt;

&lt;p&gt;Even with these issues, I’m still very happy with what it was able to generate for me. The result is much more polished and professional looking than I would have been able to generate on my own. This is the part where AI evangelists would start crowing about how “no one needs designers or artists anymore”, but I know that just isn’t true. The result I got, while much better than I could do alone, is also derivative and a little generic. And it has that same purple gradient that AIs seem to default to when designing for the web. A competent artist/designer could make something much better.&lt;/p&gt;

&lt;p&gt;A professional artist or designer can (and should) demand good professional money. AI tools are not a replacement for a good professional. But these tools can help bridge the gap for those of us that don’t have the skills, or the money to pay someone that has the skill. I won’t call my self a designer but, with these tools, I can generate something that is good enough for me.&lt;/p&gt;

</description>
      <category>chatgpt</category>
      <category>ai</category>
      <category>images</category>
    </item>
  </channel>
</rss>
