universe docs source
browse docs
docs /configuration /node-config

Node configuration

config.json sets a node identity, its place in the Hazelcast cluster, and the single flag (isMasterNode) that decides whether it runs the REST API as a Master or joins as a task-executing Wrapper.

Universe reads ./config.json from its working directory at startup. The file is generated on first run with sensible single-machine defaults, then you edit it and restart. It holds three things: who this node is on the cluster, where the Master lives, and the resource ceiling the node is willing to give to running instances. Both node roles boot from the same fat JAR, so this file is the only thing that distinguishes a Master from a Wrapper.

Field reference

FieldTypeDefaultDescription
addressstring127.0.0.1IP this node advertises to the Hazelcast cluster. Also the default for bindAddress and publicAddress.
portint6000Hazelcast member communication port. Every node opens this for cluster traffic.
apiPortint7000Ktor REST API port. Bound only when isMasterNode: true; ignored on Wrappers.
nodeIdstringnode-1Unique node identifier. Used in instance assignment, template sync targeting, and logs.
clusterNamestringuniverse-clusterHazelcast group name. Every member of one cluster must share this exact value.
isMasterNodebooleantrueRole selector. true starts the REST API and InstanceCountEnforcer; false joins as a Wrapper.
masterAddressstring127.0.0.1Hostname or IP of the Master, used by Wrappers to find and join the cluster.
masterPortint6000Hazelcast port on the Master.
masterApiPortint7000REST API port on the Master, surfaced to clients such as Minecraft plugins as the %MASTER_API_PORT% variable.
maxRamMBint8192Memory ceiling, in megabytes, that this node will commit across all instances it hosts.
maxCpuint400CPU ceiling in units, where 100 equals one physical core.
bindAddressstring= addressSocket bind address. Set to 0.0.0.0 in containers so the member listens on every interface.
publicAddressstring= addressAddress advertised to other cluster members when it differs from the bind address (NAT, Docker).
nodeSpecificVariablesobject{}Key/value pairs exposed to templates on this node. Resolved as %KEY% placeholders during deploy.
updateSourcesarray[]Auto-update definitions that fetch remote files into the working tree on an interval.
debugbooleanfalsetrue enables DEBUG console and INFO framework logging; otherwise WARN and above only.
i
note

The apiPort, masterApiPort, and resource caps all have working defaults. A fresh single-machine install only needs you to confirm isMasterNode and, on a Wrapper, point masterAddress at the Master.

Master and Wrapper roles

isMasterNode is the one field that changes behaviour at startup. A Master owns all authoritative state and is the only node that binds the REST API; a Wrapper owns nothing persistently and exists to execute tasks the Master dispatches over Hazelcast.

Master (isMasterNode: true)Wrapper (isMasterNode: false)
REST APIBound on apiPortNot bound; apiPort ignored
HazelcastForms the cluster on portJoins via masterAddress:masterPort
StateLoads configurations, runs InstanceCountEnforcerListens for tasks on IExecutorService
RuntimesCan also host instances locallyRegisters runtime providers and starts processes

A Master may point masterAddress and masterPort at itself, which is what the generated single-machine config does. A Wrapper must use the identical clusterName as the Master, otherwise Hazelcast treats it as a separate cluster and it silently fails to join.

A Master forms the cluster and serves the API. Note masterAddress points back at the node’s own address.

{
	"address": "10.0.0.10",
	"port": 6000,
	"apiPort": 7000,
	"nodeId": "master-1",
	"clusterName": "universe-cluster",
	"isMasterNode": true,
	"masterAddress": "10.0.0.10",
	"masterPort": 6000,
	"masterApiPort": 7000,
	"maxRamMB": 8192,
	"maxCpu": 400,
	"nodeSpecificVariables": { "region": "us-east-1" },
	"debug": false
}
!
warning

A mismatched clusterName is the most common reason a Wrapper never shows up in GET /api/cluster/nodes. The two nodes can reach each other on the network and still refuse to merge if the group names differ by a single character.

Binding inside containers

Inside Docker or any NAT environment the address a member binds to is not the address other members can reach it on. Split the two: bind to 0.0.0.0 so the socket listens on every interface, and advertise the routable host address through publicAddress.

{
	"address": "10.0.0.10",
	"bindAddress": "0.0.0.0",
	"publicAddress": "10.0.0.10",
	"isMasterNode": true
}

Auto-update sources

Each entry in updateSources polls a remote URL and writes the result into the working tree on an interval. This keeps a server JAR or shared asset current across the cluster without a manual redeploy. An optional hashUrl verifies the download before it replaces the existing file, and syncToStorage can push the fetched file into a configured storage provider.

Sub-fieldTypeDefaultDescription
urlstringrequiredRemote file to fetch.
targetPathstringrequiredDestination path relative to the working directory.
hashUrlstring · nullnullOptional checksum URL used to verify the download.
intervalMsint60000Polling interval in milliseconds.
enabledbooleantrueToggles the source without removing it.
syncToStoragestring · nullnullStorage provider key to upload the fetched file into.
{
	"updateSources": [
		{
			"url": "https://files.example.com/paper-1.21.jar",
			"targetPath": "templates/global/server/server.jar",
			"hashUrl": "https://files.example.com/paper-1.21.jar.sha256",
			"intervalMs": 60000,
			"enabled": true,
			"syncToStorage": null
		}
	]
}
tip

Changes to config.json apply on restart. Configuration files under ./configuration/ can be reloaded live with config reload or POST /api/node/reload, but node identity and role are read once at boot.