Run the whole dashboard under Aspire
You have built the full spine — contract, service, query layer, page, and live stream. This final
chapter steps back and runs the entire graph as one system: the orders service, the Fresh
dashboard, the durable-streams runtime, Postgres, and Redis, all under a single aspire start. We
is precise about what local Aspire is — a development orchestrator — and what it is not.
- 1 · Scaffold
- 2 · Contract to service
- 3 · Cache-first query
- 4 · definePage + island
- 5 · Live stream
- 6 · Deploy
What you will build
A complete, observable run of my-dashboard/ on one machine: every resource your dashboard touches,
booted in dependency order from a single command, with the wiring resolved into injected environment
variables and the whole graph visible in the Aspire dashboard at :18888. You finish the track with
a running live dashboard you can open, watch, and trust you understand.
Before you begin
You should have completed chapter 5: the live monitor
updating in real time. The AppHost was scaffolded back in chapter 1 (you did not pass --no-aspire),
so confirm the orchestration entry points are on disk — from the workspace root:
ls aspire/apphost.mts aspire/aspire.config.json
Both files should exist. apphost.mts is the TypeScript/Node program aspire start executes;
aspire.config.json pins the SDK. netscript init generated them — you never hand-write the
AppHost.
Step 1 — Restore the AppHost SDK (once)
The AppHost runs on its own isolated Node runtime inside aspire/ so its dependencies never leak
into your Deno workspace. Restore that runtime once per machine (and after an SDK bump):
cd aspire
aspire restore
Step 2 — Start the whole graph
A single aspire start translates appsettings.json plus the plugin contributions into a resource
graph and boots all of it — infrastructure first, then the service, the Fresh app, and the streams
runtime, with cross-references resolved into injected environment variables:
# Still inside aspire/. Prints the dashboard URL + a one-time login token.
aspire start
When boot finishes, aspire start prints the dashboard address and a login token. The graph it stands
up for this track:
| Name | Type | Description |
|---|---|---|
aspire (dashboard) |
http://localhost:18888 |
The Aspire dashboard: live resource list, console logs, structured logs and traces. A login token prints on start. |
postgres |
Container |
Provisioned via Docker. The database your orders service reads — reachable only once Aspire is up. |
redis |
Container (cache) |
Redis cache — the default --cache-backend; Redis-compatible. Backs the KV-backed query layer from chapter 3. |
orders |
:3002 |
Your oRPC service (defineService). RPC at /api/rpc/*, OpenAPI at /api/v1/orders/*. |
dashboard (Fresh app) |
:8010 |
Your Fresh frontend — the live dashboard you built in chapters 4–5. |
streams |
:4437 |
Durable-streams producer runtime, present once the sagas plugin is installed. Feeds useLiveQuery. |
Step 3 — Open the live dashboard
With the graph up, open your Fresh app and the orders route you built:
http://localhost:8010/dashboard/orders/
The table renders cache-first (chapter 4), refetches on the client, and — if the streams runtime is up — the live monitor updates in real time (chapter 5). Then open the Aspire dashboard to watch the system behind it:
https://localhost:18888
Paste the login token aspire start printed. You get one pane over the running graph:
| Name | Type | Description |
|---|---|---|
Resources |
tab |
Every container and process with status, endpoints, and resolved environment. The authority for which port each resource bound. |
Console logs |
tab |
stdout/stderr per resource — a failing service or streams runtime is one click away, not buried in a terminal. |
Structured logs + Traces |
tab |
Spans your handlers and pages emit (including the withTelemetry span from chapter 4), correlated across resources via the OTLP collector on :4318. |
Step 4 — Watch a request flow through the graph
Create an order and follow it across the whole stack in one place. From a second terminal:
curl -X POST http://localhost:3002/api/v1/orders/create \
-H 'content-type: application/json' \
-d '{ "userId": 1, "total": 49.9, "status": "pending", "shippingStreet": "1 Main", "shippingCity": "Berlin", "shippingCountry": "DE", "shippingZipCode": "10115", "items": [{ "productId": 1, "quantity": 1 }] }'
In the Resources tab you can see the orders service handle it; in Traces the request shows
as a span; the live monitor in your Fresh app advances a new saga row; and the orders table picks up
the new order on its next revalidation. One command, the full spine, observable end to end.
Verify your progress
# From the workspace root, with `aspire start` up in another terminal:
curl http://localhost:3002/health # orders service
curl http://localhost:4437/health # streams runtime (if sagas installed)
Both should return healthy responses, and the dashboard at :18888 should list postgres,
redis, orders, the Fresh dashboard, and streams all running.
- [ ]
aspire restorethenaspire startboots the graph without errors. - [ ]
https://localhost:18888lists every resource healthy. - [ ]
http://localhost:8010/dashboard/orders/renders the live table. - [ ] Creating an order is visible in the dashboard traces and the live monitor.
What you built
You ran the complete my-dashboard/ graph under one aspire start: service, Fresh app, durable
streams, Postgres, and Redis, wired automatically and observable in the dashboard at :18888. That
closes the track — you have built and run a real live operations dashboard on the full NetScript
spine.
Where to go next
- Task recipes → the how-to guides cover what the tutorials don't: adding plugins, database migrations, queue backends, and production pitfalls.
- Ship it remotely → Deploy is the production companion to local Aspire.
- Go deeper → Orchestration with Aspire explains the AppHost, plugin contributions, and two-pass reference resolution; Durable streams and the Fresh meta-framework back chapters 4 and 5.