Markbot Robot on Steampunk Rocket Be adventurous and free - start hosting this stuff yourself with no barriers to your exploration!

The $17/Month Death by a Thousand Cuts

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: hosting costs that kill exploration.

Here’s what a typical “simple” Rails app costs on popular platforms:

PlatformBasic PlanWhat You GetThe Reality
Heroku$7/dyno + $9/postgres512MB RAM, shared CPUNeed 2+ dynos for real traffic = $23+/month
Railway$5/service512MB RAM, 1GB storageAdd database, background jobs = $15+/month
Render$7/service512MB RAMPlus $7 for PostgreSQL = $14+/month
DigitalOcean App Platform$12/month512MB RAM, 1GB diskMinimal for any real app

The real killer isn’t the base price - it’s what happens when you want to do more exploration:

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

Suddenly your hobby project costs $50-100/month. At that point, you start making technical compromises not because they’re better, but because you don’t want to pay for exploration.

Enter the Mac Mini: $2/Month for 20x the Performance

Last year, I bought a Mac Mini M2 for $599. Here’s what I’m running on it right now:

EyeOnMajors.com: A Real-World Example

EyeOnMajors.com 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:

  • Database storage (historical tournament data)
  • Real-time data processing (background jobs)
  • Image processing (tournament photos, player headshots)
  • Web scraping (CPU intensive, banned on basic plans)
  • File storage (images, cached data)

My actual monthly cost: $2.25 (domain + electricity)

Performance Comparison: Cloud vs Mac Mini

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

It’s not even close. The Mac Mini has roughly 20-50x the resources for a fraction of the ongoing cost.

The Security Problem (Solved by Cloudflare Tunnels)

The traditional blocker for self-hosting was security. Opening ports on your home network? Dealing with dynamic IPs? Managing SSL certificates? No thanks.

But Cloudflare Tunnels changed everything.

  • Cloudflare Tunnel (originally called “Argo Tunnel”) was launched around 2018-2019
  • It became free for all users in 2021 (previously required paid plans)
  • The rebranding from “Argo Tunnel” to “Cloudflare Tunnel” happened around 2021-2022

What Cloudflare Tunnels Do

Cloudflare Tunnels create a secure, outbound-only connection from your home server to Cloudflare’s edge network. Here’s the magic:

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

Cloudflare Tunnel Traffic Flow Diagram Encrypted tunnels - no exposed ports, no router configuration needed

Setting Up EyeOnMajors.com with Cloudflare Tunnels

The setup took me about 30 minutes:

  1. Transfer DNS to Cloudflare (free)
  2. Install cloudflared on Mac Mini:
    brew install cloudflare/cloudflare/cloudflared
    
  3. Create and configure tunnel:
    cloudflared tunnel login
    cloudflared tunnel create eyeonmajors
    
  4. Point tunnel to Rails app:
    # ~/.cloudflared/config.yml
    tunnel: eyeonmajors
    ingress:
      - hostname: eyeonmajors.com
        service: http://localhost:3000
      - service: http_status:404
    
  5. Update DNS in Cloudflare dashboard:
    • Type: CNAME
    • Name: eyeonmajors.com
    • Content: [tunnel-id].cfargotunnel.com

That’s it. No port forwarding, no SSL certificates, no dynamic DNS. Just works.

What You Get with Cloudflare’s Free Tier

This blew my mind - Cloudflare’s free tier includes:

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

Free tier limits that matter for hobby projects:

  • 1,000 tunnels per account (you’ll use 1-3)
  • 100MB max file upload size
  • Must serve legitimate website content (no video streaming or large file hosting)

Services that could cost $100+/month on AWS are completely free with Cloudflare.

The Rails Deployment: Simple Make Scripts (For Now)

Full disclosure: 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:

# EyeOnMajors.com Production Makefile
.PHONY: deploy logs health backup status

deploy:
    @echo "🚀 Deploying EyeOnMajors..."
    git pull origin main
    docker-compose -f docker-compose.production.yml up -d --build
    @echo "✅ Deployment complete!"

logs:
    @echo "📋 Viewing application logs..."
    docker-compose -f docker-compose.production.yml logs -f web

health:
    @echo "🏥 Checking application health..."
    curl -s http://localhost:3000/health | jq
    docker-compose -f docker-compose.production.yml ps

backup:
    @echo "💾 Creating database backup..."
    docker-compose -f docker-compose.production.yml exec db pg_dump -U eyeonmajors eyeonmajors_production > backups/db_$(shell date +%Y%m%d_%H%M%S).sql
    @echo "✅ Backup complete!"

status:
    @echo "📊 System status:"
    @echo "Uptime: $(shell uptime)"
    @echo "Disk usage: $(shell df -h / | tail -1 | awk '{print $5}')"
    @echo "Memory usage: $(shell free -h | grep '^Mem:' | awk '{print $3 "/" $2}')"

Usage:

./make deploy    # Deploy latest code
./make logs      # View application logs  
./make health    # Check app status
./make backup    # Create database backup
./make status    # System overview

For hobby projects, this works fine for a start:

  • Simple to understand (no complex CI/CD to debug)
  • Fast iteration (deploy in 30 seconds)
  • Easy to modify (just edit the Makefile)
  • Educational (you learn the actual deployment steps)
  • Reliable (no external dependencies or complex pipelines)

The preferred approach: GitHub Actions that run rails test, then SSH to your Mac Mini to kick off the Docker builds on successful tests.

Real-World Performance: EyeOnMajors.com

Since moving to self-hosting, I’ve been able to implement features that would have been cost-prohibitive on cloud hosting:

Background Processing

# Multiple concurrent Sidekiq workers processing:
# - Leaderboard updates every 30 seconds
# - Image processing and optimization  
# - Push notification delivery
# - Data analysis and caching

On cloud hosting: $15+/month for worker dynos
On Mac Mini: 8 CPU cores, run as many workers as you want

Database and Storage

# PostgreSQL with full-text search, JSON queries, large datasets
# Image storage with automatic optimization
# Historical data going back years
# No artificial storage limits

On cloud hosting: $15-50/month depending on usage
On Mac Mini: 256GB-1TB local storage, backup to external drive

The Honest Downsides

Self-hosting isn’t perfect. Here are the real tradeoffs:

0. Application Security is Still Your Responsibility

Important: Cloudflare Tunnels secure your infrastructure, not your application. You still need to follow secure coding practices:

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

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.

1. Single Point of Failure

Your app goes down if:

  • Power outage at your house
  • Internet service provider issues
  • Hardware failure

Mitigation:

  • UPS (Uninterruptible Power Supply) for power outages (~$100)
  • Most ISPs have >99% uptime
  • Mac Mini hardware is extremely reliable

For hobby projects, this is acceptable. For business-critical apps, you’d obviously want redundancy.

2. Internet Upload Speed Requirements

You need decent upload bandwidth. I have 100 Mbps upload, which easily handles:

  • 50+ concurrent users
  • Real-time data updates
  • Image serving via Cloudflare CDN

Check your upload speed: most fiber connections have 100+ Mbps upload, cable varies.

3. You’re Responsible for Maintenance

  • Security updates (automated with scripts)
  • Monitoring (simple health checks)
  • Backups (multiple layers)

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.

But honestly? This is part of the fun. You learn how things actually work instead of being abstracted away from the infrastructure.

The Advanced Move: Distributed Self-Hosting

Want to get fancy? Deploy to a Mac Mini at your parents’ house in another state.

  1. Buy second Mac Mini ($599)
  2. Ship to parents with setup instructions
  3. Configure Cloudflare tunnel there
  4. Use Cloudflare load balancing to distribute traffic

Now you have:

  • Geographic redundancy
  • Multiple data centers
  • Still cheaper than cloud hosting
  • Fun family tech project

Cost Analysis: 3-Year Total Cost of Ownership

Here’s my actual cost breakdown for running EyeOnMajors.com:

3-Year Cost Comparison

OptionYear 1Year 2Year 3Total
Cloud Hosting$684$684$684$2,052
Mac Mini$611$30$30$671
Savings-$654$654$1,381

One-Time Costs

  • Mac Mini M2: $599
  • Domain registration: $12
  • Total: $611

Monthly Costs

  • Electricity (10W continuous): ~$1.50
  • Domain renewal: $1/month (amortized)
  • Total: $2.50/month

Equivalent Cloud Hosting

For the same functionality on cloud platforms:

  • App hosting: $17/month
  • Database: $15/month
  • Background workers: $15/month
  • Storage: $10/month
  • Total: $57/month = $684/year

The Mac Mini pays for itself in 11 months. After that, you’re saving $650+ every year.

Why This Matters for Innovation

Money Savings Lab Exploration Save money, build freely: Turn your home into a development playground

The real benefit isn’t just cost savings - it’s removing barriers to exploration.

When hosting is expensive, you make compromises:

  • “I won’t add real-time features” (too expensive)
  • “I’ll skip image optimization” (storage costs)
  • “I won’t implement that cool AI feature with a vector DB”

When hosting is essentially free, you build what you want to build:

  • Real-time tournament updates? Sure.
  • Advanced image processing? Why not.
  • Vector search for historical data? Let’s try it.
  • Web scraping integration? No problem.

Constraints breed creativity, but financial constraints breed compromise.

Quick Start: 30-Minute Setup

Ready to try this? Here’s the minimal path for people who are sold:

1. Get Hardware

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

2. Set up Cloudflare

  • Transfer domain DNS to Cloudflare (free)
  • Install cloudflared: brew install cloudflare/cloudflare/cloudflared
  • Create tunnel: cloudflared tunnel create myapp

3. Deploy Rails App

Use Docker (recommended) or direct install - whatever you’re comfortable with

4. Connect Tunnel

Point to localhost:3000 (or your Rails port)

5. Go Live

Update DNS in Cloudflare dashboard

Total time: ~30 minutes for basic setup

Getting Started: Your First Self-Hosted Rails App

Perfect First Projects

  • Personal dashboard
  • Hobby project API
  • Learning new frameworks

Start simple, then expand as you get comfortable.

The Future of Hobby Hosting

I think we’re seeing a shift back to self-hosting, driven by:

  1. Cloud hosting getting expensive (inflation + profit maximization)
  2. Home hardware getting powerful (Apple Silicon, efficiency improvements)
  3. Security tools improving (Cloudflare Tunnels, Tailscale, etc.)
  4. Developer tools maturing (Docker, simple deployment)

Self-hosting in 2025 feels like what cloud hosting promised in 2015 - simple, powerful, cost-effective.


Conclusion: Rediscovering the Joy of Building

Moving from cloud hosting to self-hosting brought back something I’d lost: the joy of building without constraints.

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.

Just me, a $599 Mac Mini, and the freedom to build whatever I can imagine.

Your hobby projects deserve better than 512MB of shared RAM. Give self-hosting a try - you might be surprised how much fun infrastructure can be when it’s actually yours.


I want to hear from you: 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?

Drop a comment or reach out on X @markholton - I’d love to help you get started or hear about your own self-hosting adventures.


Appendix: Technical Details

For the technically curious, here are the detailed specs and configurations I use:

Mac Mini M2 Configuration:

  • 8-core CPU, 10-core GPU
  • 16GB unified memory
  • 256GB SSD (upgraded to 1TB external)
  • Gigabit Ethernet

Software Stack for this side project:

  • Docker Desktop
  • Ruby 3.2 + Rails 8
  • PostgreSQL 16
  • Redis for caching
  • Sidekiq for background jobs

Cloudflare Configuration:

  • Free tier (no Pro features needed)
  • SSL/TLS: Full (strict)
  • Security level: Medium
  • Always Use HTTPS: Enabled

Network Setup:

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

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.