<?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: Mark Holton</title>
    <description>The latest articles on DEV Community by Mark Holton (@mark_holton).</description>
    <link>https://dev.to/mark_holton</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%2F2497703%2Fae4c4c7f-9d4b-44d3-9f7f-e68746f8251f.png</url>
      <title>DEV Community: Mark Holton</title>
      <link>https://dev.to/mark_holton</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mark_holton"/>
    <language>en</language>
    <item>
      <title>Curiosity and Craft: What Drives Me to Build</title>
      <dc:creator>Mark Holton</dc:creator>
      <pubDate>Sat, 16 Aug 2025 18:19:42 +0000</pubDate>
      <link>https://dev.to/mark_holton/curiosity-and-craft-what-drives-me-to-build-3814</link>
      <guid>https://dev.to/mark_holton/curiosity-and-craft-what-drives-me-to-build-3814</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://holtonma.github.io/posts/curiosity-and-craft/" rel="noopener noreferrer"&gt;holtonma.github.io&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Curiosity and Craft
&lt;/h2&gt;

&lt;p&gt;&lt;a href="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%2Fhls693ozcepoz2xg6j44.jpg" class="article-body-image-wrapper"&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%2Fhls693ozcepoz2xg6j44.jpg" alt="Whimsical illustration of a home AI laboratory with servers, containers, and neural networks" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Exercising those muscles of grit and resiliency that are essential to improving at our craft&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I've been thinking about what drives me to build things. It is curiosity and craftsmanship. Those two things have been consistent throughout my career and life - from LabView as a Physics undergrad, to many different languages and technologies, to Rails web applications, to data pipelines to now LLM-based architectures.  Even &lt;a href="https://www.ihsa.org/data/gob/records/ybych1.htm" rel="noopener noreferrer"&gt;golf on the driving range as a kid&lt;/a&gt;, tinkering with clubs, swing changes. Trying to constantly improve and understand the fundamentals, and then put them to test.&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2F73zra89m726o5axxdv3h.jpg" class="article-body-image-wrapper"&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%2F73zra89m726o5axxdv3h.jpg" alt="Junior golf days - competing for a State Championship" width="800" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Early days, decades ago, putting self to the test in tournaments - after work and tinkering with fundamentals and constantly trying to improve&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  "Home AI Pipeline Lab" Setup
&lt;/h2&gt;

&lt;p&gt;I am setting up this AI lab wired into my home network. I just finished configuring a small machine with 96GB RAM and running Proxmox with LXC containers. I am in the process on the weekends of a list of items like setting up an Nginx container, another container with the &lt;a href="https://holtonma.github.io/posts/self-hosting-rails-cloudflare-tunnels/" rel="noopener noreferrer"&gt;Cloudflare tunnel&lt;/a&gt;, and all the necessary DNS, etc.  &lt;/p&gt;

&lt;p&gt;&lt;a href="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%2Fzyocogzkgr84arg6wd4b.png" class="article-body-image-wrapper"&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%2Fzyocogzkgr84arg6wd4b.png" alt="ASRock machine setup for home AI lab" width="800" height="1066"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Clean ASRock setup with 96GB RAM ready for Proxmox containers and local AI models&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Then add a dedicated DB and Redis containers, an &lt;a href="https://ollama.com/search" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt; container or two for serving local models, and have Nginx proxy to my web apps that use them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Web App and RAG Home Infrastructure
├── nginx-proxy (reverse proxy, SSL)
├── PostgreSQL + Redis (data layer)  
├── FastAPI backend (app API)
├── Ollama 70B (free tier recommendations)
└── Claude API integration (premium tier)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;General architecture for applications running on my home lab infrastructure&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2F8d9h7cqflxhkda0o17zt.png" class="article-body-image-wrapper"&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%2F8d9h7cqflxhkda0o17zt.png" alt="Ollama downloading models for local inference" width="800" height="492"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Ollama pulling down language models for local experimentation&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Once the models are downloaded, I can start testing them with simple API calls:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://192.168.50.101:11434/api/generate &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "model": "llama3.1:70b-instruct-q4_0",
    "prompt": "One TV show like Succession:",
    "stream": true
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Testing the local Llama 3.1 70B model with a simple recommendation query&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;And here's the response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"llama3.1:70b-instruct-q4_0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"created_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2025-08-16T00:48:18.073237286Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"response"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Great taste! Based on your interest in the complex family dynamics of Succession and the fast-paced, character-driven storytelling of The Bear, I'd like to recommend another TV show that you might enjoy:&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;Billions&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;Here's why:&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;1. Complex characters: Like Succession, Billions features a cast of complex, multi-dimensional characters with rich backstories. You'll find yourself drawn into their world and invested in their struggles.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;2. High-stakes power struggles: The show revolves around the cat-and-mouse game between hedge fund manager Bobby &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Axe&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; Axelrod (Damian Lewis) and ruthless U.S. Attorney Chuck Rhoades (Paul Giamatti). This ongoing battle for power and supremacy will remind you of the Roy family's machinations in Succession.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;3. Character-driven storytelling: Like The Bear, Billions focuses on character development and nuanced relationships. You'll witness the intricate web of alliances, rivalries, and personal demons that drive the characters' actions.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;4. Fast-paced, witty dialogue: The show's writing is sharp, clever, and engaging, with a tone that's both humorous and intense. You'll appreciate the quick-witted banter and clever plot twists.&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;Give Billions a try if you enjoy:&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;* Character-driven drama&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;* Complex power struggles&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;* Witty, fast-paced storytelling&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;* Morally ambiguous characters&lt;/span&gt;&lt;span class="se"&gt;\n\n&lt;/span&gt;&lt;span class="s2"&gt;I think you'll find Billions to be an engaging and addictive watch!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"done"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"done_reason"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"stop"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"total_duration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;250847368597&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"load_duration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;22127677&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"prompt_eval_count"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"prompt_eval_duration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;82051803&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"context"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;128006&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;882&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;128007&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"... (truncated for brevity)"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Local model response demonstrating the LLM inference on home model + hardware&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;With this setup, I can dive into architecting web applications, RAG pipelines, and exploring the tools and patterns that make AI systems work. Active experimentation beats passive learning - turning ideas into running code rather than keeping them dormant in my head.&lt;/p&gt;

&lt;p&gt;The practical reasons are: no API costs, no hosting costs, can experiment freely. But the bigger motivating reason is simpler - I enjoy rolling up my sleeves, getting my hands dirty and making these things work, and also understanding deeply how these systems actually work.  I enjoy that process.  Specifically, here in 2025, I want to master the fundamentals of designing and building LLM-powered systems, so I can make them operate and perform in ways that scale and solve business problems. In my experiences, the best way to do that is to dive in.  &lt;/p&gt;

&lt;p&gt;AI pipelines, while different from &lt;a href="https://engineering.salesforce.com/building-a-fault-tolerant-data-pipeline-for-chatbots-47d74bc31f5b/" rel="noopener noreferrer"&gt;some of the pipelines I have built over the years&lt;/a&gt;, share the fundamentals of good architecture. You still need to think about data flow, error handling, monitoring, scalability and resiliency. Some of the differences I am thinking through now, in general terms: managing context windows for larger RAG applications, routing between different model actions, and dealing with probabilistic outputs instead of deterministic ones.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'm Learning Today
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vector databases&lt;/strong&gt; - exploring &lt;a href="https://qdrant.tech/documentation/overview/" rel="noopener noreferrer"&gt;Qdrant&lt;/a&gt; for efficient similarity search&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rerankers&lt;/strong&gt; - relevance sorters and intent matchers that are quite new to me. A colleague suggested investigating hosted services like &lt;a href="https://www.voyageai.com/" rel="noopener noreferrer"&gt;Voyage.ai&lt;/a&gt; and &lt;a href="https://cohere.com/" rel="noopener noreferrer"&gt;Cohere&lt;/a&gt; for practical reranking in RAG pipelines&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Embedding strategies&lt;/strong&gt; - techniques for converting text to meaningful vector representations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RAG architectures&lt;/strong&gt; - patterns for retrieval-augmented generation systems&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Python frameworks&lt;/strong&gt; - PydanticAI and LangChain that connect the dots between components
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There's a lot to dig into and learn.  Each piece has nuances you only discover by implementing them yourself.  It's an interactive and iterative process for me. The same way I was curious about a linear algebra problem or a calculus problem decades ago, but you you get also use a screwdriver, a keyboard.&lt;/p&gt;

&lt;p&gt;&lt;a href="/images/proxmox_ui.png" class="article-body-image-wrapper"&gt;&lt;img src="/images/proxmox_ui.png" alt="Proxmox VE interface showing ollama-inference container"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Proxmox container management - monitoring the Ollama inference container with CPU and memory usage&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I'm building a couple of Pydantic-AI apps now on the side as a testing ground - one is a recommendation system that uses local models like Llama 70B. Not because the world needs another recommendation engine, but because it gives me a concrete problem to solve with these tools, and I am curious about how I would solve this problem.  I also understand already this &lt;a href="https://ollama.com/library/llama3.3" rel="noopener noreferrer"&gt;70B model&lt;/a&gt; is too much for my ASRock machine, but that's part of the experience (it works, and gives good results, it's just slowww).  &lt;/p&gt;

&lt;p&gt;Each project teaches me something specific about AI architecture patterns in practical terms (E.g. &lt;a href="https://holtonma.github.io/posts/mcp_blog_post/" rel="noopener noreferrer"&gt;Building Conversational Apps with MCP&lt;/a&gt;). In that process pushing to solve problems you will get hit with many snags, blockers and hurdles, and the light bulb goes on related to a fundamental you missed in what you were reading, understanding. I encourage you to "just go for it", and see what you learn — it's not about the end result or "making a million dollars", praise and admiration or some external feedback "cookie".  The most sustainable feedback over time, and the stuff that breeds confidence, is in the process of striving for something and overcoming the obstacles to get there. You exercise those muscles of grit and resiliency that are essential to anything we do, but especially software engineering.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I Am Curious About RAG Architectures
&lt;/h2&gt;

&lt;p&gt;After decades engaged building and architecting web applications and data pipelines, it feels like a new set of primitives for solving problems. How can I use language models in a way to solve automation problems at scale — these mathematical reasoning engines can understand context very well and generate structured relevant outputs. &lt;/p&gt;

&lt;p&gt;The home lab lets me explore this at my own pace. Without cloud bills, API limits, no external dependencies. Just the freedom to try explore and learn.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Next
&lt;/h2&gt;

&lt;p&gt;Going to try and "document" what I learn as I build:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Giving Proxmox containers a try&lt;/li&gt;
&lt;li&gt;The containers I build and their function&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://ai.pydantic.dev/" rel="noopener noreferrer"&gt;Pydantic AI framework&lt;/a&gt; for building agents&lt;/li&gt;
&lt;li&gt;Temporal for workflows, and lessons learned&lt;/li&gt;
&lt;li&gt;Performance characteristics of different models on this hardware vs the "big boys" like GPT-5 and Claude Opus 4.1&lt;/li&gt;
&lt;li&gt;Architecture decisions for the apps I am building&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Build something, you learn from it, you build the next thing better. Keep going and enjoy 🍺&lt;/p&gt;




</description>
      <category>ai</category>
      <category>homelab</category>
      <category>rag</category>
      <category>pydanticai</category>
    </item>
    <item>
      <title>Self-Hosting Rails Apps with Cloudflare Tunnels - Why I chose to self host hobby apps on my Mac Mini</title>
      <dc:creator>Mark Holton</dc:creator>
      <pubDate>Sun, 10 Aug 2025 22:55:54 +0000</pubDate>
      <link>https://dev.to/mark_holton/self-hosting-rails-apps-with-cloudflare-tunnels-why-i-ditched-17month-cloud-hosting-for-a-599-4epo</link>
      <guid>https://dev.to/mark_holton/self-hosting-rails-apps-with-cloudflare-tunnels-why-i-ditched-17month-cloud-hosting-for-a-599-4epo</guid>
      <description>&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://holtonma.github.io/posts/self-hosting-rails-cloudflare-tunnels/" rel="noopener noreferrer"&gt;holtonma.github.io&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="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%2Fc169cp47b3hnpay4x86c.jpg" class="article-body-image-wrapper"&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%2Fc169cp47b3hnpay4x86c.jpg" alt="Markbot Robot on Steampunk Rocket" width="800" height="533"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Be adventurous and free - start hosting this stuff yourself with no barriers to your exploration!&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  The $17/Month Death by a Thousand Cuts
&lt;/h2&gt;

&lt;p&gt;I love building side projects. I tend to use them to explore technologies in a fun way - Fantasy golf leagues, personal dashboards - the kind of apps that scratch a specific itch but don't need to scale to millions of users. But every time I'd spin up a new Rails app, I'd hit the same wall: &lt;strong&gt;hosting costs that kill exploration&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Here's what a typical "simple" Rails app costs on popular platforms:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Basic Plan&lt;/th&gt;
&lt;th&gt;What You Get&lt;/th&gt;
&lt;th&gt;The Reality&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Heroku&lt;/td&gt;
&lt;td&gt;$7/dyno + $9/postgres&lt;/td&gt;
&lt;td&gt;512MB RAM, shared CPU&lt;/td&gt;
&lt;td&gt;Need 2+ dynos for real traffic = $23+/month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Railway&lt;/td&gt;
&lt;td&gt;$5/service&lt;/td&gt;
&lt;td&gt;512MB RAM, 1GB storage&lt;/td&gt;
&lt;td&gt;Add database, background jobs = $15+/month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Render&lt;/td&gt;
&lt;td&gt;$7/service&lt;/td&gt;
&lt;td&gt;512MB RAM&lt;/td&gt;
&lt;td&gt;Plus $7 for PostgreSQL = $14+/month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DigitalOcean App Platform&lt;/td&gt;
&lt;td&gt;$12/month&lt;/td&gt;
&lt;td&gt;512MB RAM, 1GB disk&lt;/td&gt;
&lt;td&gt;Minimal for any real app&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;The real killer isn't the base price&lt;/strong&gt; - it's what happens when you want to do more &lt;strong&gt;exploration&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Need web scraping? Extra $10/month for higher CPU limits&lt;/li&gt;
&lt;li&gt;Want to add vector search? $25/month for a vector database &lt;/li&gt;
&lt;li&gt;File uploads growing? $15/month for more storage&lt;/li&gt;
&lt;li&gt;Background job processing? Another $7/month for workers&lt;/li&gt;
&lt;li&gt;Redis for caching? $15/month for managed Redis&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Suddenly your hobby project costs $50-100/month.&lt;/strong&gt; At that point, you start making technical compromises not because they're better, but because you don't want to pay for exploration.&lt;/p&gt;
&lt;h2&gt;
  
  
  Enter the Mac Mini: $2/Month for 20x the Performance
&lt;/h2&gt;

&lt;p&gt;Last year, I bought a Mac Mini M2 for $599. Here's what I'm running on it right now:&lt;/p&gt;
&lt;h3&gt;
  
  
  EyeOnMajors.com: A Real-World Example
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://eyeonmajors.com" rel="noopener noreferrer"&gt;EyeOnMajors.com&lt;/a&gt; is my Rails 8 app that allows family and friends to compete in fantasy golf with real-time updates. On cloud hosting, this would easily cost $30+/month because it needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Database storage&lt;/strong&gt; (historical tournament data)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Real-time data processing&lt;/strong&gt; (background jobs)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Image processing&lt;/strong&gt; (tournament photos, player headshots)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Web scraping&lt;/strong&gt; (CPU intensive, banned on basic plans)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File storage&lt;/strong&gt; (images, cached data)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;My actual monthly cost: $2.25&lt;/strong&gt; (domain + electricity)&lt;/p&gt;
&lt;h3&gt;
  
  
  Performance Comparison: Cloud vs Mac Mini
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CLOUD HOSTING ($17/month):
- 512MB RAM (shared with other apps)
- 0.5 CPU cores (shared, throttled)
- 1GB storage (pay for more)
- Limited network I/O
- No root access
- No custom software installs

MAC MINI M2 ($599 one-time):
- 16GB unified memory
- 8-core ARM CPU (dedicated)
- 256GB SSD (upgrade to 1TB+ easily)
- Gigabit Ethernet
- Full root access
- Install anything you want
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;It's not even close.&lt;/strong&gt; The Mac Mini has roughly &lt;strong&gt;20-50x the resources&lt;/strong&gt; for a fraction of the ongoing cost.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Security Problem (Solved by Cloudflare Tunnels)
&lt;/h2&gt;

&lt;p&gt;The traditional blocker for self-hosting was security. Opening ports on your home network? Dealing with dynamic IPs? Managing SSL certificates? &lt;strong&gt;No thanks.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But &lt;strong&gt;Cloudflare Tunnels changed everything&lt;/strong&gt;. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cloudflare Tunnel (originally called "Argo Tunnel") was launched around 2018-2019&lt;/li&gt;
&lt;li&gt;It became free for all users in 2021 (previously required paid plans)&lt;/li&gt;
&lt;li&gt;The rebranding from "Argo Tunnel" to "Cloudflare Tunnel" happened around 2021-2022&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  What Cloudflare Tunnels Do
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.cloudflare.com/products/tunnel/" rel="noopener noreferrer"&gt;Cloudflare Tunnels&lt;/a&gt; create a secure, outbound-only connection from your home server to Cloudflare's edge network. Here's the magic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Traditional Self-Hosting (Scary):
Internet → Your Router (ports 80/443 open) → Your Server
❌ Exposed IP address
❌ Open ports = attack surface  
❌ DDoS risk
❌ SSL certificate management

Cloudflare Tunnels (Secure):
Internet → Cloudflare Edge → Encrypted Tunnel → Your Server
✅ No exposed IP or open ports
✅ Enterprise DDoS protection
✅ Automatic SSL/TLS
✅ Zero router configuration needed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="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%2Fbxai5ydp6b768vmqjomh.png" class="article-body-image-wrapper"&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%2Fbxai5ydp6b768vmqjomh.png" alt="Cloudflare Tunnel Traffic Flow Diagram" width="800" height="265"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Encrypted tunnels - no exposed ports, no router configuration needed&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Setting Up EyeOnMajors.com with Cloudflare Tunnels
&lt;/h3&gt;

&lt;p&gt;The setup took me about 30 minutes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Transfer DNS to Cloudflare&lt;/strong&gt; (free)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Install cloudflared on Mac Mini&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   brew &lt;span class="nb"&gt;install &lt;/span&gt;cloudflare/cloudflare/cloudflared
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create and configure tunnel&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   cloudflared tunnel login
   cloudflared tunnel create eyeonmajors
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Point tunnel to Rails app&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;   &lt;span class="c1"&gt;# ~/.cloudflared/config.yml&lt;/span&gt;
   &lt;span class="na"&gt;tunnel&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;eyeonmajors&lt;/span&gt;
   &lt;span class="na"&gt;ingress&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;hostname&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;eyeonmajors.com&lt;/span&gt;
       &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http://localhost:3000&lt;/span&gt;
     &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;http_status:404&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Update DNS in Cloudflare dashboard&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Type: CNAME&lt;/li&gt;
&lt;li&gt;Name: &lt;code&gt;eyeonmajors.com&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Content: &lt;code&gt;[tunnel-id].cfargotunnel.com&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;That's it.&lt;/strong&gt; No port forwarding, no SSL certificates, no dynamic DNS. Just works.&lt;/p&gt;
&lt;h3&gt;
  
  
  What You Get with Cloudflare's Free Tier
&lt;/h3&gt;

&lt;p&gt;This blew my mind - Cloudflare's &lt;strong&gt;free tier&lt;/strong&gt; includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unlimited bandwidth&lt;/strong&gt; (seriously)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DDoS protection&lt;/strong&gt; (enterprise-grade)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Global CDN&lt;/strong&gt; (your app loads fast worldwide)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSL/TLS termination&lt;/strong&gt; (automatic certificates)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DNS hosting&lt;/strong&gt; (fast, reliable)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Basic analytics&lt;/strong&gt; (traffic insights)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate limiting&lt;/strong&gt; (API protection)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Free tier limits that matter for hobby projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1,000 tunnels per account (you'll use 1-3)&lt;/li&gt;
&lt;li&gt;100MB max file upload size&lt;/li&gt;
&lt;li&gt;Must serve legitimate website content (no video streaming or large file hosting)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Services that could cost $100+/month on AWS are &lt;strong&gt;completely free&lt;/strong&gt; with Cloudflare.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Rails Deployment: Simple Make Scripts (For Now)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Full disclosure:&lt;/strong&gt; This is my current personal solution for hobby projects, not enterprise best practices. For deployment, I use a simple Makefile that builds and deploys my Rails app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="c"&gt;# EyeOnMajors.com Production Makefile
&lt;/span&gt;&lt;span class="nl"&gt;.PHONY&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;deploy logs health backup status&lt;/span&gt;

&lt;span class="nl"&gt;deploy&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"🚀 Deploying EyeOnMajors..."&lt;/span&gt;
    git pull origin main
    docker-compose &lt;span class="nt"&gt;-f&lt;/span&gt; docker-compose.production.yml up &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--build&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"✅ Deployment complete!"&lt;/span&gt;

&lt;span class="nl"&gt;logs&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"📋 Viewing application logs..."&lt;/span&gt;
    docker-compose &lt;span class="nt"&gt;-f&lt;/span&gt; docker-compose.production.yml logs &lt;span class="nt"&gt;-f&lt;/span&gt; web

&lt;span class="nl"&gt;health&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"🏥 Checking application health..."&lt;/span&gt;
    curl &lt;span class="nt"&gt;-s&lt;/span&gt; http://localhost:3000/health | jq
    docker-compose &lt;span class="nt"&gt;-f&lt;/span&gt; docker-compose.production.yml ps

&lt;span class="nl"&gt;backup&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"💾 Creating database backup..."&lt;/span&gt;
    docker-compose &lt;span class="nt"&gt;-f&lt;/span&gt; docker-compose.production.yml &lt;span class="nb"&gt;exec &lt;/span&gt;db pg_dump &lt;span class="nt"&gt;-U&lt;/span&gt; eyeonmajors eyeonmajors_production &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; backups/db_&lt;span class="p"&gt;$(&lt;/span&gt;shell &lt;span class="nb"&gt;date&lt;/span&gt; +%Y%m%d_%H%M%S&lt;span class="p"&gt;)&lt;/span&gt;.sql
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"✅ Backup complete!"&lt;/span&gt;

&lt;span class="nl"&gt;status&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"📊 System status:"&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Uptime: &lt;/span&gt;&lt;span class="p"&gt;$(&lt;/span&gt;&lt;span class="s2"&gt;shell uptime&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Disk usage: &lt;/span&gt;&lt;span class="p"&gt;$(&lt;/span&gt;&lt;span class="s2"&gt;shell df -h / | tail -1 | awk '{print &lt;/span&gt;&lt;span class="nv"&gt;$5&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;')"&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Memory usage: &lt;/span&gt;&lt;span class="p"&gt;$(&lt;/span&gt;&lt;span class="s2"&gt;shell free -h | grep '^Mem:' | awk '{print &lt;/span&gt;&lt;span class="nv"&gt;$3&lt;/span&gt;&lt;span class="s2"&gt; "&lt;/span&gt;/&lt;span class="s2"&gt;" &lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;')"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Usage:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./make deploy    &lt;span class="c"&gt;# Deploy latest code&lt;/span&gt;
./make logs      &lt;span class="c"&gt;# View application logs  &lt;/span&gt;
./make health    &lt;span class="c"&gt;# Check app status&lt;/span&gt;
./make backup    &lt;span class="c"&gt;# Create database backup&lt;/span&gt;
./make status    &lt;span class="c"&gt;# System overview&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For hobby projects, this works fine for a start:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;Simple to understand&lt;/strong&gt; (no complex CI/CD to debug)&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Fast iteration&lt;/strong&gt; (deploy in 30 seconds)&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Easy to modify&lt;/strong&gt; (just edit the Makefile)&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Educational&lt;/strong&gt; (you learn the actual deployment steps)&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;Reliable&lt;/strong&gt; (no external dependencies or complex pipelines)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The preferred approach:&lt;/strong&gt; GitHub Actions that run &lt;code&gt;rails test&lt;/code&gt;, then SSH to your Mac Mini to kick off the Docker builds on successful tests. &lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Performance: EyeOnMajors.com
&lt;/h2&gt;

&lt;p&gt;Since moving to self-hosting, I've been able to implement features that would have been cost-prohibitive on cloud hosting:&lt;/p&gt;

&lt;h3&gt;
  
  
  Background Processing
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Multiple concurrent Sidekiq workers processing:&lt;/span&gt;
&lt;span class="c1"&gt;# - Leaderboard updates every 30 seconds&lt;/span&gt;
&lt;span class="c1"&gt;# - Image processing and optimization  &lt;/span&gt;
&lt;span class="c1"&gt;# - Push notification delivery&lt;/span&gt;
&lt;span class="c1"&gt;# - Data analysis and caching&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;On cloud hosting:&lt;/strong&gt; $15+/month for worker dynos&lt;br&gt;&lt;br&gt;
&lt;strong&gt;On Mac Mini:&lt;/strong&gt; 8 CPU cores, run as many workers as you want&lt;/p&gt;

&lt;h3&gt;
  
  
  Database and Storage
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# PostgreSQL with full-text search, JSON queries, large datasets&lt;/span&gt;
&lt;span class="c1"&gt;# Image storage with automatic optimization&lt;/span&gt;
&lt;span class="c1"&gt;# Historical data going back years&lt;/span&gt;
&lt;span class="c1"&gt;# No artificial storage limits&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;On cloud hosting:&lt;/strong&gt; $15-50/month depending on usage&lt;br&gt;&lt;br&gt;
&lt;strong&gt;On Mac Mini:&lt;/strong&gt; 256GB-1TB local storage, backup to external drive&lt;/p&gt;

&lt;h2&gt;
  
  
  The Honest Downsides
&lt;/h2&gt;

&lt;p&gt;Self-hosting isn't perfect. Here are the real tradeoffs:&lt;/p&gt;

&lt;h3&gt;
  
  
  0. Application Security is Still Your Responsibility
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; Cloudflare Tunnels secure your &lt;em&gt;infrastructure&lt;/em&gt;, not your &lt;em&gt;application&lt;/em&gt;. You still need to follow secure coding practices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Input validation&lt;/strong&gt; - Sanitize all user inputs to prevent SQL injection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;XSS protection&lt;/strong&gt; - Use Rails' built-in CSRF protection and sanitize outputs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authentication/authorization&lt;/strong&gt; - Implement proper user access controls&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependency management&lt;/strong&gt; - Keep Rails and gems updated (&lt;code&gt;bundle audit&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Environment variables&lt;/strong&gt; - Never commit secrets to your repository&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database security&lt;/strong&gt; - Use parameterized queries, limit database permissions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cloud hosting doesn't magically make your code secure either, but don't let the infrastructure security improvements give you a false sense of application security. The same security best practices apply regardless of where you host.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Single Point of Failure
&lt;/h3&gt;

&lt;p&gt;Your app goes down if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Power outage at your house&lt;/li&gt;
&lt;li&gt;Internet service provider issues&lt;/li&gt;
&lt;li&gt;Hardware failure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Mitigation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;UPS (Uninterruptible Power Supply) for power outages (~$100)&lt;/li&gt;
&lt;li&gt;Most ISPs have &amp;gt;99% uptime&lt;/li&gt;
&lt;li&gt;Mac Mini hardware is extremely reliable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For hobby projects, this is acceptable. For business-critical apps, you'd obviously want redundancy.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Internet Upload Speed Requirements
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;You need decent upload bandwidth.&lt;/strong&gt; I have 100 Mbps upload, which easily handles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;50+ concurrent users&lt;/li&gt;
&lt;li&gt;Real-time data updates&lt;/li&gt;
&lt;li&gt;Image serving via Cloudflare CDN&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check your upload speed: most fiber connections have 100+ Mbps upload, cable varies.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. You're Responsible for Maintenance
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Security updates (automated with scripts)&lt;/li&gt;
&lt;li&gt;Monitoring (simple health checks)&lt;/li&gt;
&lt;li&gt;Backups (multiple layers)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For backups, I use both the pg_dump script shown earlier plus a simple cron job that rsyncs my database backups and application files to a local NAS with RAID 5 storage. I want to be careful and mindful about not losing even fantasy golf data, and while it's not off-site, it provides good peace of mind for hobby projects. It would require multiple simultaneous failures for that data to be truly lost.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But honestly?&lt;/strong&gt; This is part of the fun. You learn how things actually work instead of being abstracted away from the infrastructure.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Advanced Move: Distributed Self-Hosting
&lt;/h2&gt;

&lt;p&gt;Want to get fancy? &lt;strong&gt;Deploy to a Mac Mini at your parents' house in another state.&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Buy second Mac Mini ($599)&lt;/li&gt;
&lt;li&gt;Ship to parents with setup instructions&lt;/li&gt;
&lt;li&gt;Configure Cloudflare tunnel there&lt;/li&gt;
&lt;li&gt;Use Cloudflare load balancing to distribute traffic&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Now you have:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Geographic redundancy&lt;/li&gt;
&lt;li&gt;Multiple data centers&lt;/li&gt;
&lt;li&gt;Still cheaper than cloud hosting&lt;/li&gt;
&lt;li&gt;Fun family tech project&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Cost Analysis: 3-Year Total Cost of Ownership
&lt;/h2&gt;

&lt;p&gt;Here's my actual cost breakdown for running EyeOnMajors.com:&lt;/p&gt;

&lt;h3&gt;
  
  
  3-Year Cost Comparison
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Option&lt;/th&gt;
&lt;th&gt;Year 1&lt;/th&gt;
&lt;th&gt;Year 2&lt;/th&gt;
&lt;th&gt;Year 3&lt;/th&gt;
&lt;th&gt;Total&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Cloud Hosting&lt;/td&gt;
&lt;td&gt;$684&lt;/td&gt;
&lt;td&gt;$684&lt;/td&gt;
&lt;td&gt;$684&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$2,052&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mac Mini&lt;/td&gt;
&lt;td&gt;$611&lt;/td&gt;
&lt;td&gt;$30&lt;/td&gt;
&lt;td&gt;$30&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$671&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Savings&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;td&gt;$654&lt;/td&gt;
&lt;td&gt;$654&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;$1,381&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  One-Time Costs
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Mac Mini M2: $599&lt;/li&gt;
&lt;li&gt;Domain registration: $12&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Total: $611&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Monthly Costs
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Electricity (10W continuous): ~$1.50&lt;/li&gt;
&lt;li&gt;Domain renewal: $1/month (amortized)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Total: $2.50/month&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Equivalent Cloud Hosting
&lt;/h3&gt;

&lt;p&gt;For the same functionality on cloud platforms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;App hosting: $17/month&lt;/li&gt;
&lt;li&gt;Database: $15/month
&lt;/li&gt;
&lt;li&gt;Background workers: $15/month&lt;/li&gt;
&lt;li&gt;Storage: $10/month&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Total: $57/month = $684/year&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The Mac Mini pays for itself in 11 months.&lt;/strong&gt; After that, you're saving $650+ every year.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters for Innovation
&lt;/h2&gt;

&lt;p&gt;&lt;a href="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%2F0wjusp9plz54f76yv6va.jpg" class="article-body-image-wrapper"&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%2F0wjusp9plz54f76yv6va.jpg" alt="Money Savings Lab Exploration" width="800" height="533"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Save money, build freely: Turn your home into a development playground&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The real benefit isn't just cost savings - &lt;strong&gt;it's removing barriers to exploration&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When hosting is expensive, you make compromises:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"I won't add real-time features" (too expensive)&lt;/li&gt;
&lt;li&gt;"I'll skip image optimization" (storage costs)&lt;/li&gt;
&lt;li&gt;"I won't implement that cool AI feature with a vector DB" &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When hosting is essentially free, you build what you &lt;strong&gt;want&lt;/strong&gt; to build:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Real-time tournament updates? Sure.&lt;/li&gt;
&lt;li&gt;Advanced image processing? Why not.&lt;/li&gt;
&lt;li&gt;Vector search for historical data? Let's try it.&lt;/li&gt;
&lt;li&gt;Web scraping integration? No problem.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Constraints breed creativity&lt;/strong&gt;, but &lt;strong&gt;financial constraints breed compromise&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Start: 30-Minute Setup
&lt;/h2&gt;

&lt;p&gt;Ready to try this? Here's the minimal path for people who are sold:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Get Hardware
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mac Mini M2&lt;/strong&gt; ($599): My recommendation, excellent performance/watt (and can remote screenshare easily)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Beelink EQR5&lt;/strong&gt; ($239): Budget option, still powerful, especially if you like Linux&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Raspberry Pi 5&lt;/strong&gt; ($80): For simple apps, surprisingly capable&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Set up Cloudflare
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Transfer domain DNS to Cloudflare (free)&lt;/li&gt;
&lt;li&gt;Install cloudflared: &lt;code&gt;brew install cloudflare/cloudflare/cloudflared&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Create tunnel: &lt;code&gt;cloudflared tunnel create myapp&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3. Deploy Rails App
&lt;/h3&gt;

&lt;p&gt;Use Docker (recommended) or direct install - whatever you're comfortable with&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Connect Tunnel
&lt;/h3&gt;

&lt;p&gt;Point to &lt;code&gt;localhost:3000&lt;/code&gt; (or your Rails port)&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Go Live
&lt;/h3&gt;

&lt;p&gt;Update DNS in Cloudflare dashboard&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Total time: ~30 minutes for basic setup&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started: Your First Self-Hosted Rails App
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Perfect First Projects
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Personal dashboard&lt;/li&gt;
&lt;li&gt;Hobby project API&lt;/li&gt;
&lt;li&gt;Learning new frameworks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Start simple, then expand as you get comfortable.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Future of Hobby Hosting
&lt;/h2&gt;

&lt;p&gt;I think we're seeing a shift back to self-hosting, driven by:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Cloud hosting getting expensive&lt;/strong&gt; (inflation + profit maximization)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Home hardware getting powerful&lt;/strong&gt; (Apple Silicon, efficiency improvements)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security tools improving&lt;/strong&gt; (Cloudflare Tunnels, Tailscale, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developer tools maturing&lt;/strong&gt; (Docker, simple deployment)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Self-hosting in 2025 feels like what cloud hosting promised in 2015&lt;/strong&gt; - simple, powerful, cost-effective.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources and Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cloudflare Tunnels&lt;/strong&gt;: &lt;a href="https://www.cloudflare.com/products/tunnel/" rel="noopener noreferrer"&gt;cloudflare.com/products/tunnel&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EyeOnMajors.com&lt;/strong&gt;: &lt;a href="https://eyeonmajors.com" rel="noopener noreferrer"&gt;eyeonmajors.com&lt;/a&gt; (live example)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mac Mini&lt;/strong&gt;: &lt;a href="https://www.apple.com/mac-mini/" rel="noopener noreferrer"&gt;apple.com/mac-mini&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Beelink Mini PCs&lt;/strong&gt;: &lt;a href="https://www.bee-link.com/" rel="noopener noreferrer"&gt;bee-link.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Conclusion: Rediscovering the Joy of Building
&lt;/h2&gt;

&lt;p&gt;Moving from cloud hosting to self-hosting brought back something I'd lost: &lt;strong&gt;the joy of building without constraints&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;No more calculating whether a feature is "worth the hosting cost." No more architectural decisions driven by pricing tiers. No more death by a thousand $5/month cuts.&lt;/p&gt;

&lt;p&gt;Just me, a $599 Mac Mini, and the freedom to build whatever I can imagine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your hobby projects deserve better than 512MB of shared RAM.&lt;/strong&gt; Give self-hosting a try - you might be surprised how much fun infrastructure can be when it's actually yours.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;I want to hear from you:&lt;/strong&gt; Are you currently paying $20/month or more for cloud hosting on hobby projects? What's your biggest barrier to trying self-hosting - is it the security concerns, the setup complexity, or something else entirely?&lt;/p&gt;

&lt;p&gt;Drop a comment below - I'd love to help you get started or hear about your own self-hosting adventures!&lt;/p&gt;




&lt;h3&gt;
  
  
  Appendix: Technical Details
&lt;/h3&gt;

&lt;p&gt;For the technically curious, here are the detailed specs and configurations I use:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mac Mini M2 Configuration:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;8-core CPU, 10-core GPU&lt;/li&gt;
&lt;li&gt;16GB unified memory&lt;/li&gt;
&lt;li&gt;256GB SSD (upgraded to 1TB external)&lt;/li&gt;
&lt;li&gt;Gigabit Ethernet&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Software Stack for this side project:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker Desktop&lt;/li&gt;
&lt;li&gt;Ruby 3.2 + Rails 8&lt;/li&gt;
&lt;li&gt;PostgreSQL 16&lt;/li&gt;
&lt;li&gt;Redis for caching&lt;/li&gt;
&lt;li&gt;Sidekiq for background jobs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Cloudflare Configuration:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Free tier (no Pro features needed)&lt;/li&gt;
&lt;li&gt;SSL/TLS: Full (strict)&lt;/li&gt;
&lt;li&gt;Security level: Medium&lt;/li&gt;
&lt;li&gt;Always Use HTTPS: Enabled&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Network Setup:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Static IP assigned via router DHCP reservation (192.168.1.x or whatever works for your local network)&lt;/li&gt;
&lt;li&gt;Cloudflare tunnel: outbound-only&lt;/li&gt;
&lt;li&gt;No ports forwarded on router&lt;/li&gt;
&lt;li&gt;UPS for power backup&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This configuration has been rock-solid for me and enables me to host apps, with better performance, and besides the initial hardware, very low cost.&lt;/p&gt;

</description>
      <category>rails</category>
      <category>selfhosting</category>
      <category>cloudflare</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
