Hybrid cloud homelab, May 2026 - present

Jarvis homelab

A repurposed laptop and two Oracle Cloud VMs on one Tailscale mesh, running 20+ self-hosted containers for ₹0 a month.

Role
Solo project: hardware, networking, services, monitoring and backups.
Stack
  • Ubuntu 24.04
  • Docker Compose
  • Oracle Cloud
  • Tailscale
  • Caddy
  • Cosmos
  • Let's Encrypt
  • Pi-hole
  • Unbound
  • Uptime Kuma
  • Glances
  • n8n
  • Bash
  • cron
Links

The problem

I wanted my own cloud: file sync, photo backup, a password manager and a media server, without paying a subscription for any of it.

The harder goal was that no single failure should take everything down, or go unnoticed.

How it's built

Three servers sit on one Tailscale mesh. Jarvis, a laptop at home, runs most of the services. Two Oracle Cloud Always Free VMs handle the rest: a small AMD instance that holds only the password manager and a monitor, and an Arm instance that runs a Minecraft server for friends.

Jarvis

Home server

Repurposed laptop at home

  • Intel Core i3-6006U, 2 cores
  • 8 GB RAM, 490 GB SSD
  • Intel HD 520 for VAAPI transcoding
  • Cosmos
  • Pi-hole
  • Unbound
  • Nextcloud
  • Immich
  • Jellyfin
  • Media automation ×7
  • Homepage
  • Uptime Kuma
  • Glances
  • n8n
  • Code-Server
  • DuckDNS
  • iSponsorBlockTV

vault-server

Password vault

Oracle Cloud, AMD Micro

  • 1 OCPU, 1 GB RAM
  • 2 GB swap file
  • Always Free tier
  • Vaultwarden
  • Caddy
  • Uptime Kuma
  • Glances

oracle-1

Game server

Oracle Cloud, Ampere A1

  • 2 OCPU (Arm), 12 GB RAM
  • 100 GB backup volume
  • Always Free tier
  • Crafty Controller
  • Glances

Laptop

Tailscale peer

My Windows laptop

  • Receives new media from Jarvis
Servers, the services on each, and what travels over the mesh.

Key decisions

Monitor every server from a different server

A monitor can't report its own outage. Jarvis and vault-server each run Uptime Kuma and watch each other every minute; both also watch oracle-1, which runs no monitor of its own. Alerts go out by email.

Give the password manager a machine of its own

Vaultwarden started on Jarvis, next to a media server that gets restarted all the time. I moved it to its own 1 GB VM, bound it to localhost and put Caddy in front for automatic TLS, so nothing else on the box can reach it directly.

That VM had about 227 MB free under normal load and the vault sometimes hung while loading. A 2 GB swap file fixed it. Every day a cron job copies the vault to Jarvis over Tailscale and keeps the last seven copies.

tar -czf "$TMP_PATH" -C "$DATA_DIR" .
scp -i "$SSH_KEY" "$TMP_PATH" "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/"
rm -f "$TMP_PATH"

# On Jarvis, keep only the last 7 backups
ssh -i "$SSH_KEY" "$REMOTE_USER@$REMOTE_HOST" \
  "cd $REMOTE_DIR && ls -t vaultwarden-backup-*.tar.gz | tail -n +8 | xargs -r rm --"
From vault-server/scripts/backup-vaultwarden.sh

Resolve DNS without a third party

Devices ask Pi-hole, which blocks ads and trackers and forwards the rest to Unbound. Unbound walks the DNS tree from the root servers itself, so no public resolver sees every lookup the house makes.

Results

CPU per media stream after switching Jellyfin to VAAPI
90% → 15%
monthly cost: Always Free VMs and a laptop I already had
₹0
health-check interval, each server watched from another
1 min

The i3 laptop could barely transcode one stream in software. Hardware transcoding on its Intel HD 520 made streaming usable while everything else keeps running.

Limits and next steps

  • Backups are compressed tarballs, not encrypted. Encrypting them with age before they leave the box is next.
  • Monitoring alerts me, but recovery is manual. Restarting failed containers automatically would close that loop.
  • The Minecraft backups sit on a volume attached to the same VM. Copying them to another machine would survive losing the instance.