Local setup
Getting started tracks
Product teams looking to build on Open Saasframe should start with the standalone app — it gives you a clean project without cloning the full monorepo. Core contributors should follow the develop branch track instead.
If you want to build a production app without cloning the monorepo, use create-saasframe-app instead.
If you are on Windows, prefer the Windows native local development flow below: Docker Desktop for infrastructure services, then run the app natively with Node.js and Yarn. The full Docker development setup remains available as a container-only option, but on Windows it is usually much slower for this monorepo because bind-mounted file watching and filesystem I/O cross the Windows/WSL boundary.
Standalone app (recommended for product teams)
Scaffold a standalone project with a single command — no need to clone the monorepo:
npx create-saasframe-app my-app
cd my-app
Then follow the post-install steps in the full standalone app guide.
If you are working on the Open Saasframe monorepo and need to validate scaffold changes before publishing:
yarn test:create-app
yarn test:create-app:integration
See the standalone app guide for what each command does.
Develop branch (recommended)
git clone https://github.com/saasframe/saasframe.git
cd saasframe
git checkout develop
Continue with the develop setup steps below.
Docker-based setup (all platforms)
Use this track if you want to run the entire stack inside Docker with hot reload — no local Node.js or Yarn required. This works on macOS/Linux and remains available on Windows as a container-only option, but Windows contributors should usually prefer the native local workflow above because it is faster and more reliable for this monorepo.
See the full Docker Development Setup section below for step-by-step instructions.
Develop setup steps (recommended)
Follow these steps after the prerequisites are in place:
-
Use the develop branch
cd saasframegit checkout develop -
Start Docker services
docker compose up -dThis starts PostgreSQL 15 with pgvector and Redis 7. The pgvector extension is automatically installed, enabling vector search features.
-
Install workspace dependencies
yarn install -
Copy the environment template
cp apps/saasframe/.env.example apps/saasframe/.envMake sure these required variables are set in
apps/saasframe/.envbefore continuing:DATABASE_URL=postgres://postgres:postgres@localhost:5432/saasframeJWT_SECRET=change-me-dev-secretREDIS_URL=redis://localhost:6379If you prefer a separate events Redis, set
EVENTS_REDIS_URLinstead ofREDIS_URL. -
Build packages and generate registries
yarn build:packagesyarn generateyarn build:packagesRun
yarn build:packagesagain afteryarn generateon a fresh local setup. This second build makes sure newly generated scripts are compiled beforeyarn initializeruns; otherwiseyarn initializemay not detect them and can fail during bootstrap. -
Bootstrap data
yarn initializeThis script prepares module registries, generates/applies migrations, seeds default roles, provisions an admin user, and loads demo CRM data (companies, people, deals, activities, todos). Add
--no-examplesif you prefer to skip the demo content while keeping core identities,--stresstest(optionally with-n <count>) to preload thousands of synthetic contacts, companies, deals, activities, and notes, or combine--stresstest --litefor high-volume contacts without the heavier extras when you need raw throughput. -
Launch the app
yarn devyarn devstarts the compact development runtime. On native local runs it serves a startup splash screen with live progress onhttp://localhost:4000by default, auto-opens that page when possible, and prints the backend URL in the terminal. Once the runtime is ready, continue tohttp://localhost:3000/backendand sign in with the credentials printed byyarn initialize.To run multiple persistent local instances against the same PostgreSQL server (e.g. one per client repo), pass an optional
--database-name[=<name>]flag. Without the flag, behavior is unchanged.# explicit name; .env update is offered with default-yesyarn dev:greenfield --database-name=client_a# bare flag derives the database name from the current directoryyarn dev --database-name# one-off run that does not edit .envyarn dev --database-name=client_a --no-update-envThe override only rewrites the database segment of
DATABASE_URL; credentials, host, port, and query parameters are preserved. CI/non-interactive runs default to updating.env— pass--no-update-envto opt out.
Windows native local development
This is the recommended Windows setup for day-to-day work on the monorepo. Docker Desktop runs the infrastructure services, while Node.js and Yarn run directly on Windows. The full docker-compose.fullapp.dev.yml stack remains available for isolated or fully containerized workflows, but on Windows it is usually much slower because a large Node.js monorepo with bind-mounted source files does heavy watched file reads across the Windows/Linux filesystem boundary.
One-time manual setup
For a quick one-time prerequisite pass after cloning the repository or unpacking the source archive, open PowerShell as Administrator and run:
.\scripts\setup-windows-dev.ps1
If Windows shows a security warning because the script came from a downloaded ZIP/archive, unblock it first:
Unblock-File .\scripts\setup-windows-dev.ps1
The helper script:
- verifies administrator access before continuing
- verifies WSL 2 support and sets the default WSL version to
2 - verifies Node.js
24.x - verifies Yarn
4.12.0via Corepack - verifies Git and repairs the current-session
PATHif Git is installed but not yet visible - verifies Visual Studio 2022 Build Tools with the C++ workload
- verifies Microsoft Visual C++ Redistributable 2015+ x64
- optionally adds a Microsoft Defender exclusion for the target repo directory
- writes a transcript log under
%TEMP%\saasframe-setup\
The helper does not install or start Docker Desktop, clone the repository, or run monorepo bootstrap commands such as yarn install or yarn initialize.
If you prefer to run the prerequisite commands manually instead, use:
corepack enable
corepack prepare yarn@stable --activate
winget install Microsoft.VisualStudio.2022.BuildTools
winget install Microsoft.VCRedist.2015+.x64
Prerequisites
- Node.js 24+ - required by the monorepo runtime.
- Yarn via Corepack:
corepack enablecorepack prepare yarn@stable --activate
- Visual Studio 2022 Build Tools - required on clean Windows environments for native Node.js dependencies.
- Microsoft Visual C++ Redistributable 2015+ x64 - required for native binaries used by the toolchain.
- Docker Desktop with WSL 2 backend - for PostgreSQL, Redis, and Meilisearch.
If you install Build Tools through the UI, make sure the C++ build tools workload is included. Git, Node.js 24+, Yarn/Corepack, and Docker Desktop must be installed and configured separately before continuing with the monorepo setup.
Monorepo flow
Start only infrastructure services from the repository root:
docker compose up -d
The root docker-compose.yml starts the local service stack, including PostgreSQL, Redis, and Meilisearch. It does not run the application container.
Microsoft Defender exclusion is optional, but strongly recommended on Windows because without it repository operations and local development can be noticeably slower. Run it manually in PowerShell if you want the recommended setup:
Start-Process powershell -Verb RunAs -ArgumentList "-NoProfile -ExecutionPolicy Bypass -Command `"Add-MpPreference -ExclusionPath '$((Get-Location).Path)'`""
Continue with the normal monorepo setup:
yarn install
yarn build:packages
yarn generate
yarn build:packages
yarn initialize
yarn dev
yarn build:packages is a monorepo-only step that compiles workspace packages to dist/. It does not exist in standalone apps. On a fresh local setup, run it both before and after yarn generate so yarn initialize can see the generated scripts.
For an existing database where you only need to apply new migrations:
yarn db:migrate
yarn generate
yarn dev
Native dev runtime splash screen
When you run yarn dev on the host, Open Saasframe starts a compact development runtime with a dedicated splash page that shows startup progress while packages, generators, and the app server warm up.
- Default splash URL:
http://localhost:4000 - Default backend URL:
http://localhost:3000/backend - Browser auto-open happens on interactive local runs when supported by the OS
- The terminal still prints both URLs, so you can open them manually if needed
- Press
dwhileyarn devis running to toggle raw logs - Standalone apps can show a
Start coding with AImenu for detected coding tools - Standalone apps can show a GitHub publish panel that creates or publishes the local project through
gh
For the standalone splash features, install these recommended tools up front:
- GitHub CLI (
gh) for the GitHub publish panel: cli.github.com - Codex CLI for the OpenAI terminal workflow: developers.openai.com/codex/cli
- Claude Code for the Anthropic terminal workflow: code.claude.com/docs/en/setup
- Visual Studio Code as the recommended general-purpose editor: code.visualstudio.com/Download
- Cursor as the recommended AI-first editor: cursor.com/download
To override the splash port for native local runs:
SF_DEV_SPLASH_PORT=4100 yarn dev
To use a random free splash port instead of the stable default:
SF_DEV_SPLASH_PORT=random yarn dev
To keep the splash from opening automatically:
SF_DEV_AUTO_OPEN=0 yarn dev
To hide the standalone GitHub publish panel from the splash:
SF_DEV_CREATE_GIT_REPO_FLOW=false yarn dev
To hide the coding-tools menu from the splash:
SF_ENABLE_CODING_FLOW_FROM_SPLASH=false yarn dev
In-process watcher and workers (memory optimization)
To keep idle memory low, yarn dev now runs two things in-process inside the saasframe server dev runtime instead of as separate long-running Node processes:
- Structural regeneration watcher — the watcher that re-runs
saasframe generatewhen module files change is hosted by the dev server itself. Collapsing this dedicated sidecar saves ~190 MB of resident memory. - Queue workers — background queue workers are auto-spawned inside the dev process so jobs (indexing, bulk operations, notifications) are processed without a second runtime.
This is the right default for most local development. If you need higher throughput — for example a heavy import/reindex, or to profile worker behavior in isolation — opt back into separate parallel processes with these flags.
Run the generate watcher as a standalone sidecar process again:
SF_DEV_GENERATE_WATCH_MODE=legacy yarn dev
Stop the dev runtime from hosting workers, then run dedicated worker processes alongside it (each process runs its own event loop, so several in parallel scale throughput):
# In the dev runtime: do not auto-spawn in-process workers
AUTO_SPAWN_WORKERS=false yarn dev
# In separate terminals: dedicated worker processes, tuned per queue
yarn saasframe <module> worker <queue-name> --concurrency=5
Tune --concurrency per the queue guidelines (I/O-bound 5–10, CPU-bound 1–2, DB-heavy 3–5; never exceed 20). For production-grade parallelism across machines, set QUEUE_STRATEGY=async to use the Redis-backed BullMQ strategy.
To poll for jobs lazily instead of holding eager in-process workers (lower idle cost, slightly higher pickup latency):
SF_AUTO_SPAWN_WORKERS_LAZY=true yarn dev
# optional: tune the poll interval (ms, default 1000)
SF_AUTO_SPAWN_WORKERS_LAZY_POLL_MS=500 yarn dev
Docker Management
Stop services:
docker compose down
View logs:
docker compose logs -f
Complete reset (deletes all data):
docker compose down -v
docker compose up -d
yarn saasframe init
Verify pgvector installation:
docker exec saasframe-postgres psql -U postgres -d saasframe -c "SELECT extname, extversion FROM pg_extension WHERE extname = 'vector';"
Docker Development Setup
Run the entire Open Saasframe stack inside Docker with hot reload. Source code is mounted from the host so every file change is picked up automatically — no local Node.js, Yarn, or native build tools required. This is a convenient option on any OS, but on Windows it is usually slower than the native local workflow because of bind-mounted monorepo file watching.
Prerequisites
- Docker Desktop — Download for Windows, macOS, or Linux
- Docker Compose v2+ (bundled with Docker Desktop)
- Git — Download for Windows (includes Git Bash)
- At least 4 GB RAM allocated to Docker (check Docker Desktop → Settings → Resources)
- Use Git Bash, PowerShell, or Windows Terminal for running commands.
- When cloning the repo, make sure Git preserves line endings for shell scripts:
git config --global core.autocrlf input
- In Docker Desktop, ensure WSL 2 backend is enabled (Settings → General → "Use the WSL 2 based engine"). This is required for volume mounts and file watching to work correctly.
Quick Start
# Clone the repository
git clone https://github.com/saasframe/saasframe.git
cd saasframe
git checkout develop
# (Optional) Copy and customize environment
cp apps/saasframe/.env.example apps/saasframe/.env
# Build and start the full dev stack
docker compose -f docker-compose.fullapp.dev.yml up --build
The first run takes several minutes — Docker builds the image, installs dependencies, builds packages, runs migrations, and seeds demo data. Subsequent starts are much faster because initialization is cached in a named volume.
The app container uses the same compact yarn dev runtime as native local development, including the splash screen with live startup progress. In Docker, the container cannot open a browser on your host automatically, so use the URLs printed in the logs instead:
- Splash URL:
http://localhost:4000 - Backend URL:
http://localhost:3000/backend
Once the runtime is ready, open the backend URL and sign in with the default credentials printed during initialization (typically admin@example.com / password).
How It Works
The docker-compose.fullapp.dev.yml file orchestrates five services:
| Service | Image | Purpose |
|---|---|---|
| app | Built from Dockerfile (dev stage) | Next.js app with hot reload |
| postgres | pgvector/pgvector:pg17-trixie | PostgreSQL 17 with pgvector |
| redis | redis:7-alpine | Caching and event persistence |
| meilisearch | getmeili/meilisearch:v1.11 | Full-text search |
| opencode | Custom | Claude Code integration (optional) |
The app container:
- Mounts your source code from the host into
/app - Uses named volumes for
node_modules,.next, and packagedist/directories so the container manages its own builds - Enables file-watching via polling (
CHOKIDAR_USEPOLLING,WATCHPACK_POLLING) for reliable change detection on all platforms - Exposes a dedicated dev splash port so startup progress is available from the host even though browser auto-open is disabled in containerized runs
- On first run, executes
yarn saasframe init(migrations + seeding); on subsequent runs, applies pending migrations only
Common Operations
Start in detached mode (background):
docker compose -f docker-compose.fullapp.dev.yml up -d
View logs:
docker compose -f docker-compose.fullapp.dev.yml logs -f # all services
docker compose -f docker-compose.fullapp.dev.yml logs -f app # app only
Rebuild after pulling new changes:
docker compose -f docker-compose.fullapp.dev.yml up --build
Stop all services:
docker compose -f docker-compose.fullapp.dev.yml down
Full reset (deletes all data and cached builds):
docker compose -f docker-compose.fullapp.dev.yml down -v
docker compose -f docker-compose.fullapp.dev.yml up --build
Docker Wrapper Commands
The repository also exposes root-level yarn docker:* commands that run the matching workflow inside the running app container. These wrappers exist so container-first contributors can use the same command surface without translating everything to docker compose exec ... manually.
The wrappers are implemented by scripts/docker-exec.mjs. The helper:
- auto-detects the active compose profile
- prefers
docker-compose.fullapp.dev.yml, then falls back todocker-compose.fullapp.yml - lets you force a target compose file with
DOCKER_COMPOSE_FILE=... - prints explicit guidance when no
appcontainer is running
Dev stack wrappers
Start the dev stack first:
yarn docker:dev:up
Then run monorepo workflows from the host:
yarn docker:build:packages
yarn docker:generate
yarn docker:initialize
yarn docker:initialize -- --reinstall
yarn docker:reinstall
yarn docker:db:generate
yarn docker:db:migrate
yarn docker:lint
yarn docker:typecheck
yarn docker:test
yarn docker:install-skills
Use yarn docker:dev when you want to restart the app service and immediately tail logs:
yarn docker:dev
For a faster restart that skips the install/build/generate phase handled by the dev entrypoint, pass the wrapper flag through to docker-exec:
yarn docker:dev -- --skip-rebuilt
This flow is the documented replacement for manually running:
docker compose -f docker-compose.fullapp.dev.yml restart app
docker compose -f docker-compose.fullapp.dev.yml logs -f app
Fullapp stack wrappers
The production-like fullapp profile is runtime-focused. It supports operational commands, but not monorepo development workflows such as generate, build:packages, lint, typecheck, test, or install-skills.
Start the fullapp stack:
yarn docker:up
Supported runtime-oriented examples:
yarn docker:db:migrate
yarn docker:saasframe auth:list-users
If you run a dev-only wrapper against the fullapp stack, the helper fails closed and tells you to switch back to the dev profile:
DOCKER_COMPOSE_FILE=docker-compose.fullapp.dev.yml yarn docker:generate
Forcing a compose file
When both stacks exist, or when you want to target a specific profile regardless of auto-detection, set DOCKER_COMPOSE_FILE explicitly:
DOCKER_COMPOSE_FILE=docker-compose.fullapp.dev.yml yarn docker:generate
DOCKER_COMPOSE_FILE=docker-compose.fullapp.yml yarn docker:db:migrate
Wrapper troubleshooting
- If you see
Error: No running Open Saasframe app container found., start eitheryarn docker:dev:uporyarn docker:upfirst. - If you see
DOCKER_COMPOSE_FILE="..." does not exist., fix the path and re-run the command. - If a command is reported as unsupported in the production-like Docker profile, use the dev stack for that workflow.
Environment Variables
All environment variables are pre-configured with sensible defaults inside the compose file. To customize, edit apps/saasframe/.env before starting — the compose file reads from it automatically.
Key variables you may want to override:
| Variable | Default | Description |
|---|---|---|
APP_PORT | 3000 | Host port for the app |
SF_DEV_SPLASH_PORT | 4000 | Host and container port for the dev splash progress page |
SF_DEV_AUTO_OPEN | 1 | Set to 0 to disable browser auto-open for the splash on supported local runs |
SF_DEV_CREATE_GIT_REPO_FLOW | true | Set to false to hide the standalone splash GitHub publish panel |
SF_ENABLE_CODING_FLOW_FROM_SPLASH | true | Set to false to hide the splash coding-tools menu |
SF_DEV_SPLASH_VSCODE_PATH | auto-detect | Optional path override for the VS Code CLI used by the splash coding menu |
SF_DEV_SPLASH_CURSOR_PATH | auto-detect | Optional path override for the Cursor CLI used by the splash coding menu |
SF_DEV_SPLASH_CLAUDE_CODE_PATH | auto-detect | Optional path override for the Claude Code CLI used by the splash coding menu |
SF_DEV_SPLASH_CODEX_PATH | auto-detect | Optional path override for the Codex CLI used by the splash coding menu |
POSTGRES_USER | postgres | Database username |
POSTGRES_PASSWORD | postgres | Database password |
JWT_SECRET | JWT | Auth token secret |
OPENAI_API_KEY | — | Enables OpenAI-backed AI features; add it with SF_DISABLE_VECTOR_SEARCH_AUTOINDEXING=false only when you want vector auto-indexing on |
SF_DISABLE_VECTOR_SEARCH_AUTOINDEXING | true in the shipped example env | Set to false or remove it to enable automatic vector indexing |
DEMO_MODE | true | Seeds demo CRM data on first run |
If you need a different splash port in Docker, set it before startup so the host/container mapping stays aligned:
SF_DEV_SPLASH_PORT=4100 docker compose -f docker-compose.fullapp.dev.yml up --build
Troubleshooting
Container fails to start on Windows:
- Ensure WSL 2 backend is enabled in Docker Desktop
- Check that the repository was cloned with
core.autocrlf=inputto avoid CRLF issues in shell scripts - Verify Docker Desktop has enough memory allocated (4 GB minimum)
File changes not detected:
- The compose file sets
CHOKIDAR_USEPOLLING=trueandWATCHPACK_POLLING=trueby default. If changes are still not picked up, restart the app container:docker compose -f docker-compose.fullapp.dev.yml restart app
Port conflicts:
- If port 3000 is already in use, override it:
APP_PORT=3001 docker compose -f docker-compose.fullapp.dev.yml up - If port 4000 is already in use, override the splash port too:
SF_DEV_SPLASH_PORT=4100 docker compose -f docker-compose.fullapp.dev.yml up - If Postgres auth/connect errors appear during local commands (
yarn generate,yarn db:generate) andlocalhost:5432is occupied by another local PostgreSQL instance, start Docker Postgres on another port and use the same port inDATABASE_URL:POSTGRES_PORT=55432 docker compose up -d postgresDATABASE_URL=postgresql://postgres:postgres@localhost:55432/saasframe
Slow file watching on Windows/WSL 2:
- Store the repository inside the WSL 2 filesystem (
\\wsl$\Ubuntu\home\...) rather than on the Windows filesystem (/mnt/c/...) for significantly better I/O performance.
Docker Deployment (Full Stack)
Run the complete Open Saasframe stack with Docker Compose, including the application, PostgreSQL, Redis, and Meilisearch. This approach is ideal for quick demos, testing, or containerized deployments.
Prerequisites
- Docker 24+ and Docker Compose v2+
- At least 4GB RAM available for Docker
- Configured
.envfile (see Environment Variables below)
Quick Start
# Clone the repository
git clone https://github.com/saasframe/saasframe.git
cd saasframe
# Copy environment template
cp apps/saasframe/.env.example apps/saasframe/.env
# Edit apps/saasframe/.env with your configuration (see next section)
# Build and start all services
docker compose -f docker-compose.fullapp.yml up --build
The application will be available at http://localhost:3000/backend. Sign in with the default admin credentials printed during initialization (typically admin@example.com).
Environment Variables
Before starting the Docker stack, configure apps/saasframe/.env with at least these required variables:
# Database (container uses these to initialize PostgreSQL)
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres
POSTGRES_DB=saasframe
DATABASE_URL=postgres://postgres:postgres@postgres:5432/saasframe
# Authentication (generate a strong secret for production)
JWT_SECRET=your-secure-jwt-secret-change-me
# Application
APP_URL=http://localhost:3000
NODE_ENV=development
# Caching
CACHE_REDIS_URL=redis://redis:6379
CACHE_STRATEGY=redis
# Search (optional but recommended)
MEILISEARCH_HOST=http://meilisearch:7700
MEILISEARCH_API_KEY=meilisearch-dev-key
MEILISEARCH_MASTER_KEY=meilisearch-dev-key
# AI Features (optional)
OPENAI_API_KEY=sk-your-openai-key
# Vector search auto-indexing is off by default in the shipped example env.
# Enable it only when you want real-time embedding jobs:
SF_DISABLE_VECTOR_SEARCH_AUTOINDEXING=false
If you keep SF_DISABLE_VECTOR_SEARCH_AUTOINDEXING=true (the default in apps/saasframe/.env.example), semantic search can still be configured and reindexed manually, but record changes will not enqueue embeddings automatically. The legacy alias DISABLE_VECTOR_SEARCH_AUTOINDEXING=1 still works, but prefer the SF_ name for new setups.
Note: The container hostnames (postgres, redis, meilisearch) match the service names in docker-compose.fullapp.yml.
Common Operations
Start services in detached mode:
docker compose -f docker-compose.fullapp.yml up -d
View logs from all services:
docker compose -f docker-compose.fullapp.yml logs -f
View logs from app only:
docker compose -f docker-compose.fullapp.yml logs -f app
Rebuild after code changes:
docker compose -f docker-compose.fullapp.yml up --build
Stop all services:
docker compose -f docker-compose.fullapp.yml down
Stop and remove volumes (deletes all data):
docker compose -f docker-compose.fullapp.yml down -v
Restart a specific service:
docker compose -f docker-compose.fullapp.yml restart app
Data Persistence
Data is stored in named Docker volumes:
saasframe-postgres-data- PostgreSQL databasesaasframe-redis-data- Redis cache and eventssaasframe-meilisearch-data- Meilisearch indexes
Volumes persist between container restarts unless explicitly removed with docker compose down -v.
Backup volumes:
# Backup PostgreSQL
docker exec saasframe-postgres pg_dump -U postgres saasframe > backup.sql
# Restore PostgreSQL
cat backup.sql | docker exec -i saasframe-postgres psql -U postgres -d saasframe
Production Deployment Tips
When deploying to production environments, consider these recommendations:
Security:
- Generate a strong, unique
JWT_SECRET(useopenssl rand -base64 32) - Use strong, random passwords for
POSTGRES_PASSWORDandMEILISEARCH_MASTER_KEY - Never expose database or Redis ports directly to the internet
- Consider using Docker secrets or external secret management (Vault, AWS Secrets Manager)
Infrastructure:
- Use managed database services (AWS RDS, Google Cloud SQL, Azure Database) instead of containerized PostgreSQL for production workloads
- Consider managed Redis (AWS ElastiCache, Redis Cloud) for better reliability
- Set up a reverse proxy (nginx, Traefik) with SSL/TLS termination
- Use Docker Swarm or Kubernetes for orchestration and scaling
- Configure resource limits for containers (CPU, memory)
Monitoring & Operations:
- Enable health checks for all services (already configured in docker-compose.fullapp.yml)
- Set up log aggregation (ELK stack, Loki, CloudWatch)
- Monitor container resource usage and disk space
- Configure automated backups for volumes
- Test restore procedures regularly
Application Configuration:
- Set
NODE_ENV=productionin production environments - Configure proper
APP_URLwith your domain - Review and set optional environment variables for AI, email, and integrations
- Consider external Meilisearch for better search performance at scale
Troubleshooting
Container fails to start:
# Check logs for errors
docker compose -f docker-compose.fullapp.yml logs app
# Verify environment variables
cat apps/saasframe/.env
# Check if ports are already in use
lsof -i :3000
lsof -i :5432
lsof -i :6379
Database connection errors:
# Verify PostgreSQL is running
docker compose -f docker-compose.fullapp.yml ps postgres
# Check if database exists
docker exec saasframe-postgres psql -U postgres -c "\l"
# Verify DATABASE_URL matches container configuration
grep DATABASE_URL apps/saasframe/.env
Build errors:
# Clean build cache
docker compose -f docker-compose.fullapp.yml build --no-cache
# Remove old images
docker image prune -a
Out of disk space:
# Check Docker disk usage
docker system df
# Clean up unused resources
docker system prune -a --volumes
Reset everything:
# Stop and remove all containers, networks, and volumes
docker compose -f docker-compose.fullapp.yml down -v
# Rebuild from scratch
docker compose -f docker-compose.fullapp.yml up --build
Architecture Overview
The docker-compose.fullapp.yml stack includes:
- app - Open Saasframe application (Node.js 24, Next.js)
- postgres - PostgreSQL 17 with pgvector extension
- redis - Redis 7 for caching and event persistence
- meilisearch - Meilisearch v1.11 for full-text search
- opencode - Claude Code integration (optional)
Services communicate via a dedicated Docker network (saasframe-network-fullapp) and use health checks to ensure proper startup order.
For advanced/manual flows (custom migration control, selective seeding, etc.) see the CLI reference in the repository README.

