Deployment topologies
Choose whether to run MDK as a single process or as supervised services
This page explains the three supported deployment shapes and when to pick each.
Overview
MDK's runtime pieces — the ORK kernel, the App Node, and one or more Workers — can run together in a single process or be split across several. This is a packaging and operations choice, and it's independent of how MDK scales logically (adding Workers, adding sites).
If ORK, worker, manager, or thing are unfamiliar, read terminology.md first.
Connection model
Before choosing a shape, it helps to understand which components initiate connections:
- The App Node dials ORK — it is the active side of that connection, over IPC (same host) or HRPC (remote host)
- ORK discovers Workers and initiates every RPC call — Workers are passive; they become reachable and wait
- Workers never initiate any connection
This directionality is what drives the transport and discovery configuration in each shape below. For detail, see the Workers discovery model and the App Node ORK connection.
The three shapes
Single process
Solid arrow: active connection initiated by the source. Dashed arrow — ORK-initiated discovery.
ORK, the App Node, and every Worker run inside one Node.js heap and event loop. Lowest footprint, simplest to start, nothing external to supervise. This is the shape behind the single-process site how-to.
Local
Solid arrow: active connection initiated by the source. Dashed arrow — ORK-initiated discovery.
Each service runs as its own OS process on the same machine. ORK discovers Workers via a shared directory — no DHT configuration needed. The full-site example runs in local mode by default.
Microservices
Solid arrow: active connection initiated by the source. Dashed arrow — ORK-initiated discovery.
Each service runs as its own OS process or container, potentially on separate hosts, supervised by pm2 or Docker and connected via DHT. This is the shape behind the microservices site how-to.
The trade-off
Pick single-process when:
- You are developing locally, running demos, or want a self-contained site for tests
- Footprint matters more than isolation (minimal or embedded deployments)
- You do not need supervisor-managed restarts
Pick local when:
- All services run on one machine and you want independent process restarts
- Outbound networking is restricted removing DHT as an option
- You want process isolation and independent restarts without the complexity of DHT
Pick microservices when:
- You want to allocate resources per service — CPU and memory limits per process or container
- Workers run on separate hosts from ORK or the App Node
- You are orchestrating many Workers across one or more hosts
Where worker.js fits
The microservices shape is built on backend/core/mdk/worker.js, a shared process entry compatible with pm2, Docker, or a direct node worker.js. It is driven by environment variables (SERVICE, and for a Worker WORKER/TYPE/RACK) rather than CLI flags. One worker.js runs per service, and the supervisor (pm2 or Docker) owns its lifecycle and resource limits. The standalone worker.js install pattern defines the per-Worker mechanics.
The single-process and local shapes both call the programmatic APIs (getOrk, startWorker, startAppNode) directly. Local mode passes discovery: { mode: 'local' } to both getOrk and startWorker so they coordinate via a shared directory rather than DHT — see local worker discovery for configuration options.
Relationship to scaling
Topology is orthogonal to scale. Logical scaling is about how many Workers and ORK kernels you run (parallel Workers, per-site kernels, multi-site oversight). Deployment topology is about how those processes are packaged on a given host. You choose both: for example, a production site typically runs multiple processes (this page) and multiple parallel Workers per kernel (scaling).
Next steps
- Run a self-contained local site: Single-process site
- Run same-machine services without DHT
- Run supervised services on one or more hosts
- Register one miner before packaging a whole site