Skip to content

7.8 Running the Platform Locally

This page starts the whole platform on one machine with Docker and shows how to use it through the apps. Every system and app starts with docker compose up in its own repository and behaves as in the cloud: services that scale to zero, the Pub/Sub emulators pushing to the consumers, schedulers calling the relays and sweepers. Nothing reaches Google Cloud. Read it top to bottom the first time; each repository's docs/local-testing.md has the detail of its side.

7.8.1 What You Need

  • Docker with Compose v2.24 or later, and about 40 GB of free disk.
  • The GitHub CLI, signed in to an account that reads the private moonitoring-common-rs and moonitoring-design. In every terminal that builds: export GITHUB_TOKEN=$(gh auth token) CARGO_BUILD_JOBS=4.
  • Rust (rustup), uv and, for the web apps' hot reload only, Node 24 with pnpm.
  • Windows 10 or 11 for the farm sync client; everything else runs anywhere.
  • The repositories side by side in one folder: moonitoring-system-access, -releases, -farm, -status, moonitoring-app-console, -account, -status, -farm_sync.

The first build of everything takes about an hour; later starts take seconds.

7.8.2 Start the Systems, in This Order

The order matters only at the first start, because each system copies what the one before it publishes:

Step Repository Port Why here
1 moonitoring-system-access 8100 Every other system checks tokens against its keys and copies its people and Organizations. It also runs the stand-in of Identity Platform that people sign in with.
2 moonitoring-system-releases 8300 farm asks it whether a sync client's installation is genuine.
3 moonitoring-system-farm 8200 The data of the farms: sync clients, runs, raw files.
4 moonitoring-system-status 8900 Its probes call the systems above, so it starts last.
cd moonitoring-system-access      && docker compose up --build -d
cd ../moonitoring-system-releases && docker compose up --build -d
cd ../moonitoring-system-farm     && docker compose up --build -d
cd ../moonitoring-system-status   && docker compose up --build -d

Check that each one is ready before going on; within a minute each system subscribes to the events of access, and the sweeper of access reads the others' capability catalogs:

for p in 8100 8300 8200 8900; do curl -s localhost:$p/ready; echo " $p"; done

Each line must say {"status":"ready"}.

7.8.3 Start the Apps

The web apps call the systems through their own host, as in the cloud:

cd moonitoring-app-console && docker compose up --build -d   # 9100 as Luca, 9110 as Anna
cd ../moonitoring-app-account && docker compose up --build -d # 9300
cd ../moonitoring-app-status  && docker compose up --build -d # 9600

The farm sync client is a Windows program: it is built with Cargo and installed from the release system, as farms get it (7.8.4).

7.8.4 Use the Platform

Who you are. The seed of access holds the people every story uses, with fixed identifiers that the other systems' seeds copy:

Person Who Signs in
Luca Verdi, luca@moonitoring.com Staff, Administrators The Console on 9100
Anna Bianchi, anna@moonitoring.com Staff, role Releases: approves what Luca staged The Console on 9110
Maria Rossi Owner of the farm Cascina Uno The Account app on 9300, and the sync client through it
Marco Esposito Technician of Cascina Uno and owner of Cascina Due, so he chooses an Organization The Account app on 9300

Their test passwords are in dev/identity-platform/users.jsonl of moonitoring-system-access; they work only against the local stand-in of Identity Platform, the Firebase Auth emulator on 8103. Staff need none: the Console's two ports play the Identity-Aware Proxy for Luca and Anna.

The Console, http://localhost:9100 and http://localhost:9110 in two windows. Approve or decline the Organizations waiting, look at the sync clients and their runs, stage a release as Luca and approve it as Anna (Luca cannot approve what he staged), open an incident on the status page. The Dev ORM of each system is at localhost:9100/devorm/<system>/. Every story: the Console's guide.

The status page, http://localhost:9600/it and /en: all green while every system answers. Stop a system (docker compose stop backend in its repository) and within about three minutes its card turns red and an incident opens by itself; start it again and the card is green at the next run, while only staff resolve the incident, from the Console.

The farm sync client, from build to sync. The release system distributes it, so it is published first and installed from there:

  1. Build and publish build 1 with releases-publish, the tool CI uses, then approve the staged release as Anna in the Console (the releases guide).
  2. Install it for your Windows user as the client's guide says, and start it.
  3. Connect the computer: Continue in the browser, sign in as Maria on the Account app and press Allow; the browser ends on "You're connected" and the client connects Cascina Uno by itself, her only farm (a person with several farms chooses one). The client registers itself in farm, and releases checks the installation of an installed client: the Console then shows it as installed with its computer's name. A client run from source with cargo run has no installation, so it shows neither.
  4. Add an integration asks for a sign-in at most five minutes old: the browser asks for the password again, then the catalogue lists the software the farm supports (locally the Export folder).
  5. Sync: the client reads the farm software it supports on its schedule; the Console's Ingestion and the Dev ORM of farm show the runs and raw files. With no vendor strategy yet, a local build reads the sample exports of examples/exports/ through the generic reader, which stage and prod builds do not contain.
  6. Update: publish build 2, approve it, and press Check for updates now: the client checks the signed chain, restarts and shows the new version.

7.8.5 Ports

Each repository has its block of host ports from the repository standards:

Port What
8100–8199 access: API 8100, Dev ORM 8101, consumer 8102, Identity Platform stand-in 8103, PostgreSQL 5410, Pub/Sub 8185
8200–8299 farm: API 8200, Dev ORM 8201, consumer 8202, PostgreSQL 5420, Pub/Sub 8285, Cloud Storage stand-in 4243
8300–8399 releases: API 8300, CDN stand-in 8302, consumer 8303, PostgreSQL 5430, Pub/Sub 8385, bucket 4343
8900–8999 status: API and feed 8900, Dev ORM 8901, PostgreSQL 5490, Pub/Sub 8985, feed bucket 4943
9100, 9110 The Console, as Luca and as Anna
9300 The Account app
9600 The status page

If localhost does not answer, another program may hold the same port on IPv6 ([::1]): use 127.0.0.1 in the browser and in the client's local settings.toml. After pulling new code, rebuild with docker compose up --build -d and check with docker images that the image is new; a container started from an old image keeps the old behaviour.

7.8.6 Stop and Start Again

  • docker compose down in each repository, the apps first, stops everything and keeps the data.
  • docker compose down -v removes the databases, buckets and emulators; the next up seeds again. releases makes new signing keys after down -v, so an installed client no longer trusts it: uninstall the client first (moonitoring-farm-sync.exe uninstall).

7.8.7 Not Part of the Local Set-up

  • ai-gateway, moochat, grant, news and the Organization Dashboard are not started here; the sweep of access reports the missing catalogs and nothing else is affected.
  • No vendor parser exists yet: every raw file is kept and its parse job fails as unsupported_version, which records a parser integration gap.
  • releases has no Dev ORM; its button in the Console answers 502.