Developer Setup (IDE + Hot-Reload)
For developers who want to run Next.js locally with IDE integration, debugging, and hot-reload. Databases run in Docker with ports exposed to your host machine. This is separate from the Windows installer — it’s for working on the platform itself.
If you want the packaged customer experience, use the installer instead — see the repo README.md Quick Start.
Prerequisites
| Tool | Version |
|---|---|
| Git | Latest |
| Docker Desktop | 4.40+ |
| Node.js | 20+ |
| pnpm | 9+ |
Option A: Automated script
git clone https://github.com/OpenDigitalProductFactory/opendigitalproductfactory.git
cd opendigitalproductfactory
.\scripts\fresh-install.bat
The script will:
- Install pnpm dependencies (
node_modules) - Create all
.envfiles (Docker + app-level) with generated secrets - Start PostgreSQL with port 5432 exposed to the host
- Run database migrations and seed data (including all epic/backlog SQL scripts)
Then start the dev server:
pnpm --filter web dev # http://localhost:3000
Option B: Manual setup
git clone https://github.com/OpenDigitalProductFactory/opendigitalproductfactory.git
cd opendigitalproductfactory
pnpm install
Note: the repo
.npmrcsetspackage-import-method=copy, so installs copy files out of the pnpm store instead of hardlinking. This is deliberate: with many concurrent git worktrees sharing one store on the same volume, hardlinks let a single mutatednode_modulesfile corrupt the store and every sibling worktree. Copies cost more disk and install time per worktree — don’t revert this to speed up an install.
Create environment files:
# 1. Root .env — used by Docker Compose for container credentials
cp .env.docker.example .env
# 2. App-level .env file — used by Next.js and local Prisma commands
cp .env.example apps/web/.env.local
Then edit .env and apps/web/.env.local to replace the <generate with: ...> placeholders with real values. On Windows PowerShell:
# Generate AUTH_SECRET (base64)
[Convert]::ToBase64String((1..32 | ForEach-Object { [byte](Get-Random -Max 256) }))
# Generate CREDENTIAL_ENCRYPTION_KEY (hex)
-join ((1..32) | ForEach-Object { "{0:x2}" -f (Get-Random -Max 256) })
INNGEST_SIGNING_KEY and INNGEST_EVENT_KEY each need their own 64-hex-character value (openssl rand -hex 32). Compose refuses to start without them. The portal and the inngest service share them, so after changing either one, recreate both services together.
Or use the automated script (Option A) which handles this automatically.
If you have an older install with packages/db/.env, Prisma still treats it as a legacy fallback, but new installs should not need it.
Start databases (with ports exposed to host):
If you are in a linked git worktree, run scripts/seed-worktree-mcp.ps1 on Windows or scripts/seed-worktree-mcp.sh on macOS / Linux before any Compose command. The seeder writes an ignored .env value like COMPOSE_PROJECT_NAME=dpf-<topic> so worktree containers and volumes cannot join the root dpf project.
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d postgres
This exposes PostgreSQL on port 5432 to your host machine.
Run migrations and seed:
pnpm --filter @dpf/db exec prisma generate # Generate Prisma client
pnpm --filter @dpf/db exec prisma migrate deploy # Apply all migrations
pnpm --filter @dpf/db seed # Seed roles, agents, taxonomy, admin user
Build the promoter image (required for Build Studio feature deployment):
docker build -f Dockerfile.promoter -t dpf-promoter .
Build the document engine image (optional, for office document conversion). An install made with the installer does not need this step: a Customizable install pins the dpf-doctools image published for the release tag its clone descends from (the git describe baked into the portal as DPF_PLATFORM_VERSION), by digest, and builds Dockerfile.doctools from the clone only when no published image is reachable. That pin is stored in self_upgrade.doctoolsImage and resolved again after every upgrade. Build it by hand only for a bare pnpm dev portal, or to test changes to the image. The portal runs it one-shot; compose never starts it. The smoke test exercises it offline and read-only:
docker build -f Dockerfile.doctools -t dpf-doctools .
bash tools/doctools/smoke.sh dpf-doctools
The portal only runs a digest-pinned image. To point a dev portal at a local build, set DPF_DOCTOOLS_IMAGE in the dev portal’s own environment to its image id (docker image inspect -f '' dpf-doctools). The docker-gated converter test uses the same reference and is skipped without it:
DPF_DOCTOOLS_TEST_IMAGE="$(docker image inspect -f '' dpf-doctools)" pnpm --filter web exec vitest run lib/documents/conversion/convert.docker.test.ts
Start the dev server:
pnpm --filter web dev # http://localhost:3000
Login: admin@dpf.local / changeme123
Running Tests
pnpm typecheck # TypeScript across all workspaces
pnpm test # Vitest unit tests (web + db + mobile)
pnpm test:e2e # Playwright end-to-end against running portal
pnpm test:e2e:demo # Headed sandbox-preview demo
Branching
After install-dpf.ps1 runs in Customizable mode, your clone sits on a per-install branch named dpf/<instance-id>. That branch is the shared workspace for Build Studio and VS Code on this install — leave it where it is.
For feature work, create short-lived topic branches off main:
git fetch origin
git checkout -b feat/my-thing origin/main
# ... work, commit ...
git push -u origin feat/my-thing
gh pr create --base main
Branch prefixes by intent: feat/*, fix/*, chore/*, doc/*, clean/*. One concern per branch. See CONTRIBUTING.md for the full PR workflow.
Related
- Dev Container Setup — fully containerized alternative, no local Node.js required
- Agent Development Environments — set up Claude, Codex, and Grok (desktop apps or CLI): MCP, skill pack, AGENTS.md, local settings, and managing multiple concurrent threads
- Development Workspace — how Build Studio, VS Code, and production promotion fit together