<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Lee Nathan - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Lee Nathan - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 24 May 2026 22:23:51 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/author/leetheguy/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Build an Autonomous AI Agent with n8n and Decapod ]]>
                </title>
                <description>
                    <![CDATA[ I tried out Open Claw two weeks ago. I loved the potential, but did not enjoy the tool itself. I, like many others, struggled with the installation process. And working from Linux, the Mac specific or ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-build-an-autonomous-ai-agent-with-n8n-and-decapod/</link>
                <guid isPermaLink="false">69b1ce1f6c896b0519c1c8f5</guid>
                
                    <category>
                        <![CDATA[ agentic AI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ n8n ]]>
                    </category>
                
                    <category>
                        <![CDATA[ AI ]]>
                    </category>
                
                    <category>
                        <![CDATA[ automation ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Lee Nathan ]]>
                </dc:creator>
                <pubDate>Wed, 11 Mar 2026 20:18:39 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/uploads/covers/5e1e335a7a1d3fcc59028c64/d27ea304-5db6-4172-823d-3f6aa0612d38.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>I tried out Open Claw two weeks ago. I loved the potential, but did not enjoy the tool itself.</p>
<p>I, like many others, struggled with the installation process. And working from Linux, the Mac specific orientation added extra pitfalls. It wasn't always clear whether configuration and management should be done in the docs, the CLI, or the interface.</p>
<p>I found the UI unintuitive and it left me wondering if it wasn't just a dev placeholder. The color choice in particular was especially harsh. All the red tricked the eye and made white text appear green. It also made everything seem like an error message.</p>
<p>I couldn't make heads or tails of the organization and structure. Workspaces, agents, and sessions are all terms I'm familiar with and understand. But the way Open Claw implements them made no sense to me.</p>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/675ce1d600925897ba44d754/0816135a-a80f-4f56-819a-9c82920f0245.png" alt="A simple n8n workflow that clearly shows how telegram can be connected to an AI agent." style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>Open Claw started as a way to connect a chat tool to an AI. I did that eight months ago with n8n. It's literally only a few nodes. It was so easy that I didn't think anything of it. In my opinion, Open Claw isn’t actually all that special. There’s no part of it that stands out as unique, except for the approach. It’s the Flappy Bird of the agentic AI world.</p>
<p>So I set out to make my own. And within a few hours, I'd whipped up a simple working prototype vibe-coded with Python and connected to Open WebUI (OWUI).</p>
<p>But I wanted to see what prompt OWUI was sending the agent, exactly. Now, if I was actually a Python guy, I would have done some console output. But instead, I went for my favorite tool: n8n (a powerful low-code automation system). And that's where things got interesting.</p>
<h2 id="heading-about-this-handbook">About This Handbook</h2>
<p>This handbook will introduce you to agentic AI creation using a hands-on approach and a starter project I created called Decapod.</p>
<p>Decapod is not a self-contained SaaS offering. There is no part of it that is black boxed and unavailable to hack on. Decapod is a collection of <code>docker-compose.yml</code> containers, scripts, AI agent prompts, and n8n workflows that work together to help give you a leg up on your path to building your own agentic AI empire.</p>
<p>Concepts and technologies you'll be introduced to and using:</p>
<ul>
<li><p>Agentic AI with tools and skills</p>
</li>
<li><p>Docker containers with Docker Compose</p>
</li>
<li><p>Open WebUI</p>
</li>
<li><p>n8n</p>
</li>
<li><p>S3 and MinIO</p>
</li>
<li><p>Caddy</p>
</li>
<li><p>Postgres</p>
</li>
</ul>
<p>For a list of required skills, services, and tools, please check out the "Requirements and Processes" section.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a href="#heading-decapod-the-diyers-dream-agent">Decapod - The DIYer's Dream Agent</a></p>
</li>
<li><p><a href="#heading-how-decapod-works">How Decapod Works</a></p>
<ul>
<li><p><a href="#heading-core-engine">Core Engine</a></p>
</li>
<li><p><a href="#heading-supakitchen-supabase-on-a-budget">Supakitchen - Supabase on a Budget</a></p>
</li>
<li><p><a href="#heading-open-webui-ai-chat-with-all-the-bells-and-whistles">Open WebUI - AI Chat With All the Bells and Whistles</a></p>
</li>
</ul>
</li>
<li><p><a href="#heading-requirements-and-processes-tools-i-use-and-recommend">Requirements and Processes - Tools I Use and Recommend</a></p>
<ul>
<li><a href="#heading-the-checklist">The Checklist</a></li>
</ul>
</li>
<li><p><a href="#heading-assembling-the-dream-team-ikea-style">Assembling the Dream Team - Ikea Style</a></p>
<ul>
<li><p><a href="#heading-accessing-your-vps-with-cursor-and-ssh">Accessing Your VPS With Cursor and SSH</a></p>
</li>
<li><p><a href="#heading-installing-and-configuring-the-docker-containers">Installing and Configuring the Docker Containers</a></p>
</li>
</ul>
</li>
<li><p><a href="#heading-configuration-and-wiring">Configuration and Wiring</a></p>
<ul>
<li><p><a href="#heading-initiate-the-database">Initiate the Database</a></p>
</li>
<li><p><a href="#heading-a-little-minio">A Little MinIO</a></p>
</li>
<li><p><a href="#heading-adding-the-workflows">Adding the Workflows</a></p>
</li>
<li><p><a href="#heading-getting-started-with-n8n">Getting Started With n8n</a></p>
</li>
<li><p><a href="#heading-now-get-owui-to-talk-to-decapod">Now, Get OWUI to Talk to Decapod</a></p>
</li>
<li><p><a href="#heading-there-was-supposed-to-be-an-earth-shattering-kaboom">There Was Supposed to Be an Earth Shattering Kaboom</a></p>
</li>
</ul>
</li>
<li><p><a href="#heading-the-ever-present-hello-world">The Ever-Present "Hello World"</a></p>
</li>
<li><p><a href="#heading-into-the-future">Into the Future!</a></p>
<ul>
<li><p><a href="#heading-a-work-in-progress">A Work in Progress</a></p>
</li>
<li><p><a href="#heading-adding-your-own-skills-limitless-potential">Adding Your Own Skills - Limitless Potential</a></p>
</li>
<li><p><a href="#heading-future-plans">Future Plans</a></p>
</li>
</ul>
</li>
<li><p><a href="#heading-got-questions-meet-captain-finn">Got Questions? Meet Captain Finn!</a></p>
</li>
</ul>
<h2 id="heading-decapod-the-diyers-dream-agent">Decapod – The DIYer's Dream Agent</h2>
<p>I'll be honest. I'd never even considered the security issues with Open Claw at first. But they're enormous! Let's open a giant hole in our server and give a fledgling alien intelligence root access and all of our API keys. What could possibly go wrong?</p>
<p>Decapod isn't a monolithic app. It's a collection of tools and n8n workflows that give you complete control over your agent and its tools. It's a framework to give <a href="https://monday.com/appdeveloper/blog/citizen-developer/">citizen developers</a> a leg up.</p>
<p>By switching to n8n, I accidentally solved a ton of issues and made a far superior (in my opinion) project:</p>
<ul>
<li><p>Double (or triple if you choose to host in a VPS) sandboxed security. My agent lives inside of n8n inside of a Docker container inside of a VPS.</p>
</li>
<li><p>The agent never sees a single API key or even ever needs to know exactly how you're connecting services. Credentials are handled by n8n.</p>
</li>
<li><p>Universal access – I prefer OWUI. But literally anything that can connect to a standard OpenAI API endpoint can connect to Decapod.</p>
</li>
<li><p>Over 1,000 integrations – What n8n does best is connecting any API to any other API via drag-and-drop nodes. And there are more than <a href="https://community.n8n.io/t/master-list-of-every-n8n-node/155146">1,000 of them</a>.</p>
</li>
<li><p>No more sketchy skills – Decapod uses skills, but they have to actually be connected to n8n workflows and nodes to work.</p>
</li>
</ul>
<p>More problems Decapod solves:</p>
<ul>
<li><p>Fewer tokens burned – Decapod maintains a clean boundary between what's best handled with code/logic and what's best handled by AI.</p>
</li>
<li><p>No endless loops and hung jobs – Decapod uses a jobs and tasks system that the AI can manage. So if it sees that a task has failed, it can change tasks or suspend the job.</p>
</li>
<li><p>HITL (Human In The Loop) – You can add a HITL sub-workflow before any AI skill to give them permission to proceed or not.</p>
</li>
<li><p>An MVP you can trust – The core Decapod system is just an MVP. But it's built on exclusively mature, open source, enterprise ready solutions: n8n, Open WebUI, Docker, Caddy, Postgres, and MinIO.</p>
</li>
</ul>
<h2 id="heading-how-decapod-works">How Decapod Works</h2>
<p>Decapod is middleware that acts like an OpenAI API. But it intercepts the API call and does agent work with the real API.</p>
<p>The OpenAI API standard is the most widely used in the industry. Almost every tool, like Open WebUI, Zed, and Obsidian have ways to connect to the OpenAI standard. So those tools can also connect to Decapod.</p>
<p>Decapod itself can connect to any API and pass available models through to other tools. I strongly prefer and recommend OpenRouter. OpenRouter also uses the OpenAI standard, but lets you connect to hundreds of mainstream and indie models under the same pricing system. Decapod is configured to work with OR out of the box.</p>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/675ce1d600925897ba44d754/da54b254-62b5-4e4a-b5d3-b1de7dd5f0fe.png" alt="An n8n workflow with advanced routing." style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>This is an image of the Decapod agent tool router – one of the key n8n workflows in Decapod.</p>
<h3 id="heading-core-engine">Core Engine</h3>
<p>Decapod consists of an agent with tools and skills. By tools, I mean the agentic tools that an AI can access to perform tasks as part of the API. And by skills, I'm referring to <a href="https://agentskills.io/home">Anthropic's Agent Skills standard</a>. It's the same skills standard used by Open Claw.</p>
<p>The Decapod agent has a limited, immutable set of tools for managing Decapod's state and job queue. One tool is used to call skills. Skills are dynamic and you can add as many as you like mid-flight.</p>
<p>Each skill consists of core instructions, followed by JSON specs. The agent builds a skill request based on the JSON and calls the use_skill tool to have it executed. Then Decapod calls a sub-workflow with a name that matches the skill and sends it the JSON.</p>
<p>One skill = one sub-workflow. JSON specs = sub-workflow's expected input.</p>
<p>When Decapod receives a user message, it passes it to the agent. If it's just a message, the agent responds. If it's a call to action, the agent picks a tool and gets to work.</p>
<p>Decapod loops through each job in the queue, handling the agent's tool calls and passing it back the results. When the agent is done, it concludes the job and stops sending tool calls. The final message is passed back to the user.</p>
<h3 id="heading-supakitchen-supabase-on-a-budget">Supakitchen – Supabase on a Budget</h3>
<p>I'm a huge fan of Supabase. It's all the fun of Firebase, except with data normalization. But I'm self-hosting Decapod because paying $20 per month for each of five or more services doesn't sit right with me.</p>
<p>As a mad scientist, I like to be able to try different tools without dealing with the freemium hoops. So I'm running Decapod on a Hetzner VPS with 8 gigs of RAM for about $18 per month. Those 8 gigs go really far in the self-hosted world, but Supabase is heavy.</p>
<p>What I really wanted was to give my agent file access and a database. I accomplished that with MinIO and Postgres. No real-time data, but my agent is async anyway. And agent authentication is done through n8n. So it's good enough.</p>
<p>But you do you! Decapod can work with any S3 compatible file store and any Postgres database. So if you want to use Supabase instead, go for it!</p>
<h3 id="heading-open-webui-ai-chat-with-all-the-bells-and-whistles">Open WebUI – AI Chat With All the Bells and Whistles</h3>
<p>You can use chat tools, like Discord, Telegram, Slack, and others, to chat with your AI easily enough. But if you want multiple sessions or to use different models, it can be tricky.</p>
<p>The easiest tool to set up and work with, by far, is Telegram. You get chat, UI elements, and even embedded apps without having to host your own server, like you do with Discord. I once used it to create a HITL lead qualification tool in a few hours.</p>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/675ce1d600925897ba44d754/2f6501bc-b72e-4b69-bc7d-662d91d8746f.jpg" alt="A Telegram session showing buttons and commands for a lead gen system." style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>BUT! While Telegram and friends do get the job done, if you want a new session you have to create a new bot for each and every one. If you want to switch models, you need to add /slash commands. If you want context management, you have to handle that server side.</p>
<p>That's why I prefer Open WebUI. OWUI gives you everything you expect from all of the best mainstream AI offerings, but with a direct tap to the API.</p>
<ul>
<li><p>It works great on browser and mobile as a progressive web app (PWA).</p>
</li>
<li><p>You can mod it with Python.</p>
</li>
<li><p>It has many ways to manage and supply context, including nested projects/folders and RAG support.</p>
</li>
<li><p>You can collaboratively work on notes with AI.</p>
</li>
</ul>
<p>Those are a few of my favorite features, but there are <a href="https://docs.openwebui.com/features/">so many more</a>. Why reinvent the wheel when the absolute best solution already exists?</p>
<h2 id="heading-requirements-and-processes-tools-i-use-and-recommend">Requirements and Processes – Tools I Use and Recommend</h2>
<p>Welcome to my lab-or-a-tory. We're out there on the fringes of agentic AI now. Doing weird experiments by stitching together pieces and parts. Let me show you how I work and tell you where you can and can't stray from my process.</p>
<p>Decapod is a finished MVP and should work right out of the box with minimal headache. But it doesn't have more than a few skills yet. So you'll need to build your own until it takes off. Fortunately, your Decapod agent can help.</p>
<h3 id="heading-the-checklist">The Checklist</h3>
<p><strong>Skills:</strong></p>
<ul>
<li><p>✅ A generalist's mindset, problem-solving skills, and a sense of adventure.</p>
<ul>
<li><p>You don't have to be an expert at anything to install Decapod. I'm not, and I built it.</p>
</li>
<li><p>But you do have to be comfortable with many different technologies.</p>
</li>
</ul>
</li>
<li><p>✅ The command line, Docker, and probably Node. Decapod is self hosted. So you'll need to get your hands a bit dirty.</p>
</li>
<li><p>✅ The ability to read and write a little JavaScript. This helps a lot with n8n code nodes to give it more utility.</p>
</li>
<li><p>✅ Familiarity with JSON and APIs. Everything in n8n is about passing JSON from node to node. And n8n is nothing if not a universal API connector.</p>
</li>
</ul>
<p><strong>Services:</strong></p>
<ul>
<li><p>✅ A domain name with DNS access.</p>
<ul>
<li><p>This is critical for n8n to work properly due to CORS and security issues.</p>
</li>
<li><p>Also, the OWUI PWA doesn't work when hosted through an IP. It's just a web page at that point.</p>
</li>
<li><p>Plus, it's just better for security overall with https support.</p>
</li>
<li><p>If cost is an issue, you can get an <a href="https://gen.xyz/">all-digit domain name from gen.xyz</a> for $0.99. Seems legit, but I haven't tried it myself.</p>
</li>
</ul>
</li>
<li><p>✅ A dedicated VPS with SSH access. (SSH access should be standard for any VPS.)</p>
<ul>
<li><p>You can technically host this on your own PC if you know it will be running 24/7. But using a VPS will give you peace of mind and avoid complicating your PC.</p>
</li>
<li><p>Big-name solutions like AWS and Google Cloud can wind up going off the rails and costing you big bucks if you don't know exactly what you're doing. Better to stick with less enterprise-oriented offerings. I've used the following:</p>
<ul>
<li><p><a href="https://www.hetzner.com/">Hetzner</a> – My current personal favorite. Germany based. High quality and affordable pricing with a few American servers. Even more affordable with European servers.</p>
</li>
<li><p><a href="https://www.digitalocean.com/">Digital Ocean</a> – US based. Can't go wrong. Decent prices. Many offerings. Almost exclusively American servers.</p>
</li>
<li><p><a href="https://webdock.io/en">Webdock</a> – Denmark based. The most affordable of the bunch.</p>
</li>
</ul>
</li>
</ul>
</li>
<li><p>✅ An OpenRouter account. OR provides a universal interface for hundreds of AI models. There's no freemium upsell, like with Hugging Face, but there is a percentage add on when you buy credits/tokens. I feel like it's worth the extra fee to be able to easily swap from Claude to Kimi to GPT to DeepSeek as I please without more keys, more accounts, and more wiring. But this is optional. You can plug Decapod right into Kimi or Gemini and just leave it there if you like.</p>
</li>
</ul>
<p><strong>Tools:</strong></p>
<ul>
<li><p>✅ Cursor, or similar. I love Cursor. It matches my hands-on style. If you're freestyling and dreaming something into creation as you build it, AI will <strong>always</strong> take the wrong path if you take your hands off the wheel. Cursor lets me be in charge and play director while the AI does the heavy lifting and saves me from hours of Googling and digging through 10-year-old questions on Stack Overflow. Especially with the command line stuff. I could not have knocked out Decapod in two weeks without it. But it couldn't have built Decapod at all without me.</p>
</li>
<li><p>✅ Another AI bestie to help you dream, plot, and plan. Cursor is great, but very utilitarian. I always have a session open with a running commentary about my work. I'm constantly feeding it context and leaning on it to get a fresh perspective and solve more esoteric issues, like debugging n8n flow problems, for example. I use Claude for absolutely everything. It has the most natural conversational flow, it's good at taking meta instructions regarding its behavior, and it always has an eye on accuracy – very reliable.</p>
</li>
</ul>
<h2 id="heading-assembling-the-dream-team-ikea-style">Assembling the Dream Team – Ikea Style</h2>
<p>Here are the pieces and parts you'll find in your Dekkaplonkën Ikea flat pack (the GitHub repo).</p>
<ol>
<li>Four Docker containers containing five services with docker-compose files. Just heat and serve.</li>
</ol>
<ul>
<li><p>Infrastructure: Caddy for routing and SSL certificates for https security.</p>
</li>
<li><p>Infrastructure: Postgres for all your data needs.</p>
</li>
<li><p>MinIO: An S3 compatible file storage system.</p>
</li>
<li><p>n8n: The ultimate automation tool.</p>
</li>
<li><p>Open WebUI: The ultimate AI chat interface.</p>
</li>
<li><p>SQL tables</p>
<ul>
<li><p>A table for the decapod state.</p>
</li>
<li><p>A table for jobs, tasks, and tool chat history.</p>
</li>
</ul>
</li>
<li><p>S3 Files and Folders – Agent Templates</p>
<ul>
<li><p>Four starter skills (two actually implemented in n8n).</p>
</li>
<li><p>Two instructional files, including the persona and skill definitions.</p>
</li>
</ul>
</li>
<li><p>n8n Workflows (6,889 lines of pure JSON)</p>
<ul>
<li><p>API Middleware: The entry and exit point that manages the session and loops.</p>
</li>
<li><p>AI Tool Router: Executes your agent's tool requests.</p>
</li>
<li><p>Construct Message History: Injects instructions into your agent's chat history.</p>
</li>
<li><p>Get Job Queue: A one-off database call that gets active jobs ordered by priority and creation date (First In First Out).</p>
</li>
<li><p>Utility Workbench: A place for testing and managing your flows. Currently contains a Skill assembly jig.</p>
</li>
<li><p>Worker: Loops over job queues, talking to the agent and calling the tool router with its responses.</p>
</li>
<li><p>A write-file skill and a research-recipes skill.</p>
</li>
<li><p>A couple more placeholders. (Decapod is an MVP)</p>
</li>
</ul>
</li>
<li><p>Also</p>
<ul>
<li><p>A Docker cheatsheet.</p>
</li>
<li><p>A script to generate agents from the template.</p>
</li>
<li><p>A destructive script to upload local agent files to your S3 account by overwriting existing files. Good for dev. Bad if you let your agent start modding their own instructions.</p>
</li>
<li><p>Scripts to start and stop all Docker containers at once.</p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-accessing-your-vps-with-cursor-and-ssh">Accessing Your VPS With Cursor and SSH</h3>
<p>SSH is the standard way to access any server and has been forever. But working through a terminal can be slow and plodding. Fortunately, there's a better way.</p>
<p>Connect to the server with Cursor, VS Code, Antigravity, or whatever you use. This gives you:</p>
<ul>
<li><p>Multiple terminals to access the remote server.</p>
</li>
<li><p>The ability to view localhost servers as if they were on your own machine via port forwarding.</p>
</li>
<li><p>Drag and drop folder and file management.</p>
</li>
<li><p>No more Nano, Vim, or Emacs (unless you want to).</p>
</li>
<li><p>And the best part! Cursor can do all the remote file system work for you, including troubleshooting servers and containers, writing scripts for automating common tasks, and helping you hash out actionable plans.</p>
</li>
<li><p>(Cursor can also connect to your Decapod!)</p>
</li>
</ul>
<p>Every VPS provider will have their own way of managing SSH access. They usually make adding them part of the sign up process.</p>
<p>Generating and managing keys is a pretty well-paved path and I won't go over it. It's a good job for Cursor, if you need help.</p>
<p>However! I use Bitwarden for SSH key generation and management. They still need to be stored locally for tools on your computer to access. But it's nice to have them in a single secure location.</p>
<p>VS Code requires an extra plugin to access a remote server. Cursor comes with it preinstalled. Just click <code>Connect via SSH</code>, set up your connection, and you're good to go.</p>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/675ce1d600925897ba44d754/36c686e7-2d7b-43a9-9078-98a5dd2af5be.png" alt="The cursor launch screen with a button to &quot;Connect via SSH.&quot;" style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>📝 Side note: I was on the paid plan when I started, I swear. I tend to switch services a lot as new models are released and I discover different tools and options. But I only ever pay for 2 or 3 at a time.</p>
<p>I got about halfway through this article when Cursor expired. But I'm trying the new Gemini 3 models and switched to Antigravity mid-flight rather than re-up cursor.</p>
<h3 id="heading-installing-and-configuring-the-docker-containers">Installing and Configuring the Docker Containers</h3>
<p>Finally! After a novella's worth of lead-up, we, at long last, get to the actual installation. That will be shared in the next article – have a good night! Just kidding, please put down the brick.</p>
<p>Once you've SSHed in to a VPS, a Raspberry Pi with Ubuntu, or a Virtual Machine, you're ready to get started. I'm going to assume you know how to install tools like Docker and Node on your system and not go into a lot of detail. Ask your friendly neighborhood AI for help if you get stuck.</p>
<p>💡 Important! If you haven't already, get your domain name and open up the DNS page. You'll want to redirect "A" records to your IP for each relevant service.</p>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/675ce1d600925897ba44d754/c381b917-a731-41bc-a62c-923646c87ae3.png" alt="DNS records for four subdomains." style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>Start by cloning the Decapod repo.</p>
<pre><code class="language-shell">git clone https://github.com/leetheguy/decapod.git
</code></pre>
<p><code>cd decapod</code> and create your Docker network.</p>
<pre><code class="language-shell">docker network create web
</code></pre>
<p>Now we're going to go into each of the four Docker folders, configure them, and fire them up, starting with infrastructure.</p>
<p><code>cd infrastructure</code> <code>cp .env.example .env</code></p>
<p>Alternatively, you can move the files to rename them or just click on the file in the UI and <code>F2</code> to rename it. Whatever floats your goat 🐐.</p>
<p>Now edit the new <code>.env</code> file. You can get the data folder path by clicking on the infrastructure folder and <code>Ctrl/Cmd+Alt+C</code>. The rest is up to you. I used Bitwarden to generate a password here.</p>
<p>Next, copy the Caddyfile template into its own file.</p>
<p><code>cp caddy_config/Caddyfile.template caddy_config/Caddyfile</code></p>
<p>And start the Docker container with <code>docker compose up -d.</code></p>
<p>Back out of infrastructure and into <code>minio</code>. Same again with the <code>.env</code> – copy and configure. Make sure the URLs match your domain.</p>
<p>Once more for <code>n8n</code> and then again for <code>openwebui</code>.</p>
<p>OWUI config comes from the <code>infrastructure</code> and <code>minio</code> <code>.env</code> files:</p>
<ul>
<li><p>S3_ACCESS_KEY_ID=minio_admin</p>
</li>
<li><p>S3_SECRET_ACCESS_KEY=minio_password</p>
</li>
<li><p>S3_BUCKET_NAME=decapod</p>
</li>
<li><p>MINIO_ROOT_USER=minio_admin</p>
</li>
<li><p>MINIO_ROOT_PASSWORD=minio_password</p>
</li>
<li><p>POSTGRES_DB=postgres</p>
</li>
<li><p>POSTGRES_USER=postgres</p>
</li>
<li><p>POSTGRES_PASSWORD=postgres_password</p>
</li>
</ul>
<p>📝 Note! OWUI may take a moment or two to start. Go grab some water and it should be up by the time you get back.</p>
<h2 id="heading-configuration-and-wiring">Configuration and Wiring</h2>
<p>Roll up your sleeves! This is where we get up to our elbows in pieces and parts.</p>
<p>If everything went to plan, you should now have all five services up and running. You can confirm the containers are live with <code>docker ps</code>. You can check that they're actually properly connected by visiting s3, OWUI, and n8n.your-domain.com.</p>
<p>Create accounts for all three and sign in to each.</p>
<p>⚡️ Important! Get your n8n license key! It's free and gives you access to all community features. You'll be severely limited without it. Activate it under Usage and plan in the settings.</p>
<h3 id="heading-initiate-the-database">Initiate the Database</h3>
<p>Decapod only needs two data tables. You can add them from the command line. But I like pgAdmin.</p>
<p>Connect to your Postgres database in the usual way. But you'll need your server's IP for the host name instead of postgres (which you use to connect services inside of the Docker network) since pgAdmin isn't in your Docker network.</p>
<p>You'll find your SQL files in <code>components/pgsql_tables</code>. Create a decapod database and add both of the SQL files to it. A default <code>decapod_state</code> table record will be automatically generated when running the SQL.</p>
<p>In pgAdmin:</p>
<ul>
<li><p>Open the decapod server.</p>
</li>
<li><p>Create a decapod database by right-clicking on databases.</p>
</li>
<li><p>Select the new database.</p>
</li>
<li><p>Click the query tool button at the top of the explorer.</p>
</li>
<li><p>Copy and paste the decapod_state table into the query and run it with F5.</p>
</li>
<li><p>Clear the query, paste in job_queue, run it.</p>
</li>
</ul>
<p>Or ask Cursor or an AI bestie for help if you want to go pure command line.</p>
<h3 id="heading-a-little-minio">A Little MinIO</h3>
<p>Next up, you'll be adding your agent's instructions and persona files to your private S3 service. Start by visiting your MinIO server and adding a decapod bucket.</p>
<p>In <code>components/S3_structure/agents/</code>, you'll find a template for your agents. (I have the intention of making Decapod a multi-agent tool in a future release.) The template is meant to be copied to a new agent of your choice. But if you choose something other than Decapod, you'll need to update the state table.</p>
<p>You can do it manually if you wish. Copy the folder to match the new agent's name and update the <code>definitions/skills.yaml</code> file to include all the skills you want your agent to have. The name and description should exactly match what's found at the top of each skill file.</p>
<p>Alternatively, I vibe coded a script to make it a little easier. It's in the scripts folder and you'll need to install the <code>inquirer</code> Node module to use it. Run <code>cd scripts</code> and <code>create-agent.mjs</code> to use it.</p>
<p>You also need to make sure that the files and folder structure in your MinIO match those in <code>S3_structure</code>. Start by creating a bucket called decapod in your drive. Then upload the files from <code>S3_structure</code> into your bucket.</p>
<p>But that's easier said than done because they're on a remote server. And if you used the visual interface, you'd have to download them to your local machine first. So I made another script – <code>upload_S3_structure.sh</code>.</p>
<p>That script is strictly meant for dev purposes. It's absolute and destructive. Just a heavy mallet. So if you want to surgically alter your MinIO, do not use it! Remember kids: mallets and brain surgery don't mix.</p>
<p>Once your agent files are in place, you can let your agents edit them, Open Claw style, or you can edit them yourself. But MinIO doesn't give you much of anything in the way of features for their UI.</p>
<p>For a better experience, I'd recommend <a href="https://web.s3drive.app/">S3Drive</a>. When you go to sign up, look for the connect button towards the bottom to connect to your own MinIO endpoint.</p>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/675ce1d600925897ba44d754/d3b5faa7-8e5d-4a35-84c9-0d97ea73d96c.png" alt="The S3Drive setup interface." style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>S3Drive will let you edit your files in place after you've uploaded them. This is good for quick fixes or copying and pasting sections without a complete wipe.</p>
<h3 id="heading-adding-the-workflows">Adding the Workflows</h3>
<p>You'll find most of what makes Decapod Decapod in the components folder. And the heart of that is in n8n_workflows.</p>
<p>You can manually import those workflows one at a time and go over each one to make sure they're safe and sound. Or you can use the n8n CLI inside of the Docker container and save yourself some tedium.</p>
<p>These commands move the workflows to the Docker container, import them with the n8n CLI, and then remove them from the tmp directory.</p>
<pre><code class="language-shell">docker cp ./components/n8n_workflows n8n:/tmp/workflows

docker exec -u node n8n n8n import:workflow --input=/tmp/workflows --separate
docker exec -u node n8n n8n import:workflow --input=/tmp/workflows/skills --separate

docker exec -u root n8n rm -rf /tmp/workflows
</code></pre>
<p>Now, you should see the 10 workflows in n8n. I'd recommend drag-and-dropping the main workflows to a dedicated decapod folder and the two skills to decapod/skills, just to keep things tidy. But they reference each other by id, so do what you want.</p>
<h3 id="heading-getting-started-with-n8n">Getting Started With n8n</h3>
<p>Now would be a good time to start exploring the workflows in your n8n UI Personal tab. If you sort them by name, the main file will be on top. Crack it open and see it's not too intense, and it's self-documented. Blue for notes, Green for sub-workflows, and Red for nodes that require your credentials.</p>
<p>I'd recommend reading the notes and thoroughly exploring the sub-workflows to help you understand Decapod. It's your tool now! Create credentials as you go.</p>
<p>Because we're using a Docker network, creating credentials and connecting your services to each other couldn't be easier.</p>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/675ce1d600925897ba44d754/de946994-8b01-436e-9a3b-aa79a46a0073.png" alt="The credentials page for an n8n Postgres connection." style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>The standard to connect all of your services is to reference them by <code>name:port</code>. Because the Postgres credential has its own port field, you can just set it to Postgres. Port should be 5432.</p>
<p>📝 Note! All credential details, like your container names, ports, and passwords, can be found in your docker-compose and .env files.</p>
<p>For MinIO:</p>
<ul>
<li><p>Endpoint: <code>http://minio:9000</code></p>
</li>
<li><p>Force Path Style: Enabled! Important for MinIO.</p>
</li>
</ul>
<p>API Connections to OpenRouter:</p>
<ul>
<li><p>choose: Authentication -&gt; Predefined Credential Type</p>
</li>
<li><p>then: Credential Type -&gt; OpenRouter</p>
</li>
<li><p>Now just paste your API key from <a href="https://openrouter.ai/settings/keys">OpenRouter</a>.</p>
</li>
</ul>
<p>n8n – (meta access to your workflow):</p>
<ul>
<li><p>In a new tab, go to n8n Settings -&gt; n8n API.</p>
</li>
<li><p>Turn off expiration if you like.</p>
</li>
<li><p>Copy your key.</p>
</li>
<li><p>Paste it in the field.</p>
</li>
<li><p>Base URL: <code>http://n8n:5678/api/v1</code></p>
</li>
</ul>
<p>Once you've created credentials, you can reuse them for every relevant node that uses the same credential. Just select it from the dropdown.</p>
<p>💡 Tip! It may help to remove the red sticky notes as you add credentials. And don't forget the skills! I didn't sticky note them at all.</p>
<p>As a final step, make sure your n8n workflows are published in the following order:</p>
<ul>
<li><p>construct message history</p>
</li>
<li><p>get job queue</p>
</li>
<li><p>hitl yes/no</p>
</li>
<li><p>tool router</p>
</li>
<li><p>worker</p>
</li>
<li><p>middleware</p>
</li>
<li><p>and the two skills</p>
</li>
</ul>
<p>💡 Tip! Always make sure your n8n workflows are in a published state with a green dot before calling them. Otherwise, you'll be calling an outdated version.</p>
<h3 id="heading-now-get-owui-to-talk-to-decapod">Now, Get OWUI to Talk to Decapod</h3>
<p>OWUI is built for teams, so you have admin settings and personal settings. You'll want to edit the admin settings by clicking on the profile circle in the lower-left-hand corner, then Admin Panel -&gt; Settings -&gt; Connections.</p>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/675ce1d600925897ba44d754/10840f19-1cbb-41e9-b066-e4c0033c0244.png" alt="Open WebUI's connections config page." style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>From there:</p>
<ul>
<li><p>Ollama API Disabled: Just keeping things tidy.</p>
</li>
<li><p>Configure the OpenAI link by clicking on the gear and delete that too.</p>
</li>
<li><p>Direct Connections: Enabled</p>
</li>
<li><p>Cache Base Model List: Enabled Now add your Decapod connector with the plus button.</p>
</li>
<li><p>URL: <a href="http://n8n:5678/webhook/v1/decapod">http://n8n:5678/webhook/v1/decapod</a> (Click the cycle icon to confirm your connection.)</p>
</li>
<li><p>Auth: none (it's all in the same Docker network, so it's fine for now. You can add a password for production.)</p>
</li>
<li><p>Prefix ID: decapod (If you do decide to use OpenAI, Hugging Face, or whatever else, this will help distinguish the model hosts.)</p>
</li>
</ul>
<p>That's it. Save and go to the Models tab. Decapod passes OpenRouter models straight through. So if you see hundreds of models, take a victory lap! That means that Decapod is working, live, accepting requests, and you've even properly done your certifications (at least for OpenRouter).</p>
<p>Now create a new chat session and pick a model. I like Claude Haiku 4.5. Fast, cheap, and good. Pick three. I did all of my Decapod dev with it in the saddle, so I know it works. And 3.5 million tokens towards testing iterations cost me \(4, so I know it's reasonable. Alternatively, Kimi K2.5 will likely work and would be even a little bit cheaper. I burned through 4.7 million tokens installing a Docker container in Open Claw with Kimi for about \)3.</p>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/675ce1d600925897ba44d754/8773faab-b7bd-47fe-90c7-0ed4aa0cbbed.png" alt="A successful communication between Open WebUI and Decapod." style="display:block;margin-left:auto" width="600" height="400" loading="lazy">

<p>Time to say hello to your little friend! Haiku is fast. So if it takes more than a few seconds to respond, something could be borked in your n8n flow. It happened to me as I was writing this article. I had some issues with both Postgres and MinIO.</p>
<p>💡 Tip: If the agent does get hung, it's easier to resend the message than stop and try again.</p>
<h3 id="heading-there-was-supposed-to-be-an-earth-shattering-kaboom">There Was Supposed to Be an Earth Shattering Kaboom</h3>
<p>So, your agent really wants to talk to you, but all you have is a pulsating dot. It's likely that something got misconfigured in n8n.</p>
<p>You can debug n8n by going to the middleware workflow and selecting <code>executions</code> from the top tab bar. If there's an error on the left list, look for a message in the lower right.</p>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/675ce1d600925897ba44d754/af5f6ea5-ad99-45e0-88c6-49ccc479fac1.png" alt="An example n8n error message." style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>This was when I had some database config issues and it couldn't find the state table.</p>
<p>Some sub-workflows may fail quietly. You can trace flow from the webhook entry point to the error. All successful nodes will light up green. The bad node will be red. Drill down, check executions, and repeat for each sub-workflow.</p>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/675ce1d600925897ba44d754/935b1bcc-f03d-452e-a67d-da00e2265d39.png" alt="An portion of an n8n workflow showing a node that threw an error." style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>When you find the culprit – the actual bad node in the bad execution – select "copy to editor" in the upper-right-hand corner. That will freeze the workflow to that state. Open the node, fix the credential or whatever, and click <code>Execute Step</code> to see if it's fixed.</p>
<p>Remember: after every change, always always always publish your update. Otherwise, n8n won't actually use the latest fixed version of your workflow.</p>
<p>Once you've successfully debugged your Decapod, make sure that you clean out the loose unfinished jobs in the job_queue table with pgAdmin or whatever. Otherwise, your agent will try to complete each of them before finishing the next job.</p>
<h2 id="heading-the-ever-present-hello-world">The Ever-Present "Hello World"</h2>
<p>OK! Now for the moment of truth. You got your agent to say hello back. That was the easy part because it didn't need to do any work or use any tools.</p>
<p>I set you up with two skills to put it to the test: write-file and research-recipes. The recipes skill connects your bot to a free recipe API (no key needed). It's not just pulling recipes out of training data.</p>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/675ce1d600925897ba44d754/84eefbe8-ad4d-44fb-ae19-3291d85fe0e9.png" alt="A successful request to Decapod requiring tool use." style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>Try this prompt: Would you please look up pizza recipes and save them to a file?</p>
<p>If all of your credentials are properly configured, you should get what you asked for. Open up MinIO or S3Drive and look in <code>/agents/decapod/documents</code> for the file.</p>
<h2 id="heading-into-the-future">Into the Future!</h2>
<p>I know that was a lot! (At least it felt like a lot from my end.) I hope it wasn't too painful. And look at the bright side: you just got a crash course on some really powerful technology. And if you made it through, that's a major accomplishment! The hard part is behind you. Now comes the fun.</p>
<h3 id="heading-a-work-in-progress">A Work in Progress</h3>
<p>I'll be honest. I just wanted to get Decapod out fast to prove how doable a personal agent is while Open Claw is still hot. Anyone can build their own Agentic AI with little or no code. And you don't have to settle for painful UI and poor security. You can have it all.</p>
<p>But, as I've said, Decapod is still an MVP. Complete and functional, but feature light. And I was stressing about that a little bit. I wanted multiple agents and more skills for the early adopters.</p>
<p>Then it hit me. Duh! You already have everything you need with n8n.</p>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/675ce1d600925897ba44d754/466cc6ab-f038-4728-9fcf-06d9f631f75c.png" alt="An example of chatting with an n8n agent that has internet access." style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>You can add an n8n agent node, connect it to a model and an MCP server, and have a sub-agent ready to go in minutes. Then have your agent produce a skill sheet to contact the sub-agent.</p>
<h3 id="heading-adding-your-own-skills-limitless-potential">Adding Your Own Skills – Limitless Potential</h3>
<p>Let's create a dead simple n8n agent to search the web. Then we'll add that to Decapod as a new skill.</p>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/675ce1d600925897ba44d754/95ffe965-3180-44fb-8ac2-7835b3931224.png" alt="A request for Decapod to create a new skill sheet." style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>In this image I used the prompt:</p>
<blockquote>
<p>Thank you so much! Next up, I want to give you web search access via a sub-agent. So your web search skill wouldn't directly search the web, but would instead call a simple agent to do the search for you.</p>
<p>Would you please create a web-search.md skill for your future self to use? The only required field should be prompt.</p>
</blockquote>
<p>The agent's file folder is sandboxed by default, so the agent's <code>skills/web-search.md</code> is actually in the agent's private <code>documents</code> storage. I moved it to the actual skills folder and updated my agent's skills.yaml file with the new skill.</p>
<p>Now I'll create a new n8n skill workflow in <code>decapod/skills/</code>.</p>
<p>⚡️ Important! Your n8n skill workflow name must match the skill name exactly. So, <a href="http://web-search.md">web-search.md</a> would be a workflow called web-search. Decapod uses the name to look for the skill so it can be hot loaded without a secondary router.</p>
<p>The n8n screenshot above was pretty much exactly the whole thing. Try rebuilding it yourself. I used chat input to make sure it was working with n8n's chat interface. And I used the <a href="https://www.pulsemcp.com/servers/exa">Exa Web Search MCP</a> as the search tool. I used Haiku as the model, but an even simpler model would have likely been just fine. OpenRouter has a number of free models with tool abilities that would probably do the trick.</p>
<p>Once you have the workflow operating properly, replace the chat node with a "When Executed by Another Workflow" node with a <code>parameters</code> object as input.</p>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/675ce1d600925897ba44d754/ddb03570-36d2-4a50-9acb-1a80cf02c11d.png" alt="The configuration of an n8n &quot;When Executed by Another Workflow&quot; node." style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>Next, open up the utility/workbench workflow. This tool will help you turn your web-search workflow into a skill. Work through each node in order, testing the node with "Execute step" button as you go. Doing so will create output data that the next node can use as input data.</p>
<ol>
<li><p>get workflow id from name: Set name to "web-search".</p>
</li>
<li><p>deliver JSON arguments to skill: Set parameters object to { "prompt": "Can I please get a list of a variety of pizza recipes complete with links to their sources?" }; (or whatever matches your skill sheet)</p>
</li>
<li><p>call skill based on workflow id: Should be ready to execute.</p>
</li>
</ol>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/675ce1d600925897ba44d754/0752c8a8-ab15-4c49-90ee-29e822b90f57.png" alt="an example of a successful n8n call to a sub-workflow." style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>If your output looks like that, your skill should be ready to go.</p>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/675ce1d600925897ba44d754/3b13ac1e-1c61-4fce-9896-14d569593ca3.png" alt="Decapod returning search results for dessert pizza recipes." style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>In this image I used the prompt: Alright! I think you're all set. Try doing a search for dessert pizza recipes.</p>
<p>If your agent gives you the following error, make sure that it knows it MUST create a job before it can call the <code>use_skill</code> tool. It should know that from the instructions, but pobody's nerfect. (I'll need to tighten that up.)</p>
<img src="https://cloudmate-test.s3.us-east-1.amazonaws.com/uploads/covers/675ce1d600925897ba44d754/6e63dc70-3bae-4389-aa68-80a22f6553b6.png" alt="An example response from a Decapod error." style="display:block;margin:0 auto" width="600" height="400" loading="lazy">

<p>Hopefully that was also pretty painless and now your mind is exploding with possibilities like mine is. If you're unconcerned with safety or actively want to invoke Skynet, you can even give your agent a skill to create its own n8n skills with the <code>Create a workflow</code> node. But don't do that.</p>
<h2 id="heading-future-plans">Future Plans</h2>
<p>Here are a few more features I'd like to add:</p>
<ul>
<li><p>/slash commands – You shouldn't have to go into n8n or pgAdmin to see what your agent is doing and manage its job queue.</p>
</li>
<li><p>Streaming responses – I'd like to see what my agent is doing as it's doing it, but streaming is a bit tricky and was beyond the MVP.</p>
</li>
<li><p>Multiple states – With multiple states, you can run multiple agents simultaneously. Or you can have different agents/models for different sessions. For example, you can have a health and fitness session with one agent with its own context window, job queue, and skill set. And you can have another one to help you keep track of your coding education.</p>
</li>
<li><p>It's a bug, not a feature – There are many places where the state and model are hard-coded throughout the app. I also started working on features that didn't pan out and left some dangling nodes. I'd like to clean up the app and actually implement those features.</p>
</li>
</ul>
<p>If you've read this far and are totally all in, I'd love to hear feedback and suggestions for more features. I'd be fascinated to hear about how Decapod is being used. And I'm also happy to answer any questions.</p>
<h2 id="heading-got-questions-meet-captain-finn">Got Questions? Meet Captain Finn!</h2>
<p>Decapod is the culmination of a year spent studying and learning all things AI and automation. It's also the result of 20 years in the world of coding and app development.</p>
<p>I'm currently starting a community for AI Enthusiasts, Automation Inventors, and Systems Thinkers. It will be led by Captain Finn, a retro-futuristic space captain who got stranded without his crew in our time and space. He used AI, automation, and systems thinking to keep the ship working, give himself someone to talk to, and to wake up to the smell of fresh coffee every morning.</p>
<p>And yes, Finn himself is an AI persona, operating from AI-automated systems, like Decapod, that he will be teaching people about.</p>
<p>My goal is to create a welcoming environment for my fellow mad scientists, dreamers, and citizen developers to learn and grow with help from the community and Captain Finn Feldspar himself. I plan to release weekly articles, more tutorials like this, and other tips and tricks.</p>
<p>Whether you want help with Decapod, learning automation, or just want to geek out about the power and future of AI — Captain Finn's Fleet has a place for you.&nbsp;<a href="https://discord.gg/HJtTpBAjQ5">Join here for free.</a></p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How To Overcome Digital Addiction and Have More Willpower ]]>
                </title>
                <description>
                    <![CDATA[ Author’s Long-Winded Pontification: I’m a dreamer. I’ve spent my life dreaming of someday having a very comfortable life. Of being able to do the things that only people who don’t worry about money get to do. I’ve been working my ass off building app... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-overcome-digital-addiction-and-have-more-willpower/</link>
                <guid isPermaLink="false">66d460149f2bec37e2da063f</guid>
                
                    <category>
                        <![CDATA[ Life lessons ]]>
                    </category>
                
                    <category>
                        <![CDATA[ motivation ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Productivity ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Lee Nathan ]]>
                </dc:creator>
                <pubDate>Sat, 01 Jun 2019 22:50:46 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/06/zombies-1.jpeg" medium="image" />
                <content:encoded>
                    <![CDATA[ <h2 id="heading-authors-long-winded-pontification">Author’s Long-Winded Pontification:</h2>
<p>I’m a dreamer. I’ve spent my life dreaming of someday having a very comfortable life. Of being able to do the things that only people who don’t worry about money get to do. I’ve been working my ass off building apps and starting businesses for 20 years. I still haven’t made it, but I’ve never given up and I never will.</p>
<p>I used to fantasize about what my life would be like once I’d “arrived”. But I’ve always struggled with my impulses and escapes like gaming, watching Netflix, neurotically checking Facebook and email, noodling with my phone, and on and on. I can’t tell you how many times I’ve caught myself closing Facebook just to open my email, then closing my email just to open Facebook. I’ve always fallen short of my productive goals and failed to finish my projects because of this. At some point, I stopped fantasizing. I never stopped chasing my dreams, but on some level, I’d lost hope.</p>
<p>Last night I started fantasizing again. The reason was that <a target="_blank" href="https://focusme.com/?ref=37">I’d found an app</a>that will help me control my digital addictions, make sure I turn off my computer and get a good night’s sleep, and limit what I can do on my phone.</p>
<h2 id="heading-about-willpower">About Willpower:</h2>
<p>I recently read an excellent book called ‘The Willpower Instinct’, by Kelly McGonigal Ph.D. One of my main takeaways from the book was that willpower works like a muscle. We have a finite amount and it can be drained. That’s why they put candy at the checkout line of grocery stores. After walking around the store trying to make good decisions, our willpower is exhausted and we’re more likely to make a bad decision.</p>
<p>We can do things to build our willpower, but every time we have to resist something, it drains us a bit. And the people and businesses that are aware of this are constantly chipping away at our willpower. If we’re running late to work and skipped breakfast, fast food is going to look awfully tempting. When we hear that chime on our phone, we pull it out like Pavlov’s dog and look for the red numbers. If we see an attractive person, we’re going to want to take action to see more of that person. Or we may want to take action to <strong>become</strong>that person. If we’re playing a game on our phone, it’s going to use all kinds of psychology to chip away at our willpower so we’ll buy that next upgrade, and the next, and the next…</p>
<h2 id="heading-about-dopamine">About Dopamine:</h2>
<p>Another takeaway I got from ‘The Willpower Instinct’ was regarding dopamine. Dopamine is a chemical our brain releases so that we’ll seek out rewards. It’s both a carrot and a stick. It gives us a satisfying bit of pleasure when we get it. And it causes us stress when we can’t get it.</p>
<p>There were dopamine experiments done on rats where they were wired up to be able to receive a dopamine hit electronically. Then they were put in a cage with 2 levers. One lever would give them food, the other would give them a dopamine hit. The rats would hit the dopamine lever over and over again without eating or sleeping. They would keep doing it until they passed out from exhaustion or died.</p>
<p>People aren’t that much different than the rats. Because of our cognitive abilities, we can resist temptations a little here and there so direct access to dopamine won’t kill us. But it will make us less likely to seek food, shelter, real social interaction, and other needs and forms of gratification. I personally have had days go by where I’ll play computer games from the time I wake until the time I sleep. I may only stop for a quick bite sometime in the late afternoon and I’ll “hold it” as long as I can until I really have to go. Computer and video games are my dopamine lever. But we all walk around with a dopamine lever in our pocket.</p>
<h2 id="heading-about-digital-addiction">About Digital Addiction:</h2>
<p>Over the years I’ve heard the addiction label plastered on everything from games to the internet to Facebook to porn. All these things have one thing in common — they’re digital. Digital addiction isn’t a real thing, just a label I created to blanket all the other addictions. But it fits because they all addict us in the same way. The fact is, we’re not actually addicted to games or Facebook or porn, we’re addicted to dopamine.</p>
<p>Every time we check our email, our Facebook notifications, our Instagram hearts and follows and we see that little red number, we get a small dopamine hit. Games give us tons of rewards, flooding us with dopamine. Orgasm gives us a rush of dopamine as well. Know what else gives us a hit of dopamine? Cocaine. When it comes to the digital world, we’re all crackheads.</p>
<p>It’s even worse if, like me, you work in the digital realm as a designer, developer, researcher, student, etc. You can’t just turn off your computer or put away your phone if you’re dependent on them to earn a living or education.</p>
<h2 id="heading-overloaded">Overloaded:</h2>
<p>Building up our willpower is an excellent thing to do. But we are so completely bombarded with temptations every day. And those dopamine releasing temptations are super hard to resist. I read somewhere the average person touches their phone more than 2,000 times a day. That’s more than 2,000 times we have to exercise our willpower just from having a physical device in our pocket. Then we spend time scrolling through our favorite social media platform hoping for another hit of dopamine from a cat video or a compilation of guys getting hit in the crotch or a touching statement from a friend or a titillating image. Meanwhile, we have other responsibilities and have to exercise a lot of willpower to break out of that behavior.</p>
<p>Our modern lives provide far more temptations than we are biologically able to handle. Some people don’t have a problem with this. They just naturally aren’t that into social media. Or maybe they get enough of a natural hit from the joy they get from day to day successes.</p>
<p>But many, or most of us struggle with one form of digital addiction or another. And we haven’t evolved to be able to handle it. It’s just all too much. And if we struggle with anxiety or depression, it can greatly amplify the need to feel good or feel better, making those addictions all the more powerful.</p>
<h2 id="heading-the-solution">The Solution:</h2>
<p>There’s a story going around about Steve Jobs’ turtleneck. They say that he wore the same turtleneck every day so that he’d have one less decision to make. So he’d have one less thing to drain his willpower every day, allowing him to be more productive. It’s probably not true and actually has more to do with branding. But it’s still a good story!</p>
<p>The solution is to take away our decisions. We need to eliminate as many of those willpower struggles we fight every day as we can. <strong>We need to make it more manageable!</strong></p>
<p>I’ve spent years looking for an app to help me block temptations. Usually, when I google it I’ll find parental control apps. They don’t help you control yourself, just others. I’ve seen website blocking browser plugins, but they don’t help with apps and can be easily disabled. I used to use admin tools on my PC to stop certain activities, but I always found a way to override them. Apps that block social media don’t work because I need it to promote my businesses.</p>
<p>I’ve seen tools that simply disconnect the internet. As a digital worker, that’s not even an option. As a life long learner, I rely on Google constantly. As a nomad, I require Google Maps daily. Turning off my devices simply isn’t an option either.</p>
<blockquote>
<p><a target="_blank" href="https://focusme.com/?ref=37"><em>FocusMe</em></a> <em>does it all!</em></p>
</blockquote>
<p><strong>Then yesterday, I found it! An awesome little app called</strong> <a target="_blank" href="https://focusme.com/?ref=37"><strong>FocusMe</strong></a><strong>. Other similar apps are too simple. They provide all or nothing solutions. I need to be able to enable and disable different things based on how I want to use them. It also lets me limit my access to apps like Steam and Minecraft just as well as websites. They also have an Android app that works almost as well as the PC version. It’s still better than anything else out there and definitely meets my needs.</strong> <a target="_blank" href="https://focusme.com/?ref=37"><strong>FocusMe</strong></a> <strong>does it all!</strong></p>
<h2 id="heading-how-i-use-it">How I Use It:</h2>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/06/focusme.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>I love gaming! But it consumes my life as I mentioned earlier. With <a target="_blank" href="https://focusme.com/?ref=37">FocusMe</a>, I’m able to restrict the time I spend gaming on a daily basis to say, an hour or two. I could even go weekly or monthly if I just wanted an occasional marathon.</p>
<p>I need to have access to my email and social media accounts, but I want to stop the cycle of checking over and over or mindlessly scrolling away. With <a target="_blank" href="https://focusme.com/?ref=37">FocusMe</a> I can limit my sessions to 10 minutes at a time (or less) and then not again for an hour (or longer).</p>
<p>It’s vitally important to get 8 hours of sleep a night. And sleeping at a regular time is also important to maintain a healthy circadian rhythm. But I often stay up late gaming, watching Netflix or finding one of 1,000 other ways to distract myself. Then I take a break and, well crap, it’s 2 AM again. <a target="_blank" href="https://focusme.com/?ref=37">FocusMe</a>can lock my computer down completely at night. I set it to lock down from 9 PM to 6 AM. A more regular sleep schedule can also help ensure a more regular work schedule, which is good for my freelance business.</p>
<p>I watch a lot, and I mean <strong>A LOT</strong> of Netflix, Amazon Prime Video, and TV from other sources. I can use <a target="_blank" href="https://focusme.com/?ref=37">FocusMe</a> to limit the time I spend on video sites and apps like VLC, just like I do with games.</p>
<p>I came up with a thing I call “analog time” where I’m allowed to listen to music and audiobooks, and maybe watch TV, but nothing else. No google, no games, no social media, no nothing, except for something I can run in the background while I do something artistic or craftsy or physical.</p>
<p>I can set it up to prohibit certain activities like gaming while I’m in work mode. It even has Pomodoro tracking baked right in so I can completely block distractions while I’m doing a Pom.</p>
<p>I can also lock down everything but one app or page to do work I don’t want to. For example, I clip tons of interesting articles and useful information to OneNote every day. In the years of using it though, I’ve only actually tried to organize it maybe 3 times. With <a target="_blank" href="https://focusme.com/?ref=37">FocusMe</a> I can block everything BUT OneNote for say an hour a day. I can even whitelist other apps that hold data that needs to be organized like my Google Drive.</p>
<h2 id="heading-final-notes">Final Notes:</h2>
<p>When I first installed <a target="_blank" href="https://focusme.com/?ref=37">FocusMe</a>, I had some issues with it not recognizing what browser tab I had open. That was a deal breaker for me. The dev responded to my support ticket with an update to the app that fixed the issue in 15 minutes on a Saturday! Holy cow! This is now an app that I trust completely.</p>
<p>I have a couple of notes on usage. I recommend going all in with <a target="_blank" href="https://focusme.com/?ref=37">FocusMe</a> but do so incrementally. DO NOT use “forced” until you have a lot of experience. Stick with short random passwords, say 3 characters. Once you’ve streamlined your system a bit, make the passwords a little harder, like 20–50 characters or so. After you’ve been using it without thinking much about it for a week or more, go for 100–200. If you find that level isn’t stopping you, you can go all the way up to 2,000! Or you can use “forced” as an absolute last resort.</p>
<p>Also, there’s a trend when someone wants to make a big change they tend to go overboard. I’m going to stop eating all the carbs! I’m going to exercise two hours a day everyday! These extreme attempts only set us up for failure as they’re unattainable. Please don’t cut everything you enjoy out of your life. Facebook is a great way to stay in touch with the people you love. Games are a great distraction, loads of fun and a soothing escape at the end of a hard day. Be loving to yourself first, and use this to cut down and control the things that take over your life. With great power comes great responsibility.</p>
<p>I finished this article in 2 days, instead of 2 weeks thanks to <a target="_blank" href="https://focusme.com/?ref=37">FocusMe</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Angular/Ionic, React, Vue? Future-proof your app with Stencil.js! ]]>
                </title>
                <description>
                    <![CDATA[ A Brief Intro: In this tutorial, I’m going to build a plain Stencil app with a working analog clock. I will throw in a little Ionic for convenience as well, but that’s not the focus here. This tutorial will cover some of the more important basics to ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/angular-ionic-react-vue-future-proof-your-app-with-stencil-js/</link>
                <guid isPermaLink="false">66d460133bc3ab877dae2206</guid>
                
                <dc:creator>
                    <![CDATA[ Lee Nathan ]]>
                </dc:creator>
                <pubDate>Fri, 31 May 2019 20:51:20 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/06/bridge.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <h2 id="heading-a-brief-intro">A Brief Intro:</h2>
<p>In this tutorial, I’m going to build a plain Stencil app with a working analog clock. I will throw in a little Ionic for convenience as well, but that’s not the focus here. This tutorial will cover some of the more important basics to know about Stencil.</p>
<p>While this is a low-level intro to Stencil, I’m going to assume that you’ve at least scanned the Stencil docs and have a basic idea of what JSX and Stencil are all about. You should probably be familiar with Typescript or at least ES6 as well.</p>
<h2 id="heading-a-longer-intro">A Longer Intro:</h2>
<p>In a previous post, I said I’d be “migrating” toward React because it’s outstripped Ionic. That’s a daunting proposition after 3 years in the Ionic realm. And what if React gets taken over in another year? Fortunately, the folks at Ionic are completely aware of this reality. Which is why they built stencil.js.</p>
<p>Stencil uses Typescript and JSX as a super powerful, lightweight, non-framework. Stencil can be added to any other framework or used on its own to accomplish much of what someone would use Angular or React for.</p>
<p>It’s also quick and easy to learn compared to larger frameworks. So it’s a great way to get used to the JSX/Web Component way of thinking. And if you want to migrate to React from Angular, or vice versa, Stencil can smooth your path.</p>
<p>Going forward I’ll be using Stencil in my personal projects. And Ionic 4 Components are now built on Stencil. So it’s a logical choice to future-proof your apps, whether you stay with Ionic/Angular or move to another framework.</p>
<p>As a side note for the JSX beginners. I find it’s easiest to forget about making everything into perfect Components and just write HTML. Then when I see a bit of HTML I’m going to use more than once or that I want to do something special, I’ll move it into its own Component.</p>
<h2 id="heading-getting-started">Getting Started:</h2>
<p>First off:</p>
<p>npm init stencil</p>
<p>Select <code>component</code> and use <code>analog-clock-components</code> as your project name, then:</p>
<p>cd analog-clock-components npm install --save @ionic/core npm start</p>
<p>If it all went to plan, you should see the default “Home” page pop up.</p>
<h2 id="heading-making-the-clock">Making the Clock:</h2>
<p>I hate it when tutorials weigh you down with a bunch of information that isn’t critical to the core concepts. So that’s exactly what I’m going to do! I’ll be making the clock with SVG. But hey, it beats yet another fucking todo list example. And I promise to keep it simple.</p>
<p><strong>Watch out!</strong> Your Stencil component tags MUST have 2 or more words or your app will enigmatically fail with something like <code>“clock” is not a valid custom element name</code>!</p>
<p>Add a clock-face folder in the <code>src/components</code> directory like so:<code>clock-face/clock-face.tsx</code> and add the following contents.</p>
<p>import { Component } from '@stencil/core';</p>
<p>@Component({ tag: 'clock-face' }) export class ClockFace {</p>
<p>render() { return ( ); } }</p>
<p>Then add <code>analog-clock/analog-clock.tsx</code>.</p>
<p>import { Component } from '@stencil/core';</p>
<p>@Component({ tag: 'analog-clock', }) export class AnalogClock { render() { return [</p>
<p>]; } }</p>
<p>And now replace the <code>my-component</code> tag in <code>index.html</code> with <code>&lt;analog-clock\&gt;</code></p>
<p>You may have to restart the app, but you should now see this as your home page:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/05/clock-1.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>my stunning clock</em></p>
<p>That bit of SVG was pretty painless, just a circle and a couple lines with a bit of style for aesthetics. The style can and should be applied with CSS in a non-trivial app.</p>
<p>Notice that I’ve used the <code>&lt;svg&gt;</code> tag as the root of this component. Neat! So far this clock is only right twice a day, so let’s add a few props to make it adjustable. I’m also going to add functions to convert time to degrees to rotate the hands. And I’m going to update the SVG to be able to rotate those hands.</p>
<p>import { Component, Prop } from '@stencil/core';</p>
<p>@Component({ tag: 'clock-face' }) export class ClockFace { @Prop() hour: number; @Prop() minute: number; @Prop() second: number;</p>
<p>hourToDegrees(): number { return Math.floor(this.minute / 2) + (this.hour * 30); }</p>
<p>minuteToDegrees(): number { return Math.floor(this.second / 10) + (this.minute * 6); }</p>
<p>secondToDegrees(): number { return this.second * 6; }</p>
<p>render() {</p>
<p>return ( &lt;line id="hour-hand" transform={<code>rotate(${this.hourToDegrees()}, 100, 100)</code>} x1="100" y1="100" x2="100" y2="60" stroke="black" stroke-width="10" stroke-linecap="round"/&gt; &lt;line id="minute-hand" transform={<code>rotate(${this.minuteToDegrees()}, 100, 100)</code>} x1="100" y1="100" x2="100" y2="30" stroke="black" stroke-width="8" stroke-linecap="round"/&gt; &lt;line id="second-hand" transform={<code>rotate(${this.secondToDegrees()}, 100, 100)</code>} x1="100" y1="100" x2="100" y2="30" stroke="black" stroke-width="2" stroke-linecap="round"/&gt; ); } }</p>
<p>And there we go. My component can now accept incoming variables via the @Prop() decorator and change how it’s displayed based on those variables. Let’s see this in action by updating the clock-face tag to <code>&lt;clock-face hour={12} minute={34} second={56}/&gt;</code> I’ve wrapped the numbers in curly brackets so they’ll be passed in as numbers instead of strings.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/05/clock-2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>my updated clock; still only right twice a day</em></p>
<h2 id="heading-making-the-clock-tick">Making the Clock Tick:</h2>
<p>If you notice, the clock has no internal logic or time management abilities. It’s best to keep your components as simple as possible. Web Components are a bit like functional programming in that they should do just one thing. Stencil builds on the functional paradigm by making props immutable so that the component can’t affect anything outside of itself. They can fire off events, but that’s it.</p>
<p>Now I’m going to add getters to <code>analog-clock.ts</code> to get it to start ticking away.</p>
<p>import { Component } from '@stencil/core';</p>
<p>@Component({ tag: 'analog-clock', }) export class AnalogClock { get hour(): number { let h: any = new Date().getHours(); return h; }</p>
<p>get minute(): number { let m: any = new Date().getMinutes(); return m; }</p>
<p>get second(): number { let s: any = new Date().getSeconds(); return s; }</p>
<p>render() { return (</p>
<p>); } }</p>
<p>Wow! Look at that clock go… nowhere. The time is right, but it’s not ticking. If those of you following along at home are familiar with the Angular family, you may be expecting a ticking clock at this point. However, Stencil only re-renders upon certain conditions. This avoids the runaway train effect Angular developers know all too well. If you get a loop in your code or just have a lot of logic in a method that’s being called from HTML or a getter, your app can slow to a dead stop. It’s still possible for that to happen with Stencil, but it would almost have to be deliberate.</p>
<p>In order for Stencil to re-render, you have to use decorators like @Prop() or @State() to tell Stencil what data is important enough to cause the view to re-render. The state decorator is for managing internal variables, so I’m going to use that. I’m also going to tap into the Component lifecycle so that the timer doesn’t start until the component loads and so that it stops when the Component unloads.</p>
<p>import { Component, State } from '@stencil/core';</p>
<p>@Component({ tag: 'analog-clock', }) export class AnalogClock { timer: number;</p>
<p>@State() time: number = Date.now();</p>
<p>componentDidLoad() { this.timer = window.setInterval(() =&gt; { this.time = Date.now(); }, 250); }</p>
<p>componentDidUnload() { clearInterval(this.timer); }</p>
<p>get hour(): number { return new Date(this.time).getHours(); }</p>
<p>get minute(): number { return new Date(this.time).getMinutes(); }</p>
<p>get second(): number { return new Date(this.time).getSeconds(); }</p>
<p>render() { return ( ); } }</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2019/05/clock-3.gif" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>And now my clock is ticking away merrily.</em></p>
<h2 id="heading-changing-the-timezone-sort-of">Changing the Timezone (sort of):</h2>
<p>Next, I’m going to add a slider to allow me to pick a timezone. I’m not actually going to incorporate timezones though. It’s a complex feature that needs a whole other library (<a target="_blank" href="https://momentjs.com/timezone/">like moment.js for timezones</a>) to manage properly. I’m just going to offset the hour by give-or-take 12 hours. It’s a kludgey fix, but it will illustrate how to get data back out of a component, which is a critical thing to know.</p>
<p>Now I’m going to add a time-zone-slider component just like I did with the analog clock, like so <code>time-zone-slider/time-zone-slider.tsx</code>.</p>
<p>import { Component, Prop, Event, EventEmitter } from '@stencil/core'; import '@ionic/core';</p>
<p>@Component({ tag: 'time-zone-slider' }) export class TimeZoneSlider { @Prop() offset: number; @Event() timeZoneChanged: EventEmitter;</p>
<p>positionChanged(event: CustomEvent) { this.timeZoneChanged.emit(event.detail.value) }</p>
<p>render() { return ( &lt;ion-range debounce={500} max={12} min={-12} pin={true} snaps={true} step={1} value={this.offset} onIonChange={event =&gt; this.positionChanged(event)} &gt; -1212 ); } }</p>
<p>Notice that I imported the <code>@ionic/core</code> library here. This may be overkill, especially in an app where you have no intention of using Ionic components. I just found this to be the easiest way to implement a slider so I could finish this tutorial before the end of the year.</p>
<p>This component also has no internal logic. It doesn’t even manage its own state. It receives the offset as a @Prop(). And when the slider moves, it emits an @Event() to the parent, letting it know about the new value. It is then the parent’s responsibility to manage the state and update the child when the offset changes. Or the parent may also be passing in a value managed by the state of one of <strong>its</strong> ancestors.</p>
<p>import { Component, State, Listen } from '@stencil/core';</p>
<p>@Component({ tag: 'analog-clock', }) export class AnalogClock { timer: number;</p>
<p>@State() time: number = Date.now(); @State() timeZone: number = 0; @Listen('timeZoneChanged') timeZoneChangedHandler(event: CustomEvent) { this.timeZone = event.detail; }</p>
<p>componentDidLoad() { this.timer = window.setInterval(() =&gt; { this.time = Date.now(); }, 250); }</p>
<p>componentDidUnload() { clearInterval(this.timer); }</p>
<p>get hour(): number { return new Date(this.time).getHours(); }</p>
<p>get minute(): number { return new Date(this.time).getMinutes(); }</p>
<p>get second(): number { return new Date(this.time).getSeconds(); }</p>
<p>render() { return (</p>
<p>&lt;clock-face hour={this.hour + this.timeZone} minute={this.minute} second={this.second}/&gt;</p>
<p>); } }</p>
<p>In analog-clock, I just added a timeZone state manager. I also added the @Listen() decorator to the <code>timeZoneChangedHandler</code> function. That function updates the timeZone state. I changed the <code>clock-face</code> element to offset the hour based on the timeZone. Finally, I added the slider element and passed in the current timeZone, completing the loop.</p>
<h4 id="heading-summary">Summary:</h4>
<p>I just touched on about 80% of what you need to know to get started using Stencil. We’ve covered creating and implementing Components and handling their lifecycles. We covered firing and listening for Events. We covered passing data to children Components with Props. And we covered handling internal Component State. That’s actually about half of the features listed in the Components section of the Stencil docs.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
