Local Hosting
Run PiggyBack on your own machine or VPS using Docker. Full data sovereignty.
What You'll Need
An Up Bank account
You'll need a personal access token from the Up API developer portal
Git
To clone the repository
Docker Desktop
Or Docker Engine on Linux — required for Docker and local Supabase
Node.js 20+
Only needed if running without Docker
Choose Your Database
| Option A: Hosted | Option B: Local | |
|---|---|---|
| Setup | Easier — free project at supabase.com | More involved — runs via Docker |
| Data location | Supabase's cloud servers | Your machine (Docker volumes) |
| Privacy | Standard cloud hosting | Full data sovereignty |
| Maintenance | Managed by Supabase | You manage backups/updates |
| Cost | Free tier (generous) | Free (your machine's resources) |
| Dashboard | supabase.com | localhost:54323 |
Set Up Supabase
- Go to supabase.com and sign in
- Click New Project, name it, set a database password, choose a region
- Wait for initialization (~2 minutes)
Run the migration:
- Go to SQL Editor → New query
- Copy the entire contents of
supabase/migrations/00000000000000_initial_schema.sql - Paste and click Run
Configure auth URLs:
- Go to Authentication → URL Configuration
- Set Site URL to
http://localhost:3000 - Add redirect URLs:
http://localhost:3000/auth/callbackandhttp://localhost:3000/update-password
Get your keys:
Go to Settings → API. Note your Project URL, anon key, and service_role key.
Install the Supabase CLI:
# macOS brew install supabase/tap/supabase # npm (all platforms) npm install -g supabase
Start local Supabase:
cd PiggyBack supabase start
This pulls Docker images on first run (~2-5 minutes). Once running, you'll see output with your API URL, anon key, and service_role key. Copy these for the next step.
supabase/migrations/ is applied automatically when you start. Your data persists across restarts. To stop: supabase stop. Access the local dashboard at localhost:54323.Clone & Configure
git clone https://github.com/BenLaurenson/PiggyBack.git cd PiggyBack cp .env.local.example .env.local
Edit .env.local with your values:
NEXT_PUBLIC_SUPABASE_URL=https://your-project-id.supabase.co NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key_from_dashboard SUPABASE_SERVICE_ROLE_KEY=your_service_role_key_from_dashboard UP_API_ENCRYPTION_KEY=your_32_character_key NEXT_PUBLIC_APP_URL=http://localhost:3000
NEXT_PUBLIC_SUPABASE_URL=http://127.0.0.1:54321 NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key_from_supabase_start SUPABASE_SERVICE_ROLE_KEY=your_service_role_key_from_supabase_start UP_API_ENCRYPTION_KEY=your_32_character_key NEXT_PUBLIC_APP_URL=http://localhost:3000
Generate Your Encryption Key
node -e "console.log(require('crypto').randomBytes(16).toString('hex'))"This produces a 32-character hex string. Paste it as your UP_API_ENCRYPTION_KEY.
NEXT_PUBLIC_SKIP_LANDING=true to skip the marketing landing page.Run PiggyBack
With Docker (Recommended)
# Build and run docker compose -f docker-compose.prod.yml up --build # Run in the background docker compose -f docker-compose.prod.yml up --build -d # Stop docker compose -f docker-compose.prod.yml down
First build takes a few minutes. Once you see Ready in Xs, open localhost:3000.
Without Docker
npm install npm run build npm start
The app starts on localhost:3000. For development with hot-reload, use npm run dev (runs on port 3005).
First-Time Setup
- Open localhost:3000
- Click Sign Up and create your account
- Option A (hosted): Check your email for the confirmation link
- Option B (local): Email confirmation is disabled — you're signed in immediately
- Complete the onboarding flow
- Connect your Up Bank API token in Settings → Up Bank Connection
Updating
Pull the latest changes and rebuild:
git pull # Docker: docker compose -f docker-compose.prod.yml up --build -d # Without Docker: npm install npm run build npm start
Option A: Run the new SQL in the Supabase SQL Editor
Option B:
supabase db reset (warning: resets all data) or apply the specific migration manuallyOptional Configuration
Cron Jobs (Payment Reminders)
Set up a cron job or scheduled task to call the endpoint daily:
# Runs at 9am daily — replace <secret> with your CRON_SECRET 0 9 * * * curl -H "Authorization: Bearer <secret>" http://localhost:3000/api/cron/notifications
AI Assistant
Each user configures their own AI provider — no server-side keys needed. Go to Settings → AI and choose Google Gemini, OpenAI, or Anthropic.
Up Bank Webhooks (Real-Time Sync)
For local deployments, you'll need a tunnel service like ngrok or Cloudflare Tunnel. Set WEBHOOK_BASE_URL in your .env.local to your tunnel URL. Without webhooks, transactions sync when you open the app.
Exposing to the Internet (VPS)
Set up a reverse proxy (Nginx or Caddy) in front of port 3000. Caddy handles SSL automatically:
piggyback.yourdomain.com {
reverse_proxy localhost:3000
}Update NEXT_PUBLIC_APP_URL to your public domain. For Option A, also update Supabase redirect URLs.
Troubleshooting
Docker build fails with "standalone" error
Make sure you're on the latest version. Run git pull and rebuild.
Can't connect to local Supabase
Verify Supabase is running (supabase status), check Docker is running (docker ps), and ensure ports 54321-54323 aren't in use.
"Invalid login credentials" after signup
Option A: Check your email for the confirmation link. Option B: This shouldn't happen since email confirmation is disabled. Try supabase db reset to start fresh.
Auth redirect loops
Option A: Verify Supabase dashboard Site URL is http://localhost:3000 and redirect URLs include /auth/callback and /update-password. Option B: The config.toml handles this automatically.
Port conflicts
Docker runs on 3000. If it's taken, edit docker-compose.prod.yml ports. Dev server runs on 3005. Local Supabase uses 54321-54323.
Database migration issues
Option A: Ensure you copied the ENTIRE migration SQL (~1400 lines). Option B: Migrations apply automatically on supabase start. To reapply: supabase db reset.