Local Development
Complete step-by-step guide to running the Nebutra-Sailor monorepo on your local machine — from installing Node.js through seeding the database.
Prerequisites
Make sure the following are installed before you begin:
- Node.js 22+ — nodejs.org or use nvm
- pnpm 10.32+ —
npm install -g pnpm - Docker Desktop 24+ — docker.com/products/docker-desktop
- Git 2.40+ — git-scm.com
Step-by-step setup
# With nvm (recommended)
nvm install 22
nvm use 22
# Verify
node --version # v22.x.xnpm install -g pnpm@latest
# Verify
pnpm --version # 10.32.x or highergit clone https://github.com/nebutra/nebutra-sailor.git
cd nebutra-sailorpnpm installThis installs all workspace dependencies across apps and packages. It may take 2–3 minutes on first run.
pnpm infra:upThis starts three containers via docker-compose.infra.yml:
- PostgreSQL 16 on port
5432 - Redis 7 on port
6379 - ClickHouse 24 on port
8123
If you only need the database (no Redis or ClickHouse), run pnpm infra:lite instead.
Copy the example files for each app you plan to run:
cp apps/web/.env.example apps/web/.env.local
cp backends/gateway/.env.example backends/gateway/.env.local
cp apps/landing/.env.example apps/landing/.env.localThen open each .env.local and fill in your secrets. See the Environment variables section below for a full reference.
pnpm db:generateThis runs prisma generate using the schema at packages/platform/db/prisma/schema.prisma.
pnpm db:migrateThis applies all pending Prisma migrations to your local PostgreSQL instance.
pnpm db:seedSeeds the database with a test organization, users, and sample data so you can log in immediately.
pnpm devStarts all apps in parallel using Turborepo.
pnpm dev:dashboardStarts apps/web (port 3000) and backends/gateway (port 3001).
pnpm dev:marketingStarts apps/landing (port 3002) and apps/studio (port 3333).
All apps support Hot Module Replacement (HMR). Changes to source files apply instantly without a full page reload.
Port map
| Service | URL | Notes |
|---|---|---|
| SaaS dashboard | http://localhost:3000 | Requires Clerk auth |
| API gateway | http://localhost:3001 | REST API + OpenAPI docs at /doc |
| Landing page | http://localhost:3002 | 7 locales, default is /en |
| Design docs | http://localhost:3004 | Internal only |
| Storybook | http://localhost:6006 | Component library |
| Sanity Studio | http://localhost:3333 | Content management |
| PostgreSQL | localhost:5432 | Database |
| Redis | localhost:6379 | Cache and queue |
| ClickHouse | localhost:8123 | Usage metering |
Environment variables
backends/gateway
| Variable | Required | Description |
|---|---|---|
DATABASE_URL | Yes | PostgreSQL connection string, e.g. postgresql://postgres:postgres@localhost:5432/nebutra |
REDIS_URL | Yes | Redis connection string, e.g. redis://localhost:6379 |
AUTH_PROVIDER | No | Auth provider: better-auth, nextauth, clerk, supabase, or dev |
NEXT_PUBLIC_AUTH_PROVIDER | No | Client-visible auth provider; keep aligned with AUTH_PROVIDER |
CLERK_SECRET_KEY | If using Clerk | Clerk backend API key — from the Clerk dashboard |
CLERK_PUBLISHABLE_KEY | If using Clerk | Clerk publishable key |
STRIPE_SECRET_KEY | Yes | Stripe secret key |
STRIPE_WEBHOOK_SECRET | Yes | Stripe webhook signing secret |
CLERK_WEBHOOK_SECRET | If using Clerk webhooks | Clerk webhook signing secret |
CLICKHOUSE_URL | Yes | ClickHouse HTTP interface URL |
QUEUE_PROVIDER | No | qstash, bullmq, or memory (auto-detected) |
PERMISSIONS_PROVIDER | No | casl (default) or openfga |
apps/web
| Variable | Required | Description |
|---|---|---|
AUTH_PROVIDER | No | Auth provider selected for server routes |
NEXT_PUBLIC_AUTH_PROVIDER | No | Auth provider selected for client code and landing One Tap |
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY | If using Clerk | Clerk publishable key |
CLERK_SECRET_KEY | If using Clerk | Clerk backend API key |
BETTER_AUTH_SECRET | If using Better Auth | Self-hosted Better Auth signing secret |
AUTH_SECRET | If using NextAuth | Auth.js / NextAuth signing secret |
GOOGLE_CLIENT_ID | If using Google OAuth | Google OAuth web client id |
GOOGLE_CLIENT_SECRET | If using Google OAuth | Google OAuth web client secret |
NEXT_PUBLIC_API_URL | Yes | Base URL of the API gateway, e.g. http://localhost:3001 |
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY | Yes | Stripe publishable key for client-side billing |
DATABASE_URL | Yes | PostgreSQL connection string (for Server Actions) |
apps/landing
| Variable | Required | Description |
|---|---|---|
NEXT_PUBLIC_SANITY_PROJECT_ID | Yes | Sanity project ID |
NEXT_PUBLIC_SANITY_DATASET | Yes | Sanity dataset name, e.g. production |
NEXT_PUBLIC_AUTH_PROVIDER | No | Auth provider used to choose landing One Tap behavior |
NEXT_PUBLIC_GOOGLE_CLIENT_ID | If Better Auth or NextAuth One Tap is enabled | Public Google OAuth web client id |
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY | If Clerk One Tap is enabled | Clerk publishable key |
SANITY_API_TOKEN | No | Sanity read token (required for draft previews) |
All environment variables are validated by @nebutra/config at startup. If a required variable is missing the process will crash immediately with a descriptive error message — there are no silent failures.
Common first-run issues
"Cannot find module '@prisma/client'"
You need to generate the Prisma client first:
pnpm db:generate"Error: connect ECONNREFUSED 127.0.0.1:5432"
PostgreSQL is not running. Start the infrastructure containers:
pnpm infra:up"Error: connect ECONNREFUSED 127.0.0.1:6379"
Redis is not running. Use pnpm infra:up (not pnpm infra:lite, which skips Redis).
Port already in use
Another process is using the port. Find and kill it:
lsof -ti:3000 | xargs kill # free port 3000
lsof -ti:3001 | xargs kill # free port 3001pnpm version mismatch
The repo requires pnpm 10.32+. Update:
npm install -g pnpm@latestRunning individual commands
pnpm typecheck # TypeScript check across all packages
pnpm lint # Biome lint
pnpm lint:fix # Biome lint with auto-fix
pnpm test # Vitest unit tests
pnpm test:coverage # Unit tests with coverage report
pnpm test:arch # Architecture boundary tests
pnpm e2e # Playwright E2E (headless)
pnpm e2e:ui # Playwright E2E with interactive UI
pnpm build # Production build (all apps)Related
How is this guide?
Last updated on