Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .env.self-hosted.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# BetterBase self-hosted example environment

# Required
BETTERBASE_JWT_SECRET=replace-with-32+-char-secret
BETTERBASE_PUBLIC_URL=http://localhost
BETTERBASE_ADMIN_EMAIL=admin@example.com
BETTERBASE_ADMIN_PASSWORD=change-me-strong-password

POSTGRES_USER=betterbase
POSTGRES_PASSWORD=change-me-strong-password
POSTGRES_DB=betterbase

MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=change-me-minio-password

# Server runtime
NODE_ENV=production
CORS_ORIGINS=http://localhost

# Storage wiring used by compose
STORAGE_ENDPOINT=http://minio:9000
STORAGE_ACCESS_KEY=${MINIO_ROOT_USER}
STORAGE_SECRET_KEY=${MINIO_ROOT_PASSWORD}
STORAGE_BUCKET=betterbase

# Inngest (self-hosted)
INNGEST_BASE_URL=http://inngest:8288
INNGEST_LOG_LEVEL=info
INNGEST_SIGNING_KEY=replace-with-random-hex-64
INNGEST_EVENT_KEY=replace-with-random-hex-32

# Optional nginx public port override
# HTTP_PORT=80
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ dist
.env
.env.*
!.env.example
!.env.self-hosted.example

*.log
npm-debug.log
Expand Down
116 changes: 116 additions & 0 deletions BetterBase_Competitive_Plan.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# BetterBase Competitive Plan — Gap-Closing Edition

> Date: 2026-03-29
> Purpose: This is **not** a greenfield strategy. It assumes BetterBase already implements most core platform capabilities and focuses only on remaining gaps to outperform Convex.

---

## 1) Reality check: what is already built

BetterBase already has broad platform scope implemented and documented:

- IaC schema/functions model
- Auth, Realtime, Storage, Serverless Functions
- Full-text + vector search
- RLS, branching, self-hosted deployment path

This plan avoids re-planning those fundamentals and focuses on adoption, trust, and migration leverage.

---

## 2) Working mode (required before each implementation)

Before writing code, capture this mini brief in the issue/PR:

1. **Goal delta** — what improves for users this week.
2. **Existing capability used** — which implemented feature we are building on.
3. **Gap to close** — the smallest missing part.
4. **Proof** — tests/benchmarks/docs updates required.
5. **Rollback** — how to revert safely.

If this brief is missing, implementation is not ready.

---

## 3) What we should *actually* do next to beat Convex

### Priority A — Migration dominance (wedge strategy)

Convex users will only move if migration is low-risk.

**Now build:**
- Compatibility scanner in `bb migrate from-convex`
- Per-function conversion report (converted/manual/blocker)
- Auto-generated TODO checklist for unsupported APIs

**Win condition:** A typical Convex project can estimate migration effort in minutes.

---

### Priority B — Proof over claims

The implementation exists; now we need undeniable credibility.

**Now build:**
- Public benchmark methodology + reproducible scripts
- CI gate that blocks merges on test/lint/typecheck failures
- “Production evidence” docs (backup/restore, incident drill, rollback walkthrough)

**Win condition:** Every major product claim maps to a measurable artifact.

---

### Priority C — Onboarding compression

Feature-rich products lose if time-to-success is slow.

**Now build:**
- `bb init` starter that includes auth + realtime + storage out-of-the-box
- `bb doctor` command for environment health + fix suggestions
- Guided CLI output with concrete next-step commands after each setup action

**Win condition:** New user goes from init to first realtime app flow in under 10 minutes.

---

## 4) 30-day execution board

### Week 1

- Finalize migration compatibility report format
- Add CI rule enforcement and branch protections

### Week 2

- Ship first version of Convex compatibility scanner
- Publish benchmark methodology doc

### Week 3

- Add `bb doctor` checks and actionable fixes
- Add migration case study template

### Week 4

- Publish 2 end-to-end migration examples
- Publish proof matrix mapping claims -> tests/docs/benchmarks

---

## 5) What to stop doing

- Rewriting broad strategy docs from scratch when features already exist
- Shipping claims without proof links
- Merging “works locally” changes without deterministic test coverage

---

## 6) KPI focus (weekly)

- Convex migration starts / completions
- Time-to-first-success (new project)
- Main-branch green rate
- p95 API latency (local and hosted)
- Number of claims backed by reproducible artifacts

If 2 KPIs regress for 2 consecutive weeks, pause roadmap expansion and fix core reliability/adoption blockers.
21 changes: 13 additions & 8 deletions docker-compose.production.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ services:
- betterbase-network

minio:
image: minio/minio:latest
image: minio/minio:RELEASE.2024-11-07T19-31-41Z
container_name: betterbase-minio
restart: unless-stopped
command: server /data --console-address ":9001"
Expand All @@ -48,7 +48,7 @@ services:
- betterbase-network

minio-init:
image: minio/mc:latest
image: minio/mc:RELEASE.2024-11-08T03-47-05Z
container_name: betterbase-minio-init
depends_on:
minio:
Expand All @@ -66,11 +66,16 @@ services:
image: inngest/inngest:v1.17.5
container_name: betterbase-inngest
restart: unless-stopped
command: inngest dev --host 0.0.0.0 --port 8288
command: inngest start --host 0.0.0.0 --port 8288
environment:
INNGEST_LOG_LEVEL: ${INNGEST_LOG_LEVEL:-info}
volumes:
- inngest_data:/data
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://localhost:8288/health || exit 1"]
interval: 10s
timeout: 5s
retries: 5
networks:
- betterbase-network

Expand All @@ -88,18 +93,18 @@ services:
minio-init:
condition: service_completed_successfully
inngest:
condition: service_started
condition: service_healthy
environment:
DATABASE_URL: postgresql://${POSTGRES_USER:-betterbase}:${POSTGRES_PASSWORD:-betterbase}@postgres:5432/${POSTGRES_DB:-betterbase}
AUTH_SECRET: ${AUTH_SECRET:-change-this-in-production}
AUTH_URL: ${AUTH_URL:-http://localhost:3000}
BETTERBASE_JWT_SECRET: ${BETTERBASE_JWT_SECRET:?JWT secret required - set BETTERBASE_JWT_SECRET in .env}
BETTERBASE_PUBLIC_URL: ${BETTERBASE_PUBLIC_URL:-http://localhost:3000}
STORAGE_ENDPOINT: http://minio:9000
STORAGE_ACCESS_KEY: ${STORAGE_ACCESS_KEY:-minioadmin}
STORAGE_SECRET_KEY: ${STORAGE_SECRET_KEY:-minioadmin}
STORAGE_BUCKET: betterbase
PORT: "3001"
NODE_ENV: production
CORS_ORIGIN: ${CORS_ORIGIN:-http://localhost}
CORS_ORIGINS: ${CORS_ORIGINS:-http://localhost}
INNGEST_BASE_URL: http://inngest:8288
INNGEST_SIGNING_KEY: ${INNGEST_SIGNING_KEY:-}
INNGEST_EVENT_KEY: ${INNGEST_EVENT_KEY:-}
Expand Down Expand Up @@ -129,4 +134,4 @@ volumes:

networks:
betterbase-network:
driver: bridge
driver: bridge
13 changes: 9 additions & 4 deletions docker-compose.self-hosted.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,16 @@ services:
image: inngest/inngest:v1.17.5
container_name: betterbase-inngest
restart: unless-stopped
command: inngest dev --host 0.0.0.0 --port 8288
command: inngest start --host 0.0.0.0 --port 8288
environment:
INNGEST_LOG_LEVEL: ${INNGEST_LOG_LEVEL:-info}
volumes:
- inngest_data:/data
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://localhost:8288/health || exit 1"]
interval: 10s
timeout: 5s
retries: 5
networks:
- betterbase-internal

Expand All @@ -97,7 +102,7 @@ services:
minio-init:
condition: service_completed_successfully
inngest:
condition: service_started
condition: service_healthy
environment:
DATABASE_URL: postgresql://${POSTGRES_USER:-betterbase}:${POSTGRES_PASSWORD:-betterbase}@postgres:5432/${POSTGRES_DB:-betterbase}
BETTERBASE_JWT_SECRET: ${BETTERBASE_JWT_SECRET:?JWT secret required - set BETTERBASE_JWT_SECRET in .env}
Expand All @@ -108,7 +113,7 @@ services:
STORAGE_BUCKET: betterbase
PORT: "3001"
NODE_ENV: production
CORS_ORIGIN: ${CORS_ORIGIN:-http://localhost}
CORS_ORIGINS: ${CORS_ORIGINS:-http://localhost}
INNGEST_BASE_URL: http://inngest:8288
INNGEST_SIGNING_KEY: ${INNGEST_SIGNING_KEY:-}
INNGEST_EVENT_KEY: ${INNGEST_EVENT_KEY:-}
Expand Down Expand Up @@ -157,4 +162,4 @@ volumes:

networks:
betterbase-internal:
driver: bridge
driver: bridge
4 changes: 2 additions & 2 deletions docs/docker-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ docker compose -f docker-compose.self-hosted.yml up -d

```bash
# Generate a secure auth secret
AUTH_SECRET=$(openssl rand -base64 32)
BETTERBASE_JWT_SECRET=$(openssl rand -base64 32)

# Generate Inngest keys (optional for development)
INNGEST_SIGNING_KEY=$(openssl rand -hex 32)
Expand Down Expand Up @@ -158,7 +158,7 @@ docker compose up -d --build betterbase-server
| Database | Docker PostgreSQL | Docker or managed |
| Storage | Docker MinIO | Docker, R2, S3, or B2 |
| SSL/TLS | Not needed | Required (use Traefik/Caddy) |
| Inngest | Dev mode | Production mode |
| Inngest | Dev mode (`inngest dev`) | Production mode (`inngest start`) |

## Alternative: External Services

Expand Down
20 changes: 10 additions & 10 deletions docs/guides/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ CMD ["bun", "run", "start"]
docker build -t my-app .
docker run -p 3000:3000 \
-e DATABASE_URL=$DATABASE_URL \
-e AUTH_SECRET=$AUTH_SECRET \
-e BETTERBASE_JWT_SECRET=$BETTERBASE_JWT_SECRET \
my-app
```

Expand Down Expand Up @@ -93,7 +93,7 @@ services:
envVars:
- key: DATABASE_URL
fromDatabase: my-db
- key: AUTH_SECRET
- key: BETTERBASE_JWT_SECRET
generateValue: true
databases:
- name: my-db
Expand Down Expand Up @@ -218,10 +218,10 @@ Key variables:
| Variable | Description |
|----------|-------------|
| `DATABASE_URL` | PostgreSQL connection string |
| `AUTH_SECRET` | Auth secret (min 32 chars) |
| `SERVER_URL` | Public URL of your instance |
| `ADMIN_EMAIL` | Initial admin email |
| `ADMIN_PASSWORD` | Initial admin password |
| `BETTERBASE_JWT_SECRET` | Auth secret (min 32 chars) |
| `BETTERBASE_PUBLIC_URL` | Public URL of your instance |
| `BETTERBASE_ADMIN_EMAIL` | Initial admin email |
| `BETTERBASE_ADMIN_PASSWORD` | Initial admin password |

### CLI Login

Expand All @@ -242,8 +242,8 @@ See [SELF_HOSTED.md](../../SELF_HOSTED.md) for complete documentation.
DATABASE_URL=postgresql://user:password@host:5432/db

# Authentication
AUTH_SECRET=your-secret-key-min-32-chars-long
AUTH_URL=https://your-domain.com
BETTERBASE_JWT_SECRET=your-secret-key-min-32-chars-long
BETTERBASE_PUBLIC_URL=https://your-domain.com

# Storage (if using S3)
STORAGE_PROVIDER=s3
Expand All @@ -253,13 +253,13 @@ AWS_ACCESS_KEY_KEY=your-key
AWS_SECRET_ACCESS_KEY=your-secret

# CORS
CORS_ORIGIN=https://your-frontend.com
CORS_ORIGINS=https://your-frontend.com
```

### Security Checklist

- [ ] Use HTTPS in production
- [ ] Set strong `AUTH_SECRET`
- [ ] Set strong `BETTERBASE_JWT_SECRET`
- [ ] Configure CORS origins
- [ ] Enable RLS
- [ ] Set up monitoring
Expand Down
12 changes: 6 additions & 6 deletions docs/guides/production-checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ A comprehensive checklist for deploying BetterBase applications to production.
### Environment Variables

- [ ] `DATABASE_URL` set
- [ ] `AUTH_SECRET` set (minimum 32 characters)
- [ ] `AUTH_URL` set to production URL
- [ ] `BETTERBASE_JWT_SECRET` set (minimum 32 characters)
- [ ] `BETTERBASE_PUBLIC_URL` set to production URL
- [ ] `NODE_ENV` set to `production`
- [ ] CORS origins configured

Expand All @@ -70,7 +70,7 @@ A comprehensive checklist for deploying BetterBase applications to production.

### Authentication

- [ ] Strong AUTH_SECRET generated
- [ ] Strong BETTERBASE_JWT_SECRET generated
- [ ] Session expiry configured
- [ ] MFA available for admin accounts

Expand Down Expand Up @@ -206,12 +206,12 @@ bb rls list
```bash
# Required
DATABASE_URL=postgresql://...
AUTH_SECRET=your-32-char-secret-min
AUTH_URL=https://...
BETTERBASE_JWT_SECRET=your-32-char-secret-min
BETTERBASE_PUBLIC_URL=https://...

# Optional
NODE_ENV=production
CORS_ORIGIN=https://your-domain.com
CORS_ORIGINS=https://your-domain.com
STORAGE_PROVIDER=s3
```

Expand Down
Loading
Loading