Problem
Running several personal and client-adjacent projects (this site, TradePlan, internal tools) on ad-hoc VPS instances was getting expensive and hard to reason about — no shared network, no single place to deploy, no consistent way to expose internal services safely.
Constraints
- Needed to keep cloud spend low: two Oracle Cloud “always free” instances plus a mini-PC at home, not a fleet of paid VMs.
- Services on different machines — cloud and home mini-PC alike — needed to talk to each other securely without exposing raw ports to the internet.
- Wanted one place to deploy a new app without hand-writing a fresh docker-compose stack and reverse-proxy config every time.
Architecture
Four nodes joined into one private Tailscale mesh: two Oracle Cloud (OCI) instances, a mini-PC at home, and a fourth node. One OCI node runs Coolify as the control plane for deploying and managing app containers; the second OCI node runs a self-hosted Supabase stack (Postgres, Auth, Storage) for projects that need a backend without relying on managed Supabase Cloud. The mini-PC hosts lower-priority apps. Cloudflare Tunnel exposes only the specific public-facing services, so nothing needs an open inbound port.
Stack
Tailscale, Coolify, Oracle Cloud Infrastructure (OCI), self-hosted Supabase, Cloudflare Tunnel, Docker.
My role
Designed and built the whole mesh: node provisioning, Tailscale ACLs, the Coolify control plane, the self-hosted Supabase stack, and the Cloudflare Tunnel ingress rules. Fully self-operated.
Outcome
This is the infrastructure this site and several other projects (TradePlan, internal tools) run on today.