UQ Cloud is a self-hosted Cloudinary alternative built entirely on free tiers: your Linux VPS runs the API + workers, Supabase handles DB & storage & auth, Cloudflare fronts everything with free CDN, WAF, and unlimited bandwidth.
Cloudinary is best understood as five stacked products sold as one. Any credible self-hosted alternative has to cover the same surface area — even if v1 only ships a subset.
| Layer | Pick | Why |
|---|---|---|
| Edge / CDN | Cloudflare Free (proxy + cache + WAF + Bot Fight) | Free unlimited bandwidth in front of your VPS; caches derivatives so origin barely gets hit |
| TLS / Reverse Proxy | Caddy on VPS (auto-HTTPS via Cloudflare Origin cert) | Zero-config HTTP/2+3, one Caddyfile |
| Signed URLs at edge | Cloudflare Worker (Free: 100k req/day) | Verify HMAC signatures before hitting origin — blocks abuse for free |
| API + Web | Node.js (Fastify) on VPS, single Docker container | Streaming + TUS uploads on a $5 VPS; add workers later |
| Object Storage | Supabase Storage (Free: 1 GB) → Cloudflare R2 (Free: 10 GB + zero egress) once you outgrow it | R2's zero egress is the killer feature for a media host — no bandwidth bill ever |
| Metadata DB | Supabase Postgres Free (500 MB, pg_trgm + pgvector included) | Managed Postgres, auth, and RLS in one — no DB to babysit on the VPS |
| Auth | Supabase Auth (email + OAuth) for dashboard; HMAC API keys for programmatic | Free, RLS-enforced; API keys stored in a Supabase table |
| Queue / Cache | Postgres-backed queue (pg-boss) + in-memory LRU on VPS | Skip Redis entirely on free tier — pg-boss uses your existing Supabase DB |
| Image Pipeline | libvips via sharp on VPS worker | 10× faster + lower memory than ImageMagick; runs fine on 1 vCPU |
| SVG Pipeline | SVGO (sanitize) + resvg-js (rasterize) | Pure npm, no native deps beyond prebuilt binaries |
| 3D Pipeline | gltf-transform + Draco/Meshopt + KTX2; thumbnail via headless-gl or screenshot from <model-viewer> | All Node/WASM — runs on the same VPS worker |
| Analytics | Cloudflare Web Analytics (Free) + Supabase logs table | Bandwidth + hit counts without paying for a metrics stack |
| Packaging | Single docker-compose.yml on the VPS (api + worker + caddy) | One `docker compose up -d` on a fresh Ubuntu box |
Everything below stays inside free tiers of Cloudflare, Supabase, and your existing Linux VPS. No credit card required, no egress surprises.
| Service | What you get free | Free-tier limit |
|---|---|---|
| Cloudflare Free | Unlimited bandwidth, CDN, WAF, Bot Fight, Web Analytics | 100k Worker req/day, 3 Page Rules |
| Supabase Free | Postgres 500 MB, Auth, Storage 1 GB, 2 GB egress/mo, pgvector | Pauses after 7 days of inactivity — cron a keep-alive |
| Your Linux VPS | API + workers + Caddy (sharp / SVGO / gltf-transform / ffmpeg) | 1 vCPU / 1 GB RAM is enough for P1–P3; swap on for safety |
| Cloudflare R2 (optional) | 10 GB storage + zero egress fees, S3-compatible | 1M Class-A + 10M Class-B ops/mo free |
| GitHub Actions Free | CI + SSH deploy to VPS | 2000 min/mo on public repos = unlimited |
| UptimeRobot Free | 50 monitors, 5-min checks, email alerts | No SMS on free |
Cache-Control: public, max-age=31536000, immutable. After the first request, your VPS never sees the traffic again — Cloudflare eats it for free.Each phase ends in a shippable milestone. You can stop after P4 and have a real Cloudinary alternative for images, SVG, and 3D — the later phases are additive.
When you say go, I'll scaffold the monorepo, docker-compose stack, and the database schema from P0 — then move into the P1 upload + media library MVP.