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
- Requirements & Constraints
- Architecture Patterns
- Cloud Provider Comparison
- Supabase Deployment Options
- Cost Analysis
- Migration Effort Estimates
- Security Considerations
- Decision Matrix
- Recommended Path Forward
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¶
Pattern 1: Separate Cloud Cluster (Recommended)¶
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
Pattern 2: Hybrid Cluster (NOT Recommended)¶
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)
Pattern 3: Cloud Ingress Gateway (NOT Recommended for Your Needs)¶
Architecture:
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:
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
Scenario 2: Budget Production (Recommended)¶
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
Recommended Path Forward¶
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)
- Deploy minimal k3s cluster
- 2x ARM instances (2 OCPU, 12GB RAM each)
- Install k3s (master + worker)
-
Configure kubectl locally
-
Deploy one app for testing
- Clone trip-planner (least critical)
- Use Supabase Cloud free tier (simplify)
-
Test external access with Oracle LB
-
Evaluate ARM compatibility
- Do your apps build for ARM?
- Any dependency issues?
- 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
- GitOps (Optional):
- Install ArgoCD
- Git as source of truth
-
Automated sync
-
Backup automation:
- Database backups to S3/B2
- Velero for k8s resources
-
Test restore process
-
Monitoring & alerting:
- Configure Grafana dashboards
- 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:
- Start with Oracle free tier? (Recommended for discovery phase)
- Pros: Zero cost, real learning
-
Cons: ARM architecture, approval wait
-
Go straight to Hetzner? (If you want to skip Oracle)
- Pros: x86 architecture, faster start
-
Cons: $30-55/month commitment
-
AWS for experience? (If career/learning priority)
- Pros: Industry standard platform
- 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:
- Domain name: Do you have a domain for external apps? (e.g.,
homelab.example.com) - If not: Can use IP addresses + cert warnings (testing)
-
If yes: Configure DNS once cluster is up
-
Data sensitivity: Any concerns with financial data (money-tracker) in cloud?
- Consider: Application-level encryption for sensitive fields
-
Alternative: Keep money-tracker local-only
-
Uptime expectations: Is downtime for learning/experimentation acceptable?
- Yes: Proceed with experimentation freely
-
No: Start with managed services (DO DOKS, Supabase Cloud)
-
Local cluster status: Current local k3s cluster stable?
- Will serve as fallback if cloud experiments fail
-
Document current setup for reference
-
Time availability: How much time per week for this project?
- 2-4 hours/week: Spread over 2 months (steady pace)
- 8-12 hours/week: Complete in 3-4 weeks (focused sprint)
Conclusion¶
TL;DR Recommendations:
- Best Value: Hetzner Cloud (~$30/mo)
- Zero Cost: Oracle Cloud Free Tier (if ARM compatible)
- AWS Learning: AWS EC2 + RDS (~$80/mo)
- 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!