Spin up BFF with your own Perso key
In 5–10 minutes, fork vibi-bff, start it with your own Perso key, and point a physical-device vibi mobile build at it.
Assumes you have already completed "Prerequisites" in ../learning/getting-started.md.
1. Fork & clone
gh repo fork <upstream-vibi-bff-url> --clone --remote
cd vibi-bff
Or grab a zip under your account and unpack it — either works.
2. Write .env
cp .env.example .env
Keys to fill in .env:
PERSO_API_KEY=<your_perso_api_key>
PERSO_SPACE_SEQ=<your_workspace_seq>
SEPARATION_SIGNING_SECRET=<output of: openssl rand -hex 32>
AUTH_JWT_SECRET=<output of: openssl rand -hex 32>
GOOGLE_OAUTH_CLIENT_IDS=<iOS, Android, Web client ids — comma-separated>
For caption translation and chat you also need Vertex AI variables. Full table in ../reference/environment.md.
⚠️ Never commit
.envto git. It is already listed in.gitignore— verify.
3. Verify boot
./gradlew run
Success signal:
[main] INFO Application - Responding at http://0.0.0.0:8080
Live check:
curl http://localhost:8080/api/v2/languages | jq .
An HTTP 200 with a JSON array of supported languages means the Perso key is live. If you get 401 / 402 → troubleshooting.md#perso-402--payment-required.
4. External exposure options
If you only use it from emulators/simulators on the same machine, skip this step (localhost:8080 or 10.0.2.2:8080). To expose to a physical device or another computer, two common options:
Option A — LAN exposure (home / office)
ipconfig getifaddr en0 # macOS, Wi-Fi
# e.g. 192.168.1.42
Both iOS and Android physical devices must be on the same Wi-Fi. Set the mobile BFF_BASE_URL to http://192.168.1.42:8080/.
Also set .env's BFF_BASE_URL to the same value — this value is embedded in signed download URLs. A signed URL handed out externally is useless if it points at localhost.
BFF_BASE_URL=http://192.168.1.42:8080
If a firewall blocks 8080 you'll see connect timeout — on macOS, System Settings → Network → Firewall, allow Java/Gradle or turn it off briefly. Details in connect-real-device.md.
Option B — ngrok (HTTPS, reachable anywhere)
ngrok http 8080
Copy the https URL from the Forwarding https://<random>.ngrok-free.app -> http://localhost:8080 line.
# .env
BFF_BASE_URL=https://<random>.ngrok-free.app
# vibi-mobile/local.properties
BFF_BASE_URL=https://<random>.ngrok-free.app/
ngrok's free tier rotates the URL every session. For a fixed URL, use an ngrok subdomain or a cloudflare tunnel.
Side benefit: https means you can ignore iOS ATS workarounds (the
http://in option A needs extra iOS-side configuration).
Option C — Cloud Run + GitHub Actions (production)
The repo ships with everything needed to run the BFF on Google Cloud Run, fronted by a fixed HTTPS URL and redeployed on main push:
Dockerfile— multi-stage JDK21 → JRE21 + ffmpeg,MaxRAMPercentage=75..dockerignore/.gcloudignore— keep secrets and caches out of the build context.deploy/cloud-run.sh— idempotent bootstrap (enables APIs, creates the runtime service account, loads.envinto Secret Manager, runs the firstgcloud run deploy)..github/workflows/deploy.yml— main-branch push triggers a Workload Identity Federation login andgcloud run deploy --source .. No service account JSON stored in GitHub.
Quickstart:
# 1. First-time bootstrap from your laptop (creates the SA + secrets + first Cloud Run revision)
cd vibi-bff
./deploy/cloud-run.sh
# 2. One-time WIF setup so GitHub Actions can deploy without a JSON key
# Follow deploy/GITHUB_ACTIONS_SETUP.md (workload-identity-pools create + provider + SA binding)
# 3. Add the four secrets GitHub Actions needs
# GCP_PROJECT_ID / GCP_REGION / GCP_WIF_PROVIDER / GCP_SA_EMAIL
After that, git push origin main ships a new revision. The runtime credential is the Cloud Run attached service account — GOOGLE_APPLICATION_CREDENTIALS stays blank and GeminiClient falls back to Application Default Credentials via the metadata server. Memory-tier vs upload-size: scale MAX_UPLOAD_FILE_SIZE_MB down when running on --memory 1Gi, up on 4Gi+.
The full walkthrough — WIF bootstrap commands, the four GitHub secrets, the per-secret IAM role, and a table mapping four common errors (invalid_target, unauthorized_client, iam.serviceAccounts.getAccessToken denied, run deploy: Permission denied) to their root cause — lives in vibi-bff/deploy/GITHUB_ACTIONS_SETUP.md.
5. Wire up mobile
# vibi-mobile/local.properties
sdk.dir=/Users/<you>/Library/Android/sdk
BFF_BASE_URL=http://192.168.1.42:8080/ # or the ngrok https URL
After changing the value, a rebuild is required:
cd vibi-mobile
./gradlew :cmp:assembleDebug --no-configuration-cache
For iOS, Clean Build Folder in Xcode and then Run.
6. Verify
Launch the app → upload a video → run auto-captions once.
You should see lines like this in the BFF console:
[POST] /api/v2/subtitles
[GET] /api/v2/subtitles/sub-...
If this is the first call from a physical device or a different computer, note that per-user Perso workspace usage counts against the BFF's PERSO_API_KEY quota.
Common pitfalls
| Symptom | Where to go |
|---|---|
| Key validation fails on BFF boot | troubleshooting.md#perso_api_key-must-not-be-blank-on-boot |
| connect timeout from mobile | connect-real-device.md |
| iOS rejects cleartext http | connect-real-device.md#ios-ats |
| Perso 402 | troubleshooting.md#perso-402--payment-required |
See also
- Background on the flow decisions:
../explanation/why-bff.md - Full environment variable set:
../reference/environment.md - BFF README:
vibi-bff/README.md(this doc takes the mobile / external-exposure angle; the README takes the BFF's own angle) - Cloud Run deploy details:
vibi-bff/deploy/GITHUB_ACTIONS_SETUP.md(referenced from Option C above)