Run the full CCE platform on your laptop in ~10 minutes — infra (SQL, Redis, Meilisearch, MailDev, ClamAV) + two .NET 8 APIs + two Angular 19 apps.
TL;DR: clone →
cp .env.example .env && cp .env.local.example .env.local→docker compose up -d→dotnet run --project backend/src/CCE.Seeder -- --migrate --demo→ start the 4 apps below → open http://localhost:4200 (public portal) and http://localhost:4201 (admin console).
| # | Component | Stack | URL | Port |
|---|---|---|---|---|
| 1 | SQL Server 2022 | Azure SQL Edge (arm64) / SQL Server (x64) | localhost,1433 |
1433 |
| 2 | Redis 7 | distributed cache + rate limiter | localhost:6379 |
6379 |
| 3 | Meilisearch | full-text search | http://localhost:7700 |
7700 |
| 4 | MailDev | local SMTP inbox | http://localhost:1080 |
1080 / 1025 |
| 5 | ClamAV | antivirus daemon for uploads | localhost:3310 |
3310 |
| 6 | External API | .NET 8 minimal-API (BFF for public portal) | http://localhost:5001 |
5001 |
| 7 | Internal API | .NET 8 minimal-API (admin) | http://localhost:5002 |
5002 |
| 8 | Web portal | Angular 19 (public) | http://localhost:4200 |
4200 |
| 9 | Admin CMS | Angular 19 (back-office) | http://localhost:4201 |
4201 |
Services 1–5 run in Docker. Services 6–9 run on the host so hot-reload works.
- Docker v26+ (OrbStack, Docker Desktop, or Colima) with Docker Compose v2
- .NET 8 SDK (
dotnet --version≥ 8.0) - Node.js 20+ (
node -v≥ 20) - pnpm 9+ (
npm install -g pnpmorcorepack enable) curl+ncfor healthchecks (pre-installed on macOS/Linux)
Apple Silicon note: Docker uses Azure SQL Edge instead of SQL Server 2022 on arm64 — handled automatically, see ADR-0016.
# 1. Clone
git clone https://github.com/Azm-Tech/cce-platform.git
cd cce-platform
# 2. Bootstrap env files
cp .env.example .env
cp .env.local.example .env.local
# 3. Install frontend deps (≈90 s)
pnpm install --frozen-lockfile
# 4. Restore backend NuGet packages
dotnet restore backend/CCE.slnThe .env.local ships with safe dev defaults — Strong!Passw0rd for SQL, dev placeholders for Entra ID, etc. Real secrets (production Entra ID client secret, Sentry DSN) are never committed.
You'll need four terminals open (or use a multiplexer like tmux / iTerm panes).
docker compose up -d
docker compose ps # wait until all are "(healthy)" — ~90 secondsIf a service shows unhealthy, run docker compose logs <service> to see why.
dotnet run --project backend/src/CCE.Seeder -- --migrate --demoThis:
- Applies all EF Core migrations (creates schemas + tables).
- Seeds roles + permissions.
- Seeds 5 dev users (one per role: admin / editor / reviewer / expert / user) with deterministic GUIDs.
- Seeds demo data — topics, posts, replies, knowledge maps, news, events, country profiles, resources.
You only need to re-run this if you reset the database or pull new migrations. Use --migrate (no --demo) to skip demo data.
cd backend/src/CCE.Api.External
ASPNETCORE_ENVIRONMENT=Development dotnet run --urls=http://localhost:5001This is the public-facing API consumed by the web portal. Implements BFF cookie auth + public-only endpoints.
cd backend/src/CCE.Api.Internal
ASPNETCORE_ENVIRONMENT=Development dotnet run --urls=http://localhost:5002This is the admin API consumed by admin-cms. Exposes moderation + CMS endpoints with permission checks.
# from the repo root
pnpm nx serve web-portal --port 4200 # public site
pnpm nx serve admin-cms --port 4201 # admin consoleYou can run both at once with:
pnpm nx run-many -t serve -p web-portal,admin-cmsEach app proxies /api/* requests to its respective backend (web-portal → 5001, admin-cms → 5002), so cookies stay first-party.
Public portal — http://localhost:4200
Browse the homepage, knowledge center, community, world map, interactive city, country profiles, news, events. No login needed for read access.
To sign in as a regular user during dev:
http://localhost:5001/dev/sign-in?role=cce-user
This sets a cce-dev-role=cce-user cookie that the dev auth shim (active when Auth:DevMode=true) recognizes as the seeded user [email protected]. Reload the portal — you're signed in.
Admin console — http://localhost:4201
Same dev auth flow against the internal API:
http://localhost:5002/dev/sign-in?role=cce-admin
Then open http://localhost:4201 — you'll see all admin features: users, content, community moderation, knowledge maps, etc.
Available dev roles:
| Role | Capability |
|---|---|
cce-admin |
Full admin — all permissions |
cce-editor |
Author + edit content |
cce-reviewer |
Review-only |
cce-expert |
Community expert (gold badge on replies) |
cce-user |
Regular member |
Skip the cookie dance and pass the role in the Authorization header:
curl -H 'Authorization: Bearer dev:cce-admin' \
'http://localhost:5002/api/admin/community/posts?status=all'The dev auth shim is only registered when
Auth:DevMode=trueinappsettings.Development.json. Production deployments use real Entra ID and never expose this path — see Sub-11 Entra ID migration.
# Backend (≈30 s)
dotnet test backend/CCE.sln
# Frontend unit tests (≈30 s)
pnpm nx run-many -t test
# Frontend lint (≈10 s)
pnpm nx run-many -t lint
# E2E with Playwright + axe-core (≈3 min — needs the stack running)
pnpm nx run-many -t e2e
# Contract drift check (OpenAPI ↔ generated TS clients)
./scripts/check-contracts-clean.shError: listen EADDRINUSE: address already in use :::4200
Find and kill the process:
lsof -nP -iTCP:4200 -sTCP:LISTEN
kill -9 <pid>Vite's dependency cache went out of sync with the running server. Clear it and restart:
rm -rf frontend/.angular frontend/node_modules/.vite
# then restart `pnpm nx serve web-portal` and hard-reload your browser (⌘⇧R)You launched dotnet run without ASPNETCORE_ENVIRONMENT=Development. Either prefix the env var (as shown above) or remove --no-launch-profile if you added it.
docker compose ps sqlserver # is it healthy?
docker compose logs sqlserver # what's it complaining about?On low-memory machines (< 4 GB free), SQL Server / Azure SQL Edge can fail to start. Bump Docker's memory allocation.
Most often Login failed for user 'sa' — the SQL password in .env.local doesn't match the seeded SA password. Tear down with docker compose down -v (destroys data) and start fresh.
# Stop services, keep data volumes
docker compose down
# Stop services AND destroy all SQL/Redis/Meilisearch data
docker compose down -vproject-plan/README.md— sub-project index (specs, plans, completion reports)docs/adr/— 60+ architecture decisions explaining why things are built this waydocs/runbooks/— production operational procedures (DR, backup/restore, secret rotation)docs/subprojects/— one-page brief per sub-projectCONTRIBUTING.md— branch model, commit format, PR checklist