Quickstart (10 min)
You have a Controller running and at least one Daemon connected
(Installation). This page takes you from an
empty cluster to a running Paper Instance, then scales, drains, and deletes it.
Every command below is a real prexorctl command verified against the CLI
source.
Before you start
- Controller reachable (default
http://localhost:8080). - At least one Daemon
ONLINEinprexorctl node list. - A catalog entry for the Paper version you want (the Controller ships a default catalog; see Step 2).
- About 1 GB free RAM on the Daemon host for a Paper Instance.
prexorctl gates every cluster command until it has a controller context. Before
you log in, only setup, login, logout, version, help, completion,
context, and cluster work; anything else prints:
no cluster connected — run 'prexorctl setup' to install a component, or 'prexorctl login' to link this CLI to an existing controllerStep 1 — Log in
prexorctl login opens a form for the Controller URL, username, and password.
If a context already has the URL, only username and password are asked.
prexorctl loginSign in to PrexorCloudEnter your controller URL and credentials below.
Controller URL http://localhost:8080Username adminPassword ••••••••
✓ Logged in to http://localhost:8080 as adminThe CLI POSTs to /api/v1/auth/login, stores the returned bearer token in the
active context, and saves the config. Confirm the cluster:
prexorctl statusPrexorCloud v1.1.0 • cluster localhost:8080 • logged in as (authenticated)
CLUSTER NODES INSTANCES● HEALTHY 0 groups 0 players 1 online 0 running
LIVE METRICS …GROUPS (none)If status errors with not authenticated, your token is missing — rerun
prexorctl login. You can also point a single command at a different cluster
with --controller <url> / --token <token>, or --context <name>.
Step 2 — Confirm a platform version in the catalog
The catalog maps a platform + version to a download URL and an optional
sha256. A Group provisions its server JAR from a catalog version, so the
version you name in Step 3 must exist in the catalog.
There is no prexorctl catalog subcommand. The catalog lives behind REST at
/api/v1/catalog. List it with the bearer token from your saved context:
curl -s -H "Authorization: Bearer $TOKEN" \ http://localhost:8080/api/v1/catalog | jq '.[] | {platform, version, recommended}'{ "platform": "PAPER", "version": "1.21.4", "recommended": true }{ "platform": "PAPER", "version": "1.21.1", "recommended": false }{ "platform": "VELOCITY", "version": "3.4.0", "recommended": true }Each entry is a CatalogEntry: platform, category (SERVER or PROXY),
configFormat, version, downloadUrl, sha256, recommended. Platform
names are upper-cased by the Controller (PAPER, VELOCITY, FOLIA,
FABRIC, NEOFORGE, BUNGEECORD, GEYSER).
Adding a version is also REST-only and needs the CATALOG_MANAGE permission:
curl -s -X POST -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"version":"1.21.4","downloadUrl":"https://.../paper-1.21.4.jar","sha256":"…"}' \ http://localhost:8080/api/v1/catalog/paper/versionsPick a recommended Paper version. This guide uses 1.21.4.
Step 3 — Create a group
A Group is a scalable set of Instances that share one configuration: platform, version, templates, scaling rules, port range, memory, env. It is the closest analog to a Kubernetes Deployment.
prexorctl group create \ --name survival-lobby \ --platform paper \ --platform-version 1.21.4 \ --min 1 \ --max 3 \ --memory 1024 \ --port-start 30000 \ --port-end 30100✓ Group 'survival-lobby' created--name and --platform are required. The other flags and their defaults
(from the CLI):
| Flag | Default | Maps to (GroupConfig) |
|---|---|---|
--name | — (required) | name — alphanumeric, hyphen, underscore, 1–64 chars |
--platform | — (required) | platform (upper-cased server-side) |
--platform-version | "" | platformVersion — must match a catalog entry |
--template | none | templates (ordered layers; repeatable) |
--scaling-mode | DYNAMIC | scalingMode — STATIC, DYNAMIC, or MANUAL |
--min | 1 | minInstances |
--max | 10 | maxInstances |
--memory | 1024 | memoryMb (MB per Instance) |
--routing | LOWEST_PLAYERS | routing strategy |
--port-start | 30000 | port range start |
--port-end | 30100 | port range end |
The CLI POSTs to /api/v1/groups. jarFile defaults to server.jar. The
Controller writes the GroupConfig, persists it, and registers it with the
scheduler. Unset GroupConfig fields fall back to record defaults —
maxPlayers 100, scaleUpThreshold 0.8, startupTimeoutSeconds 120,
shutdownGraceSeconds 30, updateStrategy ROLLING.
Scaling modes
The mode you pick decides who controls the Instance count:
STATIC— the scheduler holds the Group atminInstances. Use this for a fixed lobby.DYNAMIC— the scheduler scales betweenminInstancesandmaxInstanceson load (scaleUpThreshold,scaleDownAfterSeconds,scaleCooldownSeconds). Default.MANUAL— the scheduler holds the current count; you add Instances withinstance start.
For a single predictable lobby, STATIC with --min 1 is the simplest choice:
prexorctl group create --name survival-lobby --platform paper \ --platform-version 1.21.4 --scaling-mode STATIC --min 1 --max 1 --memory 1024Step 4 — Watch the instance come up
The scheduler evaluates on a fixed tick — scheduler.evaluationIntervalSeconds,
default 15s. Within one tick it sees the Group below minInstances and
places an Instance. Watch the Group:
prexorctl group info survival-lobbyThis opens an interactive view: config, scaling, templates, recent events, and
the Instance table. Press ↵ on an Instance to attach its console, d to
drain (graceful stop), r to restart (force-stop; the scheduler respawns it).
Prefer a flat list? Use the Instance table directly:
prexorctl instance list --group survival-lobbyID GROUP NODE STATE PORT PLAYERS UPTIMEsurvival-lobby-1 survival-lobby node-1 RUNNING 30000 0 4sAn Instance moves through these states (InstanceState):
| State | Meaning |
|---|---|
SCHEDULED | Placed on a node; Daemon not yet preparing |
PREPARING | Daemon materializing the template chain and JAR |
STARTING | JVM spawned, not yet ready |
RUNNING | Accepting players |
DRAINING | Still serving, no new players (graceful stop) |
STOPPING | Shutting down |
STOPPED | Clean terminal state |
CRASHED | Non-zero exit; recorded as a crash report |
What happens behind the table:
- The scheduler notices
survival-lobbyis belowminand picks a node. - It sends a start frame to the Daemon over gRPC.
- The Daemon materializes the template chain, layers the Paper JAR resolved from the catalog, and spawns the JVM.
- The bundled cloud-plugin boots and the Instance reports
RUNNING.
To watch Controller activity while it schedules, tail logs in a second terminal:
prexorctl logs controller --follow(prexorctl logs --follow with no subcommand tails the Controller too.)
Step 5 — Connect a Minecraft client
Find the Instance’s node and port:
prexorctl instance info survival-lobby-1survival-lobby-1 ● RUNNING group survival-lobby • node node-1Started at 2026-06-07T… — uptime 1m4s
INSTANCE port 30000 players 0 memory 1024 MB uptime 1m4sConnect a Paper-compatible client to <node-ip>:30000. Get the node IP from
prexorctl node info node-1.
Need to run a server command? Send one without attaching:
prexorctl instance exec survival-lobby-1 say hello from prexorctlOr attach the live console (Ctrl-Q to detach; type to send commands):
prexorctl instance console survival-lobby-1For production, front the lobby with a Velocity proxy — see Your first network.
Step 6 — Scale, drain, delete
There is no group scale command. You change the desired count by updating the
Group’s bounds, or schedule one-off Instances directly.
Raise the ceiling (and floor, for STATIC):
prexorctl group update survival-lobby --max 3 --min 3✓ Group 'survival-lobby' updatedgroup update PATCHes only the flags you pass (--min, --max, --memory,
--routing, --scaling-mode); omitted fields are unchanged. The scheduler
reconciles to the new bounds on its next tick.
Schedule extra Instances on demand (1–50, clamped):
prexorctl instance start survival-lobby✓ 1 instance(s) scheduled in group survival-lobbyDrain one Instance — graceful stop:
prexorctl instance stop survival-lobby-2Force-kill immediately instead:
prexorctl instance stop survival-lobby-2 --forcePut the Group in maintenance (drains and stops new placement):
prexorctl group maintenance survival-lobby onprexorctl group maintenance survival-lobby offTear the Group down. This prompts for confirmation and stops every running Instance:
prexorctl group delete survival-lobbyDelete group 'survival-lobby'?This will stop all running instances in the group. This action cannot be undone.
✓ Group 'survival-lobby' deletedWhat can go wrong
| Symptom | Likely cause |
|---|---|
no cluster connected | No controller context. Run prexorctl login or pass --controller. |
not authenticated | Token missing or expired. Rerun prexorctl login. |
Instance stuck in SCHEDULED | No node has free capacity, or all nodes are DRAINING. Check prexorctl node list. |
Instance never leaves PREPARING | Template materialization or catalog JAR download failing on the Daemon. Check prexorctl logs daemon <node-id>. |
Group create rejected 400 | Invalid name (must be alphanumeric / - / _, 1–64 chars) or invalid config. |
Instance lands in CRASHED | Bad version or template. Inspect with prexorctl crash list --group survival-lobby then prexorctl crash info <id>. |
| Repeated crashes | The crash-loop detector trips at 3 crashes in 300s (defaults crashLoopThreshold / crashLoopWindowSeconds). Fix the cause, then start fresh Instances. |
Inspect a crash:
prexorctl crash list --group survival-lobbyprexorctl crash info <crash-id>crash info shows the exit code, classification, and the last log lines.
Next steps
- Core concepts — Controller, Daemon, Group, Instance, Template, Network, Module, Plugin.
- Your first network — proxy + lobby + game-mode, end to end.
- Groups, instances, and templates — the layered template chain and how to author your own.