Skip to main content

Local Dev Setup

Run ForgePortal from source with pnpm and a local PostgreSQL instance. Use this when you're developing the platform or contributing.

Prerequisites

RequirementVersion / notes
Node.js20+ (project uses engines.node: ">=20.19.0")
pnpm10+ (monorepo uses pnpm workspaces; packageManager: "pnpm@10.6.2")
PostgreSQL16 (e.g. postgres:16-alpine in Docker, or local 16)
GitFor cloning and entity discovery

Check versions:

node --version   # v20.x or v22.x
pnpm --version # 10.x
psql --version # 16.x (if using local Postgres)

Clone and install

git clone https://github.com/forgeportal/forgeportal.git
cd forgeportal
pnpm install

This installs dependencies for all workspace packages (core, catalog, api, ui, worker, docs, etc.).

Database

You need a running PostgreSQL 16 with a database and user. Options:

  1. Use Docker Compose for Postgres only — from repo root, run Postgres from the same Compose env:

    cd deployments/docker-compose
    docker compose up -d postgres

    Then point the app to localhost and the exposed port (e.g. 5433 if DB_PORT_HOST=5433).

  2. Local Postgres 16 — create a database and user:

    createdb forgeportal
    # Ensure user has access; set DB_HOST=localhost, DB_PORT=5432, DB_NAME=forgeportal, DB_USER=..., DB_PASSWORD=...

Set env vars (or a .env in the repo root if your tooling loads it):

export DB_HOST=localhost
export DB_PORT=5432
export DB_NAME=forgeportal
export DB_USER=forge
export DB_PASSWORD=forge_local_dev
export ENCRYPTION_KEY=local-dev-key-change-in-prod-32chars!

Run migrations (from repo root, using the API or a migration script if you have one):

# If your project has a migrate script:
pnpm run migrate
# Or apply SQL manually from tools/migration/*.sql

Run the stack in dev

From the repo root:

pnpm dev

This runs Turborepo in dev mode: it starts the API, Worker, and UI (and any other apps configured in turbo.json). Typical ports:

ServicePortURL
UI3000http://localhost:3000
API4000http://localhost:4000

Without OIDC configured, the API runs in dev-mode; the UI may allow access without login (depending on your auth guard setup).

Monorepo layout (short)

PathRole
apps/apiFastify API server
apps/uiReact (Vite) frontend
apps/workerJob runner + action runner
apps/docsDocusaurus docs site
packages/coreConfig, logger, shared utilities
packages/catalogEntities, scan, webhooks
packages/scaffolderTemplates, actions, action runner
packages/authOIDC, RBAC, permissions
tools/migrationSQL migrations
tools/seedSeed SQL

Useful commands

From repo root:

# Build all packages
pnpm build

# Run all tests
pnpm test

# Lint
pnpm lint

# Clean build artifacts
pnpm clean

Single package (examples):

# Run API tests only
pnpm --filter @forgeportal/api test

# Run UI dev (if not using turbo dev for everything)
pnpm --filter @forgeportal/ui dev

# Build docs site
pnpm --filter @forgeportal/docs-site build

# Serve docs site (Docusaurus)
pnpm --filter @forgeportal/docs-site dev

Verification

  1. Open http://localhost:3000 — UI loads.
  2. Open http://localhost:4000/healthz — returns {"status":"ok","db":"connected"} when DB is up.
  3. (Optional) Create an entity and run a scan — see Your first entity.

Next: Your first entity — add an entity.yaml to a repo and see it in the catalog.