Overview
Budget Bee uses Docker Compose to orchestrate multiple services including PostgreSQL, PostgREST, and Adminer. This is the recommended approach for both local development and small production deployments.
Docker Compose Structure
The infrastructure is split into modular compose files:
infra/
├── docker-compose.yml # Main compose file (includes all services)
├── bu-postgres.yml # PostgreSQL database
├── bu-postgrest.yml # PostgREST API server
└── bu-adminer.yml # Adminer database UI
PostgreSQL Service
The PostgreSQL service is configured in infra/bu-postgres.yml:
services :
bu-postgres :
image : postgres:17.5-alpine3.22
container_name : bu-postgres
restart : unless-stopped
networks :
- bu-net
volumes :
- bu-postgres-data:/var/lib/postgresql/data
env_file :
- path : .env
required : true
ports :
- 5100:5432
environment :
POSTGRES_DB : budgetbee
POSTGRES_USER : ${POSTGRES_USER}
POSTGRES_PASSWORD : ${POSTGRES_PASSWORD}
The database uses a persistent volume bu-postgres-data to ensure data survives container restarts.
PostgREST Service
PostgREST automatically generates a REST API from your PostgreSQL schema:
services :
bu-postgrest :
image : postgrest/postgrest:v13.0.4
container_name : bu-postgrest
restart : unless-stopped
networks :
- bu-net
ports :
- 5101:3000
environment :
PGRST_DB_URI : postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@bu-postgres:5432/budgetbee
PGRST_DB_SCHEMA : public
PGRST_DB_POOL : 10
PGRST_JWT_SECRET : ${PGRST_JWT_SECRET}
PGRST_JWT_AUD : ${NEXT_PUBLIC_APP_URL}
PGRST_DB_ANON_ROLE : anon
PGRST_DB_AUTHENTICATED_ROLE : authenticated
depends_on :
- bu-postgres
PGRST_JWT_SECRET must be obtained from the web app’s JWKS endpoint after initial setup. See JWT Configuration below.
Adminer Service
Adminer provides a web-based database administration interface:
services :
bu-adminer :
image : adminer
container_name : bu-adminer
restart : unless-stopped
ports :
- 5102:8080
environment :
ADMINER_DEFAULT_SERVER : bu-postgres
ADMINER_DESIGN : pepa-linha-dark
networks :
- bu-net
Access Adminer at http://localhost:5102 to manage your database visually.
Network Configuration
All services communicate through a custom bridge network:
networks :
bu-net :
name : bu-net
driver : bridge
volumes :
bu-postgres-data :
name : bu-postgres-data
Environment Variables
Create a .env file in the root directory with the following variables:
# Application URLs
NEXT_PUBLIC_SITE_URL = http://localhost:3001
NEXT_PUBLIC_APP_URL = http://localhost:3000
NEXT_PUBLIC_CURRENCY_API_URL = http://localhost:8787
NEXT_PUBLIC_PG_REST_URL = http://localhost:5101
# Database Configuration
POSTGRES_DATABASE = budgetbee
POSTGRES_USER = root
POSTGRES_HOST = localhost
POSTGRES_PORT = 5100
POSTGRES_PASSWORD = your_secure_password
# Database Admin Users
POSTGRES_AUTH_ADMIN_USER = auth_admin
POSTGRES_AUTH_ADMIN_PASSWORD = auth_admin_password
POSTGRES_SUBSCRIPTION_ADMIN_USER = subscription_admin
POSTGRES_SUBSCRIPTION_ADMIN_PASSWORD = subscription_admin_password
# JWT Configuration (obtain after first run)
PGRST_JWT_SECRET =
# Better Auth
BETTER_AUTH_SECRET = your_random_secret_here
# Email (Optional)
RESEND_API_KEY =
SMTP_SENDER_NAME = Budget Bee
SMTP_MAIL = [email protected]
Use openssl rand -base64 32 to generate secure random secrets for BETTER_AUTH_SECRET and passwords.
Setup Steps
Clone the Repository
git clone https://github.com/sammaji/budgetbee
cd budgetbee
Create Environment Files
chmod +x scripts/ *
./scripts/post_install.sh
This creates .env at the root and symlinks it to all packages.
Start Docker Services
make docker-up
# Or manually:
cd infra && docker compose up -d
Create Database Roles
make create-roles
# Or manually:
./scripts/create_roles.sh
Run Database Migrations
make migrate
# Or manually:
./scripts/run_migrations.sh
Start the Application
make dev
# Or manually:
pnpm turbo dev
Configure JWT Secret
After the web app starts, visit http://localhost:3000/api/auth/jwks and copy the JWKS secret. Add it to your .env file: PGRST_JWT_SECRET =< jwks_secret_from_endpoint >
Then restart the PostgREST container: cd infra && docker compose restart bu-postgrest
Makefile Commands
Budget Bee includes a Makefile with convenient commands:
Setup Commands
make install # Install dependencies with pnpm
make setup-env # Create .env and symlink to packages
make setup # Full setup (install + env + db + jwks)
Database Commands
make docker-up # Start PostgreSQL and PostgREST
make docker-down # Stop all containers
make create-roles # Create PostgreSQL roles
make migrate # Run all migrations
make db-setup # Full database setup
Development Commands
make dev # Start all apps (docs, site, web)
make dummy-data # Push test data to database
make backfill-jwks # Fetch JWKS and update .env
Utility Commands
make clean # Remove node_modules and build artifacts
JWT Configuration
The PostgREST service requires a JWKS (JSON Web Key Set) secret to validate JWT tokens from Better Auth.
Start the Web App
The web app must be running to generate the JWKS endpoint:
Fetch the JWKS Secret
Visit the JWKS endpoint or use curl: curl http://localhost:3000/api/auth/jwks
Update Environment
Copy the secret to your .env file: PGRST_JWT_SECRET =< the_jwks_secret >
Restart PostgREST
cd infra && docker compose restart bu-postgrest
You can automate this process using:
Verifying the Installation
Check Container Status
You should see bu-postgres, bu-postgrest, and bu-adminer running.
Test PostgreSQL Connection
docker exec bu-postgres pg_isready -U root
Test PostgREST API
curl http://localhost:5101/
You should receive a JSON response with available endpoints.
Access the Web App
Open http://localhost:3000 in your browser.
Managing Docker Services
View Logs
# All services
cd infra && docker compose logs -f
# Specific service
docker logs -f bu-postgres
docker logs -f bu-postgrest
Restart Services
# All services
cd infra && docker compose restart
# Specific service
docker restart bu-postgres
Stop Services
make docker-down
# Or:
cd infra && docker compose down
Remove All Data (Reset)
This will delete all database data permanently!
cd infra && docker compose down -v
Production Considerations
Use Strong Passwords Generate cryptographically secure passwords for all database users
Enable SSL/TLS Configure PostgreSQL to use SSL connections
Regular Backups Set up automated database backups
Resource Limits Configure memory and CPU limits for containers
Production Docker Compose
For production, modify the compose file to:
services :
bu-postgres :
# ... existing config ...
deploy :
resources :
limits :
cpus : '2'
memory : 4G
reservations :
cpus : '1'
memory : 2G
Troubleshooting
PostgreSQL Won’t Start
# Check logs
docker logs bu-postgres
# Verify port is available
lsof -i :5100
PostgREST Authentication Errors
Ensure PGRST_JWT_SECRET is correctly set:
# In your .env file
echo $PGRST_JWT_SECRET
# Restart PostgREST
docker restart bu-postgrest
Connection Refused Errors
Wait for PostgreSQL to fully start:
# The db-setup command includes a wait mechanism
make db-setup
Next Steps
Database Migrations Learn about the migration system
PostgreSQL Config Advanced PostgreSQL configuration
PostgREST Setup Configure the REST API