Skip to main content

Multi-node & clusters

One node is the default and the whole platform. Adding more changes where containers run, not how you use Miabi: a single control plane drives every node, grouped into clusters.

Clusters

Every node belongs to exactly one cluster. A cluster is the unit that shares private networking and a gateway, and there are three shapes:

ClusterWhat it isGateway serving its apps
DefaultThe control-plane node, plus every node that joins its swarmThe control plane's Goma Gateway
StandaloneOne remote node connected to the manager over its agent tunnel. Every node you add starts as oneThe node's own Goma (edge gateway)
Remote swarmA Docker Swarm of remote nodes, made by enabling Swarm on a standalone node and joining others to itThe Goma on the swarm's ingress node

Workspaces see clusters as locations. A new app, database, volume or stack is placed in a location, then on a node inside it; see Locations. Nothing crosses clusters at runtime: networks, volumes and database links stay inside one, and a reference to another location is refused. With an Enterprise license, a plan can bind its workspaces to locations and a node pool.

The tunnel goes outward

The agent dials the control plane, not the other way round. That single decision is what makes a homelab box, a NAT'd VPS or a machine behind a corporate firewall usable as a node: no inbound port, no exposed Docker socket, no VPN.

Once connected, the control plane holds a live Docker API client for that node and uses it exactly as it uses the local engine — the same code path creates a container whether it lands here or three hops away.

Every remote node is reached this way, a remote swarm's managers included, so the control plane drives a swarm in another region without opening a connection into that network. Miabi can install the agent on every member of a swarm for you.

How traffic reaches an app

Each cluster is served by its own gateway, and the DNS records for an app's routes point at it:

Where the app runsGatewayDNS points at
Default clusterThe control plane's Goma, over the ingress overlay for swarm membersThe cluster's public address
Standalone clusterThe node's own GomaThe cluster's public address
Remote swarmThe Goma on the swarm's ingress node, over that swarm's overlayThe cluster's public address

Every app of the default cluster is served by the control plane's Goma, so its nodes run no gateway of their own. A cluster's public address is an IP, or a hostname for a record that cannot use one, set in the cluster's Edit dialog: its gateway, or a load balancer in front of it. A remote cluster learns the IP from the public address its ingress node's agent connects from, until an administrator sets one.

A remote gateway pulls its routes from the control plane over HTTP with its own token and reloads on demand, so routing and middleware definitions stay workspace-level wherever they are served. An administrator picks a remote swarm's ingress node from the cluster's page.

A node's connectivity says whether it runs a gateway of its own:

Node connectivityMeaning
Edge gatewayThe node runs its own Goma and serves its apps. New nodes are always added this way
Cluster gatewayThe node runs no gateway: its cluster's gateway reaches its apps. The control-plane node and swarm members

A node without public ports 80/443 should join a swarm cluster as a worker, where it is served by the cluster's gateway.

Port forwarding is retired

Earlier releases could reach a node's apps through auto-allocated host ports. Upgrading converts such a node to an edge gateway, or to a cluster-gateway node when it is a swarm member, and removes the host ports Miabi held for it. The cluster page of a converted node then offers to keep its gateway or join it to a swarm cluster. Port bindings requested for TCP apps and database port forwarding are unchanged.

A gateway close to its apps is the point: traffic for a distant node or region terminates there instead of crossing the network twice.

Swarm in each cluster

Cluster mode promotes a cluster to a Docker Swarm, which adds encrypted overlay networks spanning its nodes, replicated apps, and cross-node service discovery. Each cluster is its own swarm: the default cluster's is auto-detected on the control-plane engine, and any other cluster runs one on its manager node, driven over the agent tunnel. It is opt-in: a plain single-node install behaves exactly as it did before, and nothing in the console asks you to think about Swarm.

A cluster other than the default one only takes and releases empty nodes, so its workspace networks are overlays from the start. Deploys are rationed per cluster, so a slow region cannot hold every worker slot.

Growing is not a migration

Nodes, clusters and workspace_id scoping exist from the first install, so going from one node to many, or from one cluster to several, adds rows — it never rewrites what is already there.

Technology stack

LayerChoice
BackendGo, Okapi framework, REST + OpenAPI
ORM / DBGORM over PostgreSQL
Cache / queueRedis — cache, rate limiting, asynq queue, analytics stream
Schedulerrobfig/cron via a cron manager
RuntimeDocker Engine via the Moby Go client (github.com/moby/moby/client); Docker Swarm opt-in per cluster
Reverse proxy / TLSGoma Gateway (routing + ACME); managed DNS-01 certs via go-acme/lego
Object storageS3 (aws-sdk-go-v2) or filesystem
Metrics / loggingPrometheus client · jkaninda/logger
FrontendVue 3 + Pinia + Vite + TypeScript, embedded in the binary