Appearance
Run Locally
This page gives two supported local-development patterns:
- full Docker Compose bootstrap — fastest way to get a demo running end to end;
- hybrid manual development — infrastructure in containers, .NET and UI projects started locally for debugging.
The examples below use Property Management. Trade and Agency Billing follow the same pattern with their own compose and environment files. CRM additionally consumes local platform packages; follow Prepare local platform packages before starting it.
Use .NET 10 SDK, Docker Compose v2 with Linux containers, and Node.js 24.19.x for platform package tooling. Bash examples run from the repository root unless stated otherwise. On Windows, run package tooling in WSL2; certificate setup also has a PowerShell example below.
Option 1: Full Docker Compose bootstrap
What the PM compose environment starts
The Property Management compose environment starts the following services in order:
- PostgreSQL
- database bootstrap
- Keycloak realm bootstrap
- Keycloak
- Seq
- Migrator
- API
- Background Jobs
- Watchdog
- Web client
- pgAdmin
Environment file
The main environment file is:
bash
.env.pmIt includes the local ports and demo credentials used by the stack. Important defaults include:
- Web:
http://localhost:5173 - API HTTPS:
https://localhost:7071 - Background Jobs HTTPS:
https://localhost:7074 - Watchdog HTTPS:
https://localhost:7075 - Keycloak public URL:
http://pm-keycloak.localhost:7012 - Seq:
http://localhost:5342 - pgAdmin:
http://localhost:4882
Demo user:
- email:
alex.carter@demo.ngbplatform.com - password:
DemoAdmin!2026
⚠️ Windows note
Compose reads the HOME environment variable, not PowerShell's separate $HOME variable. Set it in the session that launches Compose:
powershell
$env:HOME = $env:USERPROFILE.Replace('\', '/')For IDE launches, configure HOME in the run configuration, or persist it and restart the IDE:
powershell
[System.Environment]::SetEnvironmentVariable('HOME', $env:USERPROFILE.Replace('\', '/'), 'User')Export the PFX file as described under HTTPS certificates before startup.
Start the demo
From the repository root:
bash
docker compose -f docker-compose.pm.yml --env-file .env.pm up --buildStop the demo
bash
docker compose -f docker-compose.pm.yml --env-file .env.pm downOpen the running services
- Web:
http://localhost:5173 - API health:
https://localhost:7071/health - Background Jobs dashboard:
https://localhost:7074/hangfire - Watchdog UI:
https://localhost:7075/health-ui - Keycloak:
http://pm-keycloak.localhost:7012 - Seq:
http://localhost:5342 - pgAdmin:
http://localhost:4882
What the compose migrator does
The PM compose stack runs the migrator container with this effective sequence:
- migrate PM packs with
--modules pm --repair; - run
seed-defaults; - optionally run
seed-demo.
That means a fresh local environment comes up already migrated and seeded.
Prepare local platform packages
The full solution includes CRM, which consumes NGB.Platform.* through NuGet. PM, AB, and Trade use project references. Before building CRM or the complete solution against unpublished/local platform code, populate the local feed configured in NuGet.config.
Package npm before NuGet
From the repository root on macOS/Linux or in WSL2:
bash
npm --prefix ui ci
npm --prefix ui run pack:platform-ui -- --local-candidate
bash packaging/nuget/pack-platform.shThe UI archive must exist first. NuGet packing includes the application template, whose lockfile preparation reads that archive. pack-platform.sh packages the complete set from packaging/nuget/projects.txt, refreshes artifacts/nuget, invalidates replaced versions in artifacts/nuget-cache, and restores NGB.sln. It also regenerates template and CRM lockfile data against the package set.
CRM's local web image uses artifacts/npm/ngbplatform-ui-local.tgz. Re-run package preparation after changing the platform. --local-candidate permits npm packing before its matching lockfiles exist; subsequent NuGet packing prepares them.
Windows package tooling
Use a WSL2 checkout and install .NET 10, Node 24.19.x and npm inside that distribution. Enable Docker Desktop integration for it, then run the same Bash commands above. The current Node packaging/application scripts launch subprocesses that are not supported by this runbook on native Windows. The former standalone PowerShell dotnet pack loop did not generate the template lockfiles and is not equivalent to the complete package-preparation sequence.
Start CRM
After both package preparations and certificate setup:
bash
docker compose -f docker-compose.crm.yml --env-file .env.crm up -d --buildUnable to find package NGB.Platform.* indicates that the required NuGet version is absent from the configured feeds. ENOENT ... ngbplatform-ui-local.tgz indicates that the UI packaging step was skipped. Both artifacts are ignored by Git and must be recreated on a new machine.
Option 2: Hybrid manual development
Use this mode when you want infrastructure bootstrapped quickly but want to debug the .NET or Vue apps locally.
Step 1: Start infrastructure only
Start PostgreSQL, bootstrap, Keycloak, Seq, and optional pgAdmin:
bash
docker compose -f docker-compose.pm.yml --env-file .env.pm up ngb.pm.postgres ngb.pm.postgres.bootstrap ngb.pm.keycloak.init ngb.pm.keycloak ngb.pm.seq ngb.pm.pgadmin -dStep 2: Run the migrator locally
Create a connection string that matches .env.pm:
bash
export NGB_PM_CONNECTION="Host=localhost;Port=5433;Database=ngb_pm;Username=ngb_pm_app;Password=Password(55)60-stronG-pm"Run migrations:
bash
dotnet run --project NGB.PropertyManagement.Migrator -- --connection "$NGB_PM_CONNECTION" --modules pm --repairSeed defaults:
bash
dotnet run --project NGB.PropertyManagement.Migrator -- seed-defaults --connection "$NGB_PM_CONNECTION"Seed demo data if needed:
bash
dotnet run --project NGB.PropertyManagement.Migrator -- seed-demo --connection "$NGB_PM_CONNECTION" --dataset demo --seed 20260412 --from 2024-01-01 --skip-if-dataset-exists trueStep 3: Run backend hosts locally
You can run the PM API, Background Jobs, and Watchdog projects from your IDE or from the CLI. The exact local settings can be taken from .env.pm.
Typical environment variables you will need:
bash
export ConnectionStrings__DefaultConnection="$NGB_PM_CONNECTION"
export KeycloakSettings__Issuer="http://pm-keycloak.localhost:7012/realms/ngb-demo"
export KeycloakSettings__RequireHttpsMetadata="false"
export Serilog__WriteTo__1__Args__serverUrl="http://localhost:5342"To create, update, deactivate, and reactivate users from the NGB UI, also configure the Keycloak Admin client for the API:
bash
export KeycloakAdminClientSettings__BaseUrl="http://pm-keycloak.localhost:7012"
export KeycloakAdminClientSettings__Realm="ngb-demo"
export KeycloakAdminClientSettings__ClientId="<admin-client-id>"
export KeycloakAdminClientSettings__ClientSecret="<admin-client-secret>"Application roles and permissions are stored in NGB, not in the Keycloak token. See Security and Permissions.
Then run the hosts you need:
bash
dotnet run --project NGB.PropertyManagement.Api
dotnet run --project NGB.PropertyManagement.BackgroundJobs
dotnet run --project NGB.PropertyManagement.WatchdogStep 4: Run the web client locally
From the UI workspace root:
bash
cd ui
npm ci
npm run dev:pm-webThe UI workspace already exposes dedicated workspace scripts such as:
npm run dev:pm-webnpm run dev:trade-webnpm run dev:ab-webnpm run dev:crm-web
Developer notes
HTTPS certificates
Compose mounts ${HOME}/.aspnet/https and uses /https/servercert.pfx by default. Trust and export a development certificate, using the same password as ASPNET_CERT_PASS in .env.*. Trusting the certificate alone does not create the mounted PFX file.
Bash:
bash
dotnet dev-certs https --trust
mkdir -p "$HOME/.aspnet/https"
dotnet dev-certs https --export-path "$HOME/.aspnet/https/servercert.pfx" --password "<ASPNET_CERT_PASS>"PowerShell:
powershell
$env:HOME = $env:USERPROFILE.Replace('\', '/')
New-Item -ItemType Directory -Force "$env:HOME/.aspnet/https" | Out-Null
dotnet dev-certs https --trust
dotnet dev-certs https --export-path "$env:HOME/.aspnet/https/servercert.pfx" --password "<ASPNET_CERT_PASS>"Local hostname for Keycloak
Modern browsers generally resolve *.localhost correctly. If your environment does not, add a host entry manually:
text
127.0.0.1 pm-keycloak.localhostValidation commands
After preparing the local NuGet feed above, use these commands from the repository root:
bash
dotnet build NGB.sln
dotnet test NGB.slnFrom the UI workspace:
bash
cd ui
npm ci
npm run test:allWhen to use which mode
Use full Docker Compose when you want a quick demo environment.
Use hybrid manual development when you are actively coding and want:
- debugger-friendly .NET hosts;
- quick restarts;
- local UI hot reload;
- containerized infrastructure with minimal setup.
That hybrid mode is usually the best day-to-day developer workflow.