Nimbusv1.0.0

Server Groups

Configure server groups in Nimbus — group types, scaling, lifecycle, templates, software updates, and runtime type changes.

Groups are the building blocks of a Nimbus network. Each group defines a type of server -- its software, version, resources, scaling rules, and lifecycle behavior. Services (running instances) are created from groups.

Group types

STATIC groups

Static groups create persistent services that keep their data between restarts.

  • The template is applied only on first creation
  • Server files (worlds, configs, plugins) persist in services/static/<ServiceName>/
  • Ideal for: proxies, lobbies, survival servers, build servers
Configuration
[group]
name = "Lobby"
type = "STATIC"
software = "PAPER"
version = "1.21.4"

DYNAMIC groups

Dynamic groups create ephemeral services that start fresh every time.

  • A clean copy of the template is made on every start
  • Instance files are stored in services/temp/<ServiceName>/ and cleaned on stop
  • Instance count is managed by the scaling engine
  • Ideal for: minigames, game servers, event servers
config/groups/bedwars.toml
[group]
name = "BedWars"
type = "DYNAMIC"
software = "PAPER"
version = "1.21.4"

You can convert between static and dynamic at runtime using the static and dynamic console commands. See Runtime type changes below.

Creating groups

Interactive command

The create console command walks you through group creation:

Output
nimbus> create

It prompts for name, software, version, type, memory, and scaling parameters, then generates the TOML file.

Manual TOML file

Create a file in the config/groups/ directory named after your group (lowercase):

Output
config/groups/bedwars.toml

Full example:

config/groups/bedwars.toml
[group]
name = "BedWars"
type = "DYNAMIC"
software = "PAPER"
version = "1.21.4"

[group.resources]
memory = "2G"
max_players = 16

[group.scaling]
min_instances = 2
max_instances = 10
players_per_instance = 16
scale_threshold = 0.8
idle_timeout = 300

[group.lifecycle]
stop_on_empty = false
restart_on_crash = true
max_restarts = 5

[group.jvm]
optimize = true

Via REST API

Terminal
# Create a group via the API
curl -X POST http://127.0.0.1:8080/api/groups \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "SkyWars",
    "type": "DYNAMIC",
    "software": "PAPER",
    "version": "1.21.4"
  }'

Naming conventions

ElementConventionExample
Group namesPascalCaseBedWars, Lobby, Proxy
Service names<GroupName>-<N>BedWars-1, Lobby-2, Proxy-1
Config fileslowercase.tomlbedwars.toml, lobby.toml

Service names are auto-generated. The number is the next available integer for that group.

Configuration reference

Software

ValueDescription
PAPERPaper server (most common)
PUFFERFISHPufferfish server (Paper fork, optimized for high player counts)
PURPURPurpur server (Paper fork with extra features)
LEAFLeaf server (Paper fork, performance + stability balance, 1.21.4+)
FOLIAFolia server (Paper fork with regionized multithreading, 1.19.4+)
VELOCITYVelocity proxy
FORGEForge modded server
FABRICFabric modded server (optionally with Cardboard for plugin support)
NEOFORGENeoForge modded server
CUSTOMCustom server JAR (requires jar_name)

For CUSTOM software, set the jar_name field:

Configuration
[group]
name = "CustomServer"
software = "CUSTOM"
jar_name = "server.jar"

Resources

Configuration
[group.resources]
memory = "2G"          # JVM heap size (-Xmx)
max_players = 50       # Server max player slots

Scaling

config/groups/<group>.toml
[group.scaling]
min_instances = 1          # Always keep at least this many running
max_instances = 4          # Never exceed this many instances
players_per_instance = 40  # Expected capacity per instance
scale_threshold = 0.8      # Scale up when fill rate exceeds 80%
idle_timeout = 0           # Seconds before stopping an empty instance (0 = never)

See Auto-Scaling Guide for a detailed explanation.

Lifecycle

config/groups/<group>.toml
[group.lifecycle]
stop_on_empty = false      # Stop the service when all players leave
restart_on_crash = true    # Auto-restart if the process crashes
max_restarts = 5           # Max consecutive restart attempts before giving up
deploy_on_stop = false     # Copy changed files back into the template on stop
deploy_excludes = ["logs/", "crash-reports/", "cache/", "libraries/", "*.tmp"]

stop_on_empty is different from idle_timeout. stop_on_empty triggers immediately when the last player leaves. idle_timeout waits for the specified number of seconds after the server becomes empty.

Deploy-back workflow

deploy_on_stop = true is designed for the "edit a running DYNAMIC service, then persist the changes into the template" pattern — useful for iterating on configs or plugins without hand-copying files. On graceful stop, Nimbus diffs the service directory against the template and copies back only files that differ (skipping anything matched by deploy_excludes). If the copy-back fails, the service is moved to CRASHED with a descriptive error instead of silently losing data.

Avoid enabling this for servers that write large, rapidly-changing state (worlds, player data) — use STATIC services or [group.sync] for those instead. Deploy-back is meant for configuration drift, not world persistence.

JVM & Performance

Configuration
[group.jvm]
optimize = true    # Aikar's flags + config tuning (default)

When optimize = true (default), Nimbus automatically applies Aikar's JVM flags and optimizes server configs for best performance. Set custom args to override the JVM flags, or optimize = false to disable all auto-optimization. Memory (-Xmx/-Xms) is set automatically from resources.memory.

Advanced fields

FieldDescription
templateTemplate directory name (defaults to group name)
modloader_versionModloader version for Forge/Fabric/NeoForge
jar_nameCustom JAR filename (for CUSTOM software)
ready_patternCustom regex to detect when the server is ready
java_pathPath to a specific Java binary

Port allocation

Nimbus automatically assigns ports to services:

TypePort range
Proxy25565, 25566, 25567, ...
Backend30000, 30001, 30002, ...

You never need to configure ports manually. The PortAllocator tracks used ports and assigns the next available one.

Templates

Each group has a template directory under templates/:

Output
templates/
  Lobby/           # Template for the Lobby group
    plugins/
    server.properties
  BedWars/         # Template for the BedWars group
    plugins/
    bukkit.yml
  global/          # Applied to ALL backend servers (user-owned)
    plugins/
      # your own shared plugins go here
  global_proxy/    # Applied to ALL proxy servers (user-owned)
    plugins/
      # your own shared proxy plugins go here
  • Group templates are copied to new service instances
  • global/ contents are overlaid onto every backend service
  • global_proxy/ contents are overlaid onto every proxy service
  • For static groups, the template is only applied on first creation
  • For dynamic groups, a fresh copy is made every time

Nimbus-managed plugins (SDK, Bridge, and module companion plugins — Perms, Display, Punishments, Resource Packs, …) are not stored in templates/. They are deployed on every service prepare with REPLACE_EXISTING, so deleted or modified copies self-heal on the next start. Templates stay user-owned.

Hot-reload

The reload command re-reads all group configs without restarting Nimbus:

Nimbus
nimbus> reload

This picks up:

  • New group files added to config/groups/
  • Changes to existing group configurations
  • Updated permission and display configs

Removing a group file while services are still running does not stop those services. They continue running but are flagged as orphaned until the next restart.

Import modpacks

The import command lets you import a Modrinth modpack as a new server group:

Output
nimbus> import adrenaserver
nimbus> import https://modrinth.com/modpack/cobblemon
nimbus> import /path/to/modpack.mrpack

It downloads the modpack, installs the modloader and mods, and walks you through group configuration.

Updating software & versions

The update command lets you change a group's Minecraft version or server software without recreating it. Nimbus handles the JAR download, config update, and reload automatically.

Update the Minecraft version

Nimbus
nimbus> update Lobby version 1.21.5

For modded servers (Forge, NeoForge, Fabric), Nimbus also resolves the latest matching modloader version automatically.

Switch server software

Output
nimbus> update Lobby software purpur

You can also switch software and version at the same time:

Output
nimbus> update Lobby software purpur 1.21.5

Interactive mode

Run update <group> without arguments for an interactive wizard that shows available versions and compatible software options:

Output
nimbus> update Lobby

Compatibility rules

Not all software switches are allowed. Nimbus groups software into families and only allows switches within compatible families:

FamilySoftwareCan switch to
Plugin serversPaper, Purpur, LeafEach other
Forge familyForge, NeoForgeEach other (with warning)
FabricFabricVersion changes only
ProxyVelocityVersion changes only
CustomCustomVersion changes only

Switching between families (e.g., Paper → Forge, Forge → Fabric) is blocked because plugins and mods are fundamentally incompatible. Create a new group instead.

After updating, restart running services to apply the changes: restart Lobby-1

Runtime type changes

Convert a dynamic group to static (preserves instance data):

Output
nimbus> static group BedWars

Convert a static group to dynamic (future instances will be ephemeral):

Output
nimbus> dynamic BedWars

You can also convert an individual running service to static:

Nimbus
nimbus> static service BedWars-1

Service lifecycle states

Every service goes through these states:

StateDescription
PREPARINGTemplate is being copied to the service directory
STARTINGJVM process started, waiting for the ready pattern
READYServer is accepting players
STOPPINGGraceful shutdown in progress
STOPPEDClean shutdown complete
CRASHEDProcess exited unexpectedly

The ready detection watches stdout for a "Done" pattern (e.g., Done (12.345s)!). You can override this with the ready_pattern field for custom server software.

Shutdown order

When Nimbus shuts down (via shutdown command or SIGTERM), services stop in a specific order:

  1. Game servers (dynamic groups) -- stop first to evacuate players
  2. Lobbies (static backend groups) -- stop next
  3. Proxies -- stop last to maintain connectivity as long as possible

Next steps