Skip to content

Cloud Migration Evaluation

This document provides a comprehensive comparison of cloud migration options for the Tower Fleet k3s cluster, focusing on external accessibility while maintaining local infrastructure security.


Table of Contents


Executive Summary

Goal: Enable external access to homelab applications without exposing local network to internet.

Key Requirements: - External accessibility for web apps (home-portal, money-tracker, trip-planner) - Keep local infrastructure as primary (no VPN-less access to local network) - Budget: $20-100/month - Maintain development environment locally

Top Recommendations: 1. Experimentation (Now): Oracle Cloud Free Tier - Zero cost, real production capability 2. Production (After testing): Hetzner Cloud - Best value at ~$32/month 3. AWS Experience: AWS EKS - Premium option at ~$60-70/month


Requirements & Constraints

Functional Requirements

  • External Access: Public-facing apps accessible without VPN
  • Local Isolation: No direct external access to local network (security requirement)
  • Database in Cloud: PostgreSQL/Supabase can move to cloud
  • Hybrid Operation: Local cluster remains operational for internal services

Non-Functional Requirements

  • Budget: $20-100/month preferred
  • Security: VPN required for local network access
  • Maintainability: Minimal operational overhead
  • Flexibility: Can switch providers without major refactoring

Out of Scope (Staying Local)

  • Media stack (arr-stack VM)
  • NAS storage (LXC 101)
  • Internal-only services
  • Development environments (can use local or cloud)

Architecture Patterns

Architecture:

┌─────────────────────────────────────────┐
│           Cloud Environment             │
│                                         │
│  ┌─────────────────────────────────┐   │
│  │   Cloud k3s Cluster             │   │
│  │                                 │   │
│  │  • home-portal (public)         │   │
│  │  • money-tracker (public)       │   │
│  │  • trip-planner (public)        │   │
│  │                                 │   │
│  │  PostgreSQL:                    │   │
│  │  • Self-hosted Supabase    OR   │   │
│  │  • Managed PostgreSQL           │   │
│  └─────────────────────────────────┘   │
│                                         │
└─────────────────────────────────────────┘
           Internet Access
┌─────────────────────────────────────────┐
│        Local Homelab (VPN Only)         │
│                                         │
│  ┌─────────────────────────────────┐   │
│  │   Local k3s Cluster             │   │
│  │                                 │   │
│  │  • Development environments     │   │
│  │  • Internal services            │   │
│  │  • Media stack (arr-stack)      │   │
│  │  • NAS storage                  │   │
│  │                                 │   │
│  │  Supabase (local dev instances) │   │
│  └─────────────────────────────────┘   │
│                                         │
└─────────────────────────────────────────┘

Pros: - Complete isolation between public and private - Local network never exposed to internet - Independent scaling and operation - Clear security boundary

Cons: - Duplicate infrastructure management - Can't easily share services between clusters - Apps deployed twice (local dev, cloud prod)

Best For: Your use case - external access without compromising local security


Architecture:

┌─────────────────────────────────────────┐
│   Single k3s Cluster (Mixed Nodes)      │
│                                         │
│  Cloud Nodes:           Local Nodes:    │
│  • Master node          • Worker nodes  │
│  • Public ingress       • Storage       │
│  • External apps        • Internal svcs │
└─────────────────────────────────────────┘

Why Not: - High latency affects etcd consensus - Network costs for pod-to-pod communication - Complex scheduling (cloud vs local placement) - Split-brain risk if connectivity drops - Violates security requirement (local nodes accessible from cloud)


Architecture:

Cloud VM → Cloudflare Tunnel/Tailscale → Local k3s

Why Not: - Violates security requirement (external access tunnels to local) - Single point of failure - Latency for all requests - Local network still involved in external traffic


Cloud Provider Comparison

AWS (Experience & Enterprise)

Instance Types: - Control Plane + Workers: 2-3x t3.small (2vCPU, 2GB RAM) - Alternative: EKS managed control plane + t3.small workers

Monthly Cost Breakdown:

EC2 Instances:
  2x t3.small (On-Demand):  $15.33/mo each  = $30.66
  Alternative: 3x t3.small                  = $45.99

Load Balancer:
  Application LB:                           = $16.20
  Network traffic (~100GB):                 = $9.00

RDS PostgreSQL:
  db.t4g.micro (20GB storage):              = $15.00

EBS Storage (100GB across instances):       = $10.00

Total (Self-managed k3s):                   ≈ $80-90/month
Total (EKS managed):                        ≈ $145-160/month
  (EKS control plane: $72/mo)

Pros: - Industry-standard platform (AWS experience valuable for career) - Rich ecosystem (RDS, S3, Lambda, CloudFront, etc.) - Excellent documentation and community support - Can integrate with AWS services (SES for emails, S3 for storage) - Free tier available for 12 months (t2.micro, limited RDS) - Enterprise-grade reliability and SLAs

Cons: - Most expensive option (2-3x competitors) - Complex pricing (easy to overspend) - Steep learning curve (IAM, VPCs, security groups) - Overkill for homelab use case

Best For: - Learning AWS specifically for career/work - Planning to use AWS-specific services - Budget allows $80-100+/month

Learning Value: - ⭐⭐⭐⭐⭐ (Industry standard, widely used)


Hetzner Cloud (Best Value)

Instance Types: - CX21: 2vCPU, 4GB RAM, 40GB SSD - €4.51/mo ($4.90) - CX31: 2vCPU, 8GB RAM, 80GB SSD - €9.51/mo ($10.30) - CPX21: 3vCPU, 4GB RAM, 80GB SSD - €9.21/mo ($10.00)

Recommended Setup: - 2x CX21 for k3s nodes - Hetzner Managed PostgreSQL (Basic: 2GB RAM, 25GB) - €13/mo - Load Balancer - €5.39/mo

Monthly Cost Breakdown:

Compute (2x CX21):                          = €9.02  ($9.80)
Managed PostgreSQL:                         = €13.00 ($14.10)
Load Balancer:                              = €5.39  ($5.85)
Traffic (20TB included, unlimited):         = €0.00

Total:                                      ≈ €27.41 ($29.75/month)

Pros: - Best price-to-performance ratio - Simple, intuitive interface - Generous included bandwidth (20TB!) - EU-based (good for GDPR if relevant) - Excellent network performance - Fast provisioning (<60 seconds) - Managed PostgreSQL available

Cons: - Less "brand name" than AWS/Azure/GCP - Fewer managed services - EU locations only (may have latency for US users) - Smaller ecosystem

Best For: - Best value for money - Production homelab deployments - Learning k8s without cloud-specific lock-in

Learning Value: - ⭐⭐⭐ (Pure k8s/Linux skills, portable knowledge)


DigitalOcean (Managed Simplicity)

Managed Kubernetes (DOKS): - Control Plane: Free (DO manages) - Worker Nodes: Basic Droplets 2GB RAM - $12/mo each - Managed PostgreSQL: 1GB RAM, 10GB SSD, 7-day backups - $15/mo

DIY k3s Option: - Basic Droplets: 2GB RAM - $12/mo each - Same managed PostgreSQL

Monthly Cost Breakdown:

Option A - Managed DOKS:
  Worker nodes (2x $12):                    = $24.00
  Managed PostgreSQL:                       = $15.00
  Load Balancer (included in DOKS):         = $0.00
  Total:                                    ≈ $39/month

Option B - DIY k3s:
  Droplets (2x $12):                        = $24.00
  Managed PostgreSQL:                       = $15.00
  Total:                                    ≈ $39/month

Pros: - Managed k8s option (easier operations) - Clean, beginner-friendly interface - Excellent documentation and tutorials - 1-click apps and integrations - Predictable pricing - Good community support

Cons: - More expensive than Hetzner for same specs - Managed PostgreSQL small (1GB RAM minimum) - Limited free tier ($200 credit for 60 days)

Best For: - Want managed k8s to reduce ops burden - Prefer simplicity over cost optimization - Good middle-ground between Hetzner and AWS

Learning Value: - ⭐⭐⭐⭐ (Managed k8s, good docs, clear concepts)


Oracle Cloud (Free Tier Experiment)

Always Free Resources: - 4x ARM Ampere A1 instances: 4 OCPU, 24GB RAM (combined) - Can configure as: 4x (1 OCPU, 6GB) or 2x (2 OCPU, 12GB) - Block Storage: 200GB total - Flexible Network Load Balancer: 1 instance, 10Mbps - Outbound Traffic: 10TB/month

Recommended Configuration for k3s:

2x ARM instances (2 OCPU, 12GB RAM each):
  - Node 1: Master + worker
  - Node 2: Worker

Monthly Cost:

Compute (ARM free tier):                    = $0.00
Storage (200GB free):                       = $0.00
Network (10TB free):                        = $0.00

Optional Add-ons:
  Larger load balancer:                     ≈ $10-15/mo
  x86 instances (if ARM doesn't work):      ≈ $5-10/mo

Total:                                      = $0-15/month

Pros: - Actually FREE (not trial, permanent "Always Free" tier) - Surprising capability (24GB RAM total!) - Can run full production workload at zero cost - Good performance (ARM Ampere processors) - 10TB/month bandwidth included

Cons: - ARM architecture (requires ARM-compatible images) - Most Docker images support ARM now - Next.js, PostgreSQL, Supabase all have ARM builds - Account approval can be difficult (anti-fraud checks) - Oracle's reputation/UI not as polished - Support limited on free tier - Risk: Oracle could change free tier policy (rare but possible)

Best For: - Zero-cost experimentation - Testing cloud deployment before committing money - Actually running production if ARM compatible

ARM Compatibility for Your Stack: - ✅ Next.js - Full ARM support - ✅ PostgreSQL - Native ARM builds - ✅ Supabase - Works on ARM (community tested) - ✅ NGINX Ingress - ARM compatible - ⚠️ May need to verify individual app dependencies

Learning Value: - ⭐⭐⭐⭐ (Real k8s, free experimentation, ARM architecture exposure)

Getting Started Tips: - Use a credit card (not debit) for better approval odds - Provide accurate information (Oracle verification is strict) - Start with smaller instance sizes, scale up later - Use Terraform/Ansible for reproducible setup (free tier can be reclaimed)


Azure (Alternative Enterprise Option)

Instance Types: - B2s: 2vCPU, 4GB RAM - ~$30/mo - AKS (Managed k8s): Free control plane + node costs

Monthly Cost (Estimated):

2x B2s instances:                           = $60.00
Azure PostgreSQL Flexible (Burstable):      = $20-30.00
Load Balancer:                              = $18.00

Total (DIY k3s):                            ≈ $98-108/month
Total (AKS):                                ≈ $98-108/month
  (AKS control plane free)

Pros: - Free AKS control plane (unlike AWS EKS) - Good for learning Azure specifically - Integration with Microsoft ecosystem - Strong hybrid cloud story (if you have on-prem Windows)

Cons: - Expensive (similar to AWS) - Complex pricing and billing - Interface can be overwhelming

Best For: - Work/career requires Azure knowledge - Already using Microsoft 365/Azure AD

Learning Value: - ⭐⭐⭐⭐ (Enterprise platform, common in corporate environments)


Google Cloud Platform (GCP)

Instance Types: - e2-medium: 2vCPU, 4GB RAM - ~$24/mo - GKE (Managed k8s): Free control plane (1 cluster) + node costs

Monthly Cost (Estimated):

2x e2-medium instances:                     = $48.00
Cloud SQL PostgreSQL (small):               = $25.00
Load Balancer:                              = $18.00

Total:                                      ≈ $91/month

Pros: - Free GKE control plane - Excellent k8s integration (Google invented k8s) - Good free tier ($300 credit for 90 days) - Strong data/ML services

Cons: - Expensive - Known for unexpected project shutdowns - Complex billing

Best For: - Learning GKE/k8s best practices - Want Google ML/data services

Learning Value: - ⭐⭐⭐⭐⭐ (k8s native, best k8s documentation)


Supabase Deployment Options

Your apps depend on Supabase for PostgreSQL, Auth, Storage, and Realtime. You have three options for cloud deployment.

Option 1: Supabase Cloud (Managed)

What It Is: - Fully managed Supabase platform (supabase.com) - No self-hosting required

Pricing: - Free Tier: 500MB database, 1GB file storage, 50,000 monthly active users - Good for experimentation - Paused after 7 days inactivity (can unpause) - Pro Tier: $25/month - 8GB database, 100GB file storage - No inactivity pause - Daily backups, 7-day retention - Suitable for production

Pros: - Zero operational overhead - Automatic updates and patches - Built-in backups and point-in-time recovery - Dashboard for management - Best reliability (Supabase team manages)

Cons: - Ongoing monthly cost ($25/month minimum for production) - Less control over configuration - Data stored on Supabase's infrastructure - Vendor lock-in

Best For: - Minimal operational burden - Budget allows $25/month - Want professional-grade database management

Monthly Cost Impact: - Free tier: $0 (experimentation only) - Pro tier: +$25/month to cloud infrastructure cost


Option 2: Self-Hosted Supabase in k3s

What It Is: - Deploy full Supabase stack (PostgreSQL, PostgREST, GoTrue, Realtime, Storage) in your cloud k3s cluster - Same as your local setup

Resource Requirements: - Minimum: 2-4GB RAM dedicated to Supabase pods - Storage: 20-50GB for database + file storage - Recommended: Dedicated node or large instances

Pros: - Full control over configuration - No additional monthly cost (beyond compute) - Matches local development setup - Can customize Supabase components

Cons: - Operational overhead (updates, backups, monitoring) - Requires k8s knowledge - More complex troubleshooting - You're responsible for backups - Consumes significant resources (affects instance sizing)

Best For: - Want full control - Have k8s expertise - Budget-constrained (include in compute cost)

Implementation: - Use official Supabase Helm chart or docker-compose manifests - Configure persistent volumes for PostgreSQL - Set up backups (pgBackRest, Velero, or manual pg_dump) - Monitor with Prometheus/Grafana

Monthly Cost Impact: - Included in compute cost - May need larger instances: +$5-15/month


Option 3: Managed PostgreSQL + Minimal Supabase

What It Is: - Use cloud provider's managed PostgreSQL (AWS RDS, DO Managed DB, Hetzner DB) - Self-host lightweight Supabase components (PostgREST, GoTrue) in k3s

Pros: - Provider manages database (backups, updates, scaling) - Lower resource usage in k3s - Better database reliability than DIY - Lower cost than full Supabase Cloud

Cons: - Split management (database vs app components) - Supabase components still need maintenance - May not support all Supabase features easily - More complex setup

Best For: - Want managed database benefits - Don't need full Supabase Cloud - Comfortable with hybrid approach

Monthly Cost Impact: - Managed PostgreSQL: $15-30/month (depending on size) - k3s runs lightweight Supabase components (minimal resource impact)


Supabase Option Comparison Table

Feature Supabase Cloud Self-Hosted in k3s Managed DB + Components
Monthly Cost $25 (Pro) Included in compute $15-30 (DB only)
Operational Burden None High Medium
Customization Limited Full Medium
Backup Management Automatic Manual Automatic (DB only)
Resource Usage N/A 2-4GB RAM <1GB RAM
Learning Value Low High Medium
Production Ready Immediate Requires setup Requires setup

Recommendation for Your Situation:

  • Starting out: Supabase Cloud free tier (remove cost variable while learning)
  • Budget-conscious: Self-hosted in k3s (learning experience, no extra cost)
  • Production-ready: Managed PostgreSQL + components (good middle ground)
  • Long-term: Supabase Cloud Pro if budget allows ($25/month for peace of mind)

Cost Analysis

Scenario 1: Zero-Cost Experimentation

Setup: - Oracle Cloud Free Tier (ARM instances) - Self-hosted Supabase in k3s - Oracle Load Balancer (free tier)

Monthly Cost: $0

Pros: No financial commitment, real production capability Cons: ARM architecture, Oracle approval process


Setup: - Hetzner Cloud 2x CX21 instances - Hetzner Managed PostgreSQL - Self-hosted Supabase components (or Supabase Cloud)

Monthly Cost: - Infrastructure: $30 - Option A (Self-hosted Supabase): $30/month total - Option B (Supabase Cloud Pro): $55/month total

Pros: Best value, production-ready, simple management Cons: EU-only locations


Scenario 3: Managed Simplicity

Setup: - DigitalOcean Managed Kubernetes - DO Managed PostgreSQL - Self-hosted Supabase components

Monthly Cost: - Infrastructure: $39/month - With Supabase Cloud: $64/month

Pros: Easiest to operate (managed control plane) Cons: Higher cost than Hetzner DIY


Scenario 4: AWS Experience

Setup: - AWS 2x t3.small instances (self-managed k3s) - AWS RDS PostgreSQL (t4g.micro) - Application Load Balancer

Monthly Cost: - Infrastructure: ~$80-90/month - With Supabase Cloud: ~$105-115/month

Pros: AWS experience, enterprise ecosystem Cons: Most expensive, complex billing


Scenario 5: AWS Managed (Premium)

Setup: - AWS EKS (managed control plane) - 2x t3.small worker nodes - AWS RDS PostgreSQL - Application Load Balancer

Monthly Cost: - Infrastructure: ~$145-160/month - With Supabase Cloud: ~$170-185/month

Pros: Fully managed, minimal operations Cons: Very expensive for homelab


Cost Comparison Table

Scenario Monthly Cost Operational Burden Learning Value Production Ready
Oracle Free + Self-hosted Supabase $0 High ⭐⭐⭐⭐ Yes (if ARM works)
Hetzner + Self-hosted Supabase $30 Medium ⭐⭐⭐⭐ Yes
Hetzner + Supabase Cloud $55 Low ⭐⭐⭐ Yes
DO DOKS + Managed DB $39 Low ⭐⭐⭐⭐ Yes
AWS DIY k3s + RDS $80-90 Medium ⭐⭐⭐⭐⭐ Yes
AWS EKS + RDS $145-160 Low ⭐⭐⭐⭐⭐ Yes

Migration Effort Estimates

Phase 1: Cloud Cluster Setup

Oracle Cloud Free Tier: - Account creation & approval: 1-2 days (Oracle verification) - Instance provisioning: 30 minutes - k3s cluster setup: 1-2 hours (ARM troubleshooting) - Total: 2-4 hours (plus approval wait)

Hetzner Cloud: - Account creation: 5 minutes - Instance provisioning: 5 minutes - k3s cluster setup: 1 hour - Total: 1-2 hours

AWS: - Account setup: 15 minutes - VPC/Security group configuration: 30-60 minutes - Instance provisioning: 15 minutes - k3s cluster setup: 1-2 hours - Total: 2-4 hours (more if learning AWS)

DigitalOcean DOKS (Managed): - Account setup: 5 minutes - Managed k8s cluster creation: 15 minutes (DO does it) - Configure kubectl: 5 minutes - Total: 30-60 minutes (easiest option)


Phase 2: Supabase Deployment

Supabase Cloud (Managed): - Create project: 5 minutes - Run migrations: 15 minutes - Configure DNS/connection strings: 15 minutes - Total: 30-45 minutes

Self-Hosted Supabase in k3s: - Deploy Supabase stack: 1-2 hours - Configure persistent storage: 30 minutes - Run migrations: 15 minutes - Troubleshoot issues: 1-2 hours (first time) - Total: 3-5 hours (more on first attempt)

Managed PostgreSQL + Components: - Provision managed DB: 15 minutes - Deploy PostgREST/GoTrue: 1 hour - Configure connections: 30 minutes - Run migrations: 15 minutes - Total: 2-3 hours


Phase 3: Application Deployment

Per Application (e.g., home-portal): - Build Docker image: 15 minutes - Push to registry: 10 minutes - Create k8s manifests (Deployment, Service, Ingress): 30 minutes - Deploy and test: 30 minutes - Configure environment variables: 15 minutes - Troubleshoot issues: 30-60 minutes - Total: 2-3 hours per app

For 3 apps (home-portal, money-tracker, trip-planner): - First app: 3 hours (learning) - Second app: 2 hours (template reuse) - Third app: 1 hour (streamlined) - Total: 6 hours for all apps


Phase 4: DNS & Ingress Configuration

Setup: - Configure DNS records: 15 minutes - Install cert-manager: 15 minutes - Configure Let's Encrypt: 15 minutes - Test HTTPS access: 15 minutes - Total: 1 hour


Phase 5: CI/CD & GitOps (Optional)

GitHub Actions Deployment: - Create workflow files: 1 hour - Configure secrets: 15 minutes - Test pipeline: 30 minutes - Total: 2 hours

ArgoCD/Flux (GitOps): - Install ArgoCD: 30 minutes - Configure app repositories: 1 hour - Set up automated sync: 30 minutes - Total: 2 hours


Total Migration Effort Summary

Path Time Investment Spread Over
Quick Test (Oracle + Supabase Cloud) 4-6 hours 1 weekend
Budget Production (Hetzner + Self-hosted) 12-16 hours 2 weekends
Managed Easy (DO DOKS + Supabase Cloud) 6-8 hours 1 weekend
AWS Learning (DIY k3s + RDS) 16-20 hours 2-3 weekends
Full GitOps Production 20-30 hours 3-4 weekends

Note: These are hands-on keyboard hours. Calendar time will be longer due to waiting for DNS propagation, learning, troubleshooting, etc.


Security Considerations

Network Isolation

Requirement: No direct external access to local network without VPN.

Cloud Architecture Enforcement: - Cloud k3s cluster has NO network connectivity to local network - Local cluster remains behind firewall, VPN-only access - Apps in cloud are standalone deployments (separate instances) - Database in cloud (not tunneling to local Supabase)

Access Patterns:

✅ ALLOWED:
- External users → Cloud apps (public access)
- You → Cloud apps (public access)
- You → Local cluster (via VPN)

❌ BLOCKED:
- External users → Local cluster (no route)
- Cloud cluster → Local cluster (no connection)
- External users → Local apps (behind VPN)


Data Security

Database in Cloud: - Encryption at rest (all providers support) - Encryption in transit (TLS/SSL) - Regular backups (managed or self-configured) - Consider: What data is sensitive? - Financial data (money-tracker) - may want extra encryption - Personal trips (trip-planner) - generally fine in cloud - Home portal - links and metadata, low sensitivity

Recommendation: - Use managed database with encryption enabled - Enable automated backups (point-in-time recovery) - Rotate database credentials regularly - Consider application-level encryption for sensitive fields (money-tracker)


Authentication & Access Control

Supabase Auth: - Keep existing Supabase Auth setup - Configure JWT secrets properly - Enable MFA for admin accounts - Use row-level security (RLS) policies

Kubernetes Access: - Use kubectl with certificate auth (not username/password) - Enable RBAC (Role-Based Access Control) - Restrict API server access (firewall rules) - Consider Teleport/Boundary for audited access

Cloud Provider IAM: - Use least-privilege IAM policies - Enable MFA for cloud provider account - Use service accounts for automation (not personal credentials) - Audit access logs regularly


Secrets Management

Current Approach: - .env.local files (gitignored) - Manual secret management

Cloud Best Practices: - Kubernetes Secrets: Base64-encoded, stored in etcd - Enable etcd encryption at rest - Sealed Secrets: Encrypted secrets safe to commit to git - External Secret Operators: Sync from cloud provider secret stores - AWS Secrets Manager - DO Managed Secrets (coming soon) - Hetzner doesn't have secret store (use k8s secrets)

Recommendation: - Start with Kubernetes secrets (simple) - Graduate to Sealed Secrets when you have CI/CD - Use cloud provider secrets for database credentials


Compliance & Privacy

Data Residency: - Hetzner (EU): Data stored in Germany/Finland - AWS/DO/Oracle: Can choose region (US, EU, Asia) - Consider: Do you need GDPR compliance? (EU users)

Backup Locations: - Managed databases: Provider handles (usually same region) - Self-hosted: Configure backup storage location

Recommendation: - Choose region close to primary users (latency) - If EU users: Consider EU-based provider (Hetzner) for GDPR ease


Disaster Recovery

Cloud Outage Scenarios: - Provider outage: Can failover to local cluster? (if VPN accessible) - Account compromise: Have backups outside cloud account - Data loss: Regular backups to separate location

Recommendation: - Keep local cluster as fallback (can redeploy apps locally if needed) - Automated database backups to separate storage (S3, Backblaze B2) - Document recovery procedures - Test recovery process (restore from backup quarterly)


Decision Matrix

Quick Reference: Which Cloud Provider?

If You Want... Choose
Zero cost experimentation Oracle Cloud Free Tier
Best value for money Hetzner Cloud
Easiest managed experience DigitalOcean DOKS
AWS experience for career AWS EC2 + EKS
Minimal operational burden DigitalOcean or AWS with managed services
Maximum learning Hetzner DIY k3s + self-hosted Supabase
Future enterprise scalability AWS or Azure

Supabase Decision Tree

Do you want to learn database operations and k8s?
├─ Yes: Self-hosted Supabase in k3s
│   └─ Comfortable with 3-5 hours setup + ongoing maintenance
└─ No: Managed option
    ├─ Budget allows $25/month?
    │   ├─ Yes: Supabase Cloud Pro (easiest)
    │   └─ No: Managed PostgreSQL + lightweight components ($15/mo)
    └─ Want zero ops burden: Supabase Cloud Pro

Budget Decision Tree

What's your monthly budget?
├─ $0-10: Oracle Cloud Free Tier (ARM)
│   └─ Can tolerate ARM compatibility issues?
│       ├─ Yes: Go for it!
│       └─ No: Start with free tier to learn, then Hetzner
├─ $20-40: Hetzner Cloud
│   └─ Self-hosted Supabase: ~$30/mo
│   └─ Supabase Cloud Pro: ~$55/mo
├─ $40-60: DigitalOcean DOKS (managed k8s)
│   └─ Lower ops burden, higher cost
└─ $80+: AWS (for experience/enterprise learning)
    ├─ DIY k3s: ~$80-90/mo
    └─ Managed EKS: ~$145-160/mo

Based on your requirements (external access, $20-100/month budget, local isolation, discovery phase), here's my recommended approach:


Stage 1: Zero-Cost Discovery (NOW - Week 1-2)

Goal: Learn cloud k8s deployment without financial commitment.

Action Plan: 1. Sign up for Oracle Cloud Free Tier - Use credit card (better approval odds) - Provide accurate info (strict verification) - Wait for approval (1-3 days)

  1. Deploy minimal k3s cluster
  2. 2x ARM instances (2 OCPU, 12GB RAM each)
  3. Install k3s (master + worker)
  4. Configure kubectl locally

  5. Deploy one app for testing

  6. Clone trip-planner (least critical)
  7. Use Supabase Cloud free tier (simplify)
  8. Test external access with Oracle LB

  9. Evaluate ARM compatibility

  10. Do your apps build for ARM?
  11. Any dependency issues?
  12. Performance acceptable?

Time Investment: 4-6 hours over 1 weekend Cost: $0 Success Criteria: - Can deploy and access app externally - Understand k8s deployment workflow - Identified any ARM issues


Stage 2: Production Decision (Week 3-4)

Based on Stage 1 results:

If Oracle/ARM worked well: - Stay on free tier! - Deploy remaining apps - Configure monitoring - Set up backups

If Oracle had issues or want more robust setup: - Migrate to Hetzner Cloud (~$30/mo) - 2x CX21 instances + managed PostgreSQL - Self-hosted Supabase components - Deploy all 3 apps

Action Plan: 1. Deploy Supabase (Cloud or self-hosted) 2. Migrate apps one by one: - home-portal first (most mature) - money-tracker second - trip-planner third 3. Configure custom domains (if you have one) 4. Set up monitoring (Prometheus/Grafana or cloud native)

Time Investment: 12-16 hours over 2 weekends Cost: $0 (Oracle) or $30-55/month (Hetzner)


Stage 3: Optimization (Week 5-8)

Goal: Streamline operations and reduce toil.

Action Plan: 1. Set up CI/CD: - GitHub Actions for automated builds - Push to container registry - Auto-deploy to k8s on merge

  1. GitOps (Optional):
  2. Install ArgoCD
  3. Git as source of truth
  4. Automated sync

  5. Backup automation:

  6. Database backups to S3/B2
  7. Velero for k8s resources
  8. Test restore process

  9. Monitoring & alerting:

  10. Configure Grafana dashboards
  11. Set up alerts (Slack/email)

Time Investment: 8-12 hours over 2-3 weekends Cost: No change


Alternative: AWS Learning Path

If you prioritize AWS experience over cost:

Stage 1: AWS Free Tier (First 12 Months) - t2.micro instances (1 GB RAM) x2 - Free - RDS t2.micro - Free for 12 months - ALB not free (~$16/mo unavoidable)

Limitation: t2.micro might be underpowered (1GB RAM tight for Next.js)

Stage 2: Paid AWS (After validation) - Upgrade to t3.small instances - Follow Stage 2/3 from Oracle path above - Budget: $80-90/month


Migration Timeline Summary

Timeframe Activity Cost Outcome
Week 1-2 Oracle free tier experiment $0 Validated cloud deployment
Week 3-4 Production deployment (Hetzner or stay Oracle) $0-55/mo All apps externally accessible
Week 5-8 CI/CD, monitoring, backups No change Automated operations
Month 3+ Steady state, evaluate switch to AWS if desired Variable Production-ready homelab in cloud

When to Consider AWS

Switch to AWS if: - Oracle/Hetzner running stable for 2-3 months - Want AWS-specific learning (career motivation) - Budget increased to $80-100/month - Want to use AWS services (S3, Lambda, SES, etc.)

Migration path: Export k8s manifests → Deploy to AWS → Update DNS → Done (4-6 hours)


Next Steps

To proceed, you need to decide:

  1. Start with Oracle free tier? (Recommended for discovery phase)
  2. Pros: Zero cost, real learning
  3. Cons: ARM architecture, approval wait

  4. Go straight to Hetzner? (If you want to skip Oracle)

  5. Pros: x86 architecture, faster start
  6. Cons: $30-55/month commitment

  7. AWS for experience? (If career/learning priority)

  8. Pros: Industry standard platform
  9. Cons: $80-90/month, steeper learning curve

I recommend: Start with Oracle, move to Hetzner after validation.


Questions to Clarify

Before proceeding with cloud setup, clarify:

  1. Domain name: Do you have a domain for external apps? (e.g., homelab.example.com)
  2. If not: Can use IP addresses + cert warnings (testing)
  3. If yes: Configure DNS once cluster is up

  4. Data sensitivity: Any concerns with financial data (money-tracker) in cloud?

  5. Consider: Application-level encryption for sensitive fields
  6. Alternative: Keep money-tracker local-only

  7. Uptime expectations: Is downtime for learning/experimentation acceptable?

  8. Yes: Proceed with experimentation freely
  9. No: Start with managed services (DO DOKS, Supabase Cloud)

  10. Local cluster status: Current local k3s cluster stable?

  11. Will serve as fallback if cloud experiments fail
  12. Document current setup for reference

  13. Time availability: How much time per week for this project?

  14. 2-4 hours/week: Spread over 2 months (steady pace)
  15. 8-12 hours/week: Complete in 3-4 weeks (focused sprint)

Conclusion

TL;DR Recommendations:

  1. Best Value: Hetzner Cloud (~$30/mo)
  2. Zero Cost: Oracle Cloud Free Tier (if ARM compatible)
  3. AWS Learning: AWS EC2 + RDS (~$80/mo)
  4. Easiest: DigitalOcean DOKS + Supabase Cloud (~$64/mo)

Recommended Path: - Start: Oracle free tier (2 weeks, $0) - Production: Hetzner + self-hosted Supabase (ongoing, $30/mo) - Optional: Move to AWS later if desired (career focus)

Next Action: - Decide which path interests you most - I can guide you through specific setup for chosen path

Let me know which direction you'd like to explore first!