Local Hosting

Run PiggyBack on your own machine or VPS using Docker. Full data sovereignty.

Run PiggyBack on your own machine or VPS using Docker. Choose between hosted Supabase (easier) or a fully local Supabase instance (maximum privacy).
Note on webhooks: Up Bank webhooks require a publicly accessible HTTPS URL. On a local machine, real-time transaction syncing won't work unless you use a tunnel service like ngrok or Cloudflare Tunnel. Without webhooks, your transactions will still sync — just when you open the app rather than in real time. If you're deploying to a VPS with a public domain, webhooks work out of the box.

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: HostedOption B: Local
SetupEasier — free project at supabase.comMore involved — runs via Docker
Data locationSupabase's cloud serversYour machine (Docker volumes)
PrivacyStandard cloud hostingFull data sovereignty
MaintenanceManaged by SupabaseYou manage backups/updates
CostFree tier (generous)Free (your machine's resources)
Dashboardsupabase.comlocalhost:54323
1

Set Up Supabase

Option A: Hosted Supabase
  1. Go to supabase.com and sign in
  2. Click New Project, name it, set a database password, choose a region
  3. Wait for initialization (~2 minutes)

Run the migration:

  1. Go to SQL Editor New query
  2. Copy the entire contents of supabase/migrations/00000000000000_initial_schema.sql
  3. Paste and click Run

Configure auth URLs:

  1. Go to Authentication URL Configuration
  2. Set Site URL to http://localhost:3000
  3. Add redirect URLs: http://localhost:3000/auth/callback and http://localhost:3000/update-password

Get your keys:

Go to SettingsAPI. Note your Project URL, anon key, and service_role key.

Option B: Local Supabase

Install the Supabase CLI:

terminal
# macOS
brew install supabase/tap/supabase

# npm (all platforms)
npm install -g supabase

Start local Supabase:

terminal
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.

The migration in supabase/migrations/ is applied automatically when you start. Your data persists across restarts. To stop: supabase stop. Access the local dashboard at localhost:54323.
2

Clone & Configure

terminal
git clone https://github.com/BenLaurenson/PiggyBack.git
cd PiggyBack
cp .env.local.example .env.local

Edit .env.local with your values:

Option A: Hosted Supabase
.env.local
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
Option B: Local Supabase
.env.local
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

terminal
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.

Tip: For personal use, add NEXT_PUBLIC_SKIP_LANDING=true to skip the marketing landing page.
3

Run PiggyBack

With Docker (Recommended)

terminal
# 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

terminal
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).

4

First-Time Setup

  1. Open localhost:3000
  2. Click Sign Up and create your account
  3. Option A (hosted): Check your email for the confirmation link
  4. Option B (local): Email confirmation is disabled — you're signed in immediately
  5. Complete the onboarding flow
  6. Connect your Up Bank API token in Settings Up Bank Connection
5

Updating

Pull the latest changes and rebuild:

terminal
git pull

# Docker:
docker compose -f docker-compose.prod.yml up --build -d

# Without Docker:
npm install
npm run build
npm start
If there are new database migrations, apply them:
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 manually

Optional Configuration

Cron Jobs (Payment Reminders)

Set up a cron job or scheduled task to call the endpoint daily:

crontab
# 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 SettingsAI 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:

Caddyfile
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.