Skip to content

Aggregator DPG Setup

The Aggregator DPG is the downstream portal (web), API and worker. It sits in front of the Signals DPG, so its local stack brings up both DPGs plus the shared infra (Postgres, Redis, Keycloak, MinIO, Mailpit).

Pick a track: A — Docker-only (one command, whole ecosystem) or B — hybrid dev (run the apps from source with hot-reload).

Clone both repos side by side, then run everything from aggregator-dpg/local-setup/:

Terminal window
git clone https://github.com/Blue-Dots-Economy/aggregator-dpg.git
git clone https://github.com/Blue-Dots-Economy/signals-dpg.git # sibling — required
cd aggregator-dpg/local-setup
docker login dhi.io # app images build FROM dhi.io
cp .env.example .env # set ADMIN_EMAILS
./gen-secrets.sh # fills every CHANGE_ME_* value
echo "127.0.0.1 keycloak" | sudo tee -a /etc/hosts # OIDC issuer must resolve
docker compose up -d --build
Open thisURL
Aggregator portalhttp://localhost:3100
Signals UIhttp://localhost:5173
Mailpit inboxhttp://localhost:8025 (catches all dev mail)
Signals Searchhttp://localhost:3110 (only with --profile search)
MinIO consolehttp://localhost:9001 (S3 API on 9000)

Search is published on 3110 here, not 3100 — the Aggregator portal already owns that port. Inside the compose network it still listens on 3100, so container-to-container URLs match the Signals-only stack.

Full URL list, cross-DPG wiring and troubleshooting are in the local-setup/LOCAL_SETUP.md guide.

Run the backing services in Docker and the apps from source:

Terminal window
cd aggregator-dpg/local-setup && cp .env.example .env
./gen-secrets.sh # fills every CHANGE_ME_*
echo "127.0.0.1 keycloak" | sudo tee -a /etc/hosts # needed for Track B too
docker compose up -d postgres signals-redis aggregator-redis \
keycloak keycloak-init mailpit minio minio-init # infra only
cd .. # repo root
pnpm install && pnpm -w build # build workspace packages first
cp apps/api/.env.example apps/api/.env # + apps/web, apps/worker
pnpm --filter @aggregator-dpg/api db:migrate
pnpm --filter @aggregator-dpg/api dev # API :4000
pnpm --filter @aggregator-dpg/web dev # portal :3000

The full guide lists the exact per-app .env values (Signals wiring, Keycloak issuer, ports). Keycloak serves both DPGs from one realm, so it is shared infrastructure here rather than an aggregator-only service — see Keycloak Setup.

Continue to Configuration or the Adaptor Onboarding walkthrough.

The unified stack runs the Signals tier too, so without search its discover results come back in recency order and match scores are unavailable. To add it:

Terminal window
cd aggregator-dpg/local-setup
cp .env.search.example .env.search # then mint an apikey — see §10.3 of the guide
docker compose --profile search up -d

Unlike the two DPGs, which this stack builds from source, signals-search is pulled prebuilt from public GHCR — no third checkout and no registry login.

Details specific to this stack — the 3110 port, targeting the signals database rather than aggregator, and using the signals-redis instance — are in §10 of the local-setup/LOCAL_SETUP.md guide. The canonical reference for signals-search’s own configuration is §7 of signals-dpg’s guide.