Files
advance-photo-gallery-web-sdk/docs/DEPLOY.md
T
2026-07-18 01:34:52 +05:30

5.5 KiB

Deploying for free (Vercel + Supabase free tier)

This app runs 100% on free tiers: Vercel Hobby (Next.js hosting) + Supabase Free (Postgres for metadata + Storage for the media files). No paid services are required. The in-browser AI (object detection, faces, OCR) runs on the user's device for free; only the optional Gemini generative edit needs a key (and can be left off).

TL;DR — run the SQL once, push to GitHub, import into Vercel with Root Directory = apps/web, set the two NEXT_PUBLIC_SUPABASE_* env vars, deploy. Everything (photos, videos, tags, versions, comments, albums, edited copies) then persists to your Supabase project.


1. Supabase (database + file storage)

  1. Create a project at https://supabase.com (free tier).
  2. Open SQL Editor → New query, paste all of docs/supabase-setup.sql, and Run. This creates the metadata tables, the demo RLS policies, and the public media storage bucket (the bucket is what makes uploaded/edited/captured files survive a reload — without it the app silently falls back to non-durable URLs).
  3. Confirm Storage now lists a bucket named media marked Public.
  4. Project Settings → API → copy:
    • Project URLNEXT_PUBLIC_SUPABASE_URL
    • anon public key → NEXT_PUBLIC_SUPABASE_ANON_KEY (Never use the service_role key in the client — it stays server-side only, if used at all.)

Free-tier note: a Supabase project pauses after ~7 days idle. Open the dashboard to unpause before a demo. Storage free tier is 1 GB, Postgres 500 MB — plenty for a demo library.

2. Push the repo to GitHub

Commit everything including pnpm-lock.yaml at the repo root (Vercel uses it to detect pnpm and install the whole workspace). Do not commit .env.local (it's gitignored).

3. Vercel

  1. https://vercel.comAdd New → Project → import your GitHub repo.

  2. Configure the project:

    Setting Value
    Root Directory apps/web
    Framework Preset Next.js (auto-detected)
    Install Command pnpm install (default)
    Build Command next build (default)
    Output .next (default)
    Node.js Version 20.x

    No separate SDK build step is needed: @photo-gallery/sdk is consumed from TypeScript source via Next's transpilePackages, so pnpm install (which links the workspace) is enough.

  3. Environment Variables (Project → Settings → Environment Variables), for Production + Preview:

    Client (safe to expose — required for persistence):

    Name Value
    NEXT_PUBLIC_SUPABASE_URL your Project URL
    NEXT_PUBLIC_SUPABASE_ANON_KEY your anon public key
    NEXT_PUBLIC_SUPABASE_BUCKET media (optional; default is media)

    Server-only (optional — do NOT prefix with NEXT_PUBLIC):

    Name Value
    GEMINI_API_KEY a Gemini key (only for the AI generative-edit button)
    GEMINI_IMAGE_MODEL gemini-2.5-flash-image (optional)

    Without the Supabase vars the app still runs, but on browser-local storage only (data won't sync across devices). Without GEMINI_API_KEY the generative-edit route returns 503 while all the free in-browser AI keeps working.

    Optional theming/feature flags (NEXT_PUBLIC_APG_*) are documented in docs/ENV.md.

  4. Deploy.

4. Verify after the first deploy

  • Response headers include a per-request content-security-policy with a nonce-… (confirms the nonce CSP middleware works on Vercel — expected; the app renders dynamically, not as a static export).
  • Import a photo → its src becomes a https://<project>.supabase.co/... URL → hard-reload: it still shows. Same for a camera capture and an edited copy.
  • Edit a photo twice → the Info panel shows Version 3; reload → history + comments persist.
  • The Objects sidebar section fills in as on-device detection tags photos.

What persists to the database

Everything is stored as JSONB per item (gallery_media.data) + binaries in Storage, so a reload restores it all: tags, detected objects/labels, faces, versions[] (full edit history + audit log), comments[], albums, favorites, edits, and Save-as-Copy items (each copy is a new row with its own 2-entry history). System/smart albums (incl. the auto object albums) are regenerated on load, so they're intentionally not stored.

Gotchas / limits (free tier)

  • Gemini AI edit + Vercel body limit: Vercel Hobby caps request bodies at ~4.5 MB. The AI-edit route is capped accordingly and large images are downscaled client-side first; very large images may still be rejected. The free in-browser AI is unaffected.
  • Single-user demo: the Supabase adapter does a full-state sync (no auth). For multi-user, add Supabase Auth and scope rows per user before going to production (the RLS policies are open for the demo — tighten them with auth.uid()).
  • In-browser video export (trim/overlays/watermark/etc.) requires the source video to be readable for canvas capture. Same-origin (Supabase Storage with CORS, which is on by default) works; a cross-origin host without CORS headers can't be exported in-browser (the editor now surfaces a clear error instead of failing silently).
  • Heavy AI libs (TensorFlow.js / face-api / tesseract / transformers / imgly) are dynamically imported on the client only — they don't bloat the server bundle, but first analysis downloads model weights (cached afterwards).