Deploy your own simpleBudget backend (and optionally the frontend) with Docker Compose.
Two deployment modes:
- Backend-only — Self-host the database and API. Use the hosted frontend at simplebudget.vercel.app.
- Full stack — Self-host everything, including the frontend served via Caddy.
# 1. Clone this repo
git clone https://github.com/simplebudgets/simplebudget-selfhost.git
cd simplebudget-selfhost
# 2. Create and populate your environment file
cp deploy/.env.example deploy/.env
cd deploy && bash scripts/generate-secrets.sh && cd ..
# 3. Start the backend
docker compose -f deploy/compose.yml up -d
# 4. (Optional) Start with frontend included
docker compose -f deploy/compose.yml -f deploy/compose.frontend.yml up -dThe API gateway will be available at http://localhost:8000.
The frontend (if enabled) will be at http://localhost:8080.
| Requirement | Notes |
|---|---|
| Docker + Compose v2 | docker compose version should return 2.x+ |
| Bash shell | Git Bash on Windows; native on macOS/Linux |
openssl, base64 |
Required by the secret generator script |
Windows users: Run all
bashcommands from Git Bash, not PowerShell or CMD.
Run your own Supabase-compatible backend while using the hosted frontend.
cp deploy/.env.example deploy/.env
cd deploy && bash scripts/generate-secrets.sh && cd ..
docker compose -f deploy/compose.yml up -dVerify everything is healthy:
docker compose -f deploy/compose.yml psThen open the hosted frontend and use the Config Backend page to enter:
- URL:
http://localhost:8000(or your server's address) - Anon Key: The
ANON_KEYvalue fromdeploy/.env
Run the entire stack — backend and frontend — on your own machine.
cp deploy/.env.example deploy/.env
cd deploy && bash scripts/generate-secrets.sh && cd ..
docker compose -f deploy/compose.yml -f deploy/compose.frontend.yml up -dOpen http://localhost:8080 in your browser.
The frontend container clones the latest simplebudgets/simplebudget source, builds it, and serves it via Caddy. The config.js is auto-generated from your .env values at container startup — no manual configuration needed.
All config lives in deploy/.env. Run generate-secrets.sh to auto-fill secrets.
| Variable | Default | Scope | Description |
|---|---|---|---|
SUPABASE_PUBLIC_URL |
http://localhost:8000 |
Public | Kong API gateway URL (browser-accessible) |
ANON_KEY |
(generated) | Public | Browser-safe JWT for unauthenticated API access |
SERVICE_ROLE_KEY |
(generated) | Private | Elevated JWT — bypasses RLS |
JWT_SECRET |
(generated) | Private | Signs all JWTs |
POSTGRES_PASSWORD |
(generated) | Private | Database password |
DASHBOARD_USERNAME |
admin |
Optional | Studio dashboard username |
DASHBOARD_PASSWORD |
(generated) | Optional | Studio dashboard password |
FRONTEND_PORT |
8080 |
Frontend | Port for the self-hosted frontend |
| Safe for browsers | Never expose |
|---|---|
SUPABASE_PUBLIC_URL |
SERVICE_ROLE_KEY |
ANON_KEY |
JWT_SECRET |
POSTGRES_PASSWORD |
deploy/.envis in.gitignore— never commit it.- The frontend container only receives
SUPABASE_PUBLIC_URLandANON_KEY.
Connect with pgAdmin or any Postgres client:
| Setting | Value |
|---|---|
| Host | localhost |
| Port | 5432 |
| Database | postgres |
| Username | supabase_admin |
| Password | Your POSTGRES_PASSWORD |
git pull origin main
# Backend-only
docker compose -f deploy/compose.yml down
docker compose -f deploy/compose.yml up -d
# Full stack (rebuilds frontend with latest source)
docker compose -f deploy/compose.yml -f deploy/compose.frontend.yml down
docker compose -f deploy/compose.yml -f deploy/compose.frontend.yml up -d --buildMigrations run automatically on every startup.
The simplest way to access your instance from other devices — no port forwarding, no reverse proxy, automatic HTTPS.
tailscale serve 8000 # Expose API gateway
tailscale serve --https 8080 # Expose frontendUpdate SUPABASE_PUBLIC_URL in deploy/.env to your Tailscale URL and restart.
Postgres won't start
docker compose -f deploy/compose.yml logs postgresEnsure POSTGRES_PASSWORD is set. To reset completely:
docker compose -f deploy/compose.yml down -v
docker compose -f deploy/compose.yml up -dMigration errors
docker compose -f deploy/compose.yml logs migrationsTo re-run from scratch (destroys data):
docker compose -f deploy/compose.yml down -v
docker compose -f deploy/compose.yml up -dGoTrue (auth) fails
docker compose -f deploy/compose.yml logs gotrueUsually caused by role passwords not being set. Fix with a full reset:
docker compose -f deploy/compose.yml down -v
docker compose -f deploy/compose.yml up -dCORS errors in browser
Handled by the Kong CORS plugin in deploy/kong.yml. If a header is blocked, add it to the headers list and restart:
docker compose -f deploy/compose.yml restart kongComplete reset
docker compose -f deploy/compose.yml down -v
rm deploy/.env
cp deploy/.env.example deploy/.env
cd deploy && bash scripts/generate-secrets.sh && cd ..
docker compose -f deploy/compose.yml up -d ┌─────────────────────────────────────┐
│ Docker Compose │
│ │
Browser ──────────►│ Kong :8000 (API Gateway) │
│ ├── /rest/v1/* → PostgREST :3000 │
│ └── /auth/v1/* → GoTrue :9999 │
│ │
│ Postgres :5432 │
│ Migrations (runs once at startup) │
│ Frontend :8080 (optional, Caddy) │
└─────────────────────────────────────┘
See LICENSE.