Skip to content

Fledge v0.6.1.1 "Roost" ​

A plugin system with one-click mod and plugin installation, plus autopilot (schedules, crash protection, notifications), template v2, quotas, passkeys and much more.

Highlights ​

  • Plugins. A sandboxed plugin system with a store, permission review, a settings wizard, signed community registries and rollback. Two plugins ship with Fledge: the Modrinth Mod Browser (Fabric, Quilt, Forge, NeoForge) and the Modrinth Plugin Browser (Paper, Purpur, Folia, Spigot).
  • Mods and Plugins tab on servers. Search Modrinth, review dependencies, install with a SHA-512 check done by the node, update, disable, pin and remove. A restart applies the change.
  • Autopilot. Schedules with cron, time zones and chained steps (command, wait, backup, power); automatic restart after crashes with crash-loop protection and exit details; a notification centre with Discord, Slack, webhook and email channels; CPU and memory history from one hour to 30 days.
  • Templates v2, quotas, ports, clone. Typed variables, versions and "update servers", import and export; per-customer quotas; extra ports; clone a server with or without its data.
  • Accounts and security. Passkeys, signed-in devices, email invitations and password reset, an administrator network allow-list, audit filters and export, an OpenAPI description with an in-panel API reference, security headers.
  • Stopping a booting Minecraft server works. A stop during first boot no longer ends in a kill (see Fixed).
  • A documentation site. https://kavaliersdelikt.github.io/fledge/, with a generated API reference.

Added ​

Plugins and add-ons ​

  • New Compose service plugins: runs plugin code in QuickJS compiled to WebAssembly. Read-only root, non-root user, all capabilities dropped, PID and memory limits, health check, its own network shared only with the API, no database credentials, no Docker socket, no published port.
  • Manifest, permissions (network:<host>, servers:read, servers:files.write, storage, hooks), typed settings (secrets encrypted), catalog contract, hooks (server.created, server.deleted, server.updated, addon.installed, addon.removed).
  • Trust tiers: bundled, verified (Ed25519 signature from a key you trust) and community (off until you allow it). Updates that ask for more permissions need approval. Rollback keeps the previous version and its settings. A plugin that fails five times in a row is switched off.
  • Limits per call: 25 s, 64 MB, 40 requests, 24 MB of responses, 2 MB result. Outbound requests: HTTPS only, declared hosts only, public addresses only, pinned to the checked address, redirects re-checked.
  • Add-ons: template rules decide which servers get a tab; plans resolve required and optional dependencies; the node performs file.fetch (SHA-512 required, allowed hosts, public addresses, size counted against the disk allowance, atomic placement), file.delete and file.rename. Needs agent 0.6.1.1.
  • plugins/tools/pack.mjs builds, signs, indexes and verifies .fledgeplugin packages. The default registry index lives in plugins/registry/index.json.

Automation and notifications ​

  • Schedules v2 run on a persistent engine with leases and a unique running run per schedule; missed runs are skipped or run once; history is kept for 30 days.
  • Crash policy (off, on-failure, always), growing back-off, crash-loop protection, exit code, out-of-memory flag and log tail (agent 0.6.1.1).
  • Notification inbox and channels (Discord, Slack, any webhook, email), per event and server, with de-duplication; customers get their own inbox and channels for their servers.
  • Metrics history (one-minute, five-minute and hourly buckets), more Prometheus metrics.

Templates, servers and customers ​

  • Template v2: typed variables, versions, outdated-server detection and apply, export and import, the Startup panel.
  • Quotas on servers, memory, CPU, disk, backups and extra ports. Extra ports (up to 20 per server, allocated next to the base port). Clone with or without data.

Accounts and security ​

  • Passkeys as a second factor, signed-in devices with sign-out, email invitations and password reset (SMTP, optional), administrator IP allow-list with a lock-out guard and ADMIN_IP_ALLOW_DISABLE, audit filters and CSV/JSON export with retention, GET /api/openapi.json, Content-Security-Policy and frame protection headers.

Infrastructure and docs ​

  • The installers and updaters (shell and PowerShell) build and check the plugin host (a problem there only warns) and require Docker Compose 2.20 or newer.
  • CI gained plugin host, plugin, template, autopilot, account, update-flow and documentation jobs plus a Compose job. The release workflow packages the bundled plugins, writes SBOMs from an unprivileged job and signs checksums on a best-effort basis.
  • A VitePress documentation site published to GitHub Pages; the READMEs became short pointers.

Changed ​

  • Customers still never receive start commands or template-level environment values; the Startup panel shows owners the image and the variables they may edit.
  • Schedules are processed by a persistent run engine: runs are claimed with a lease, a schedule never has two runs at once and a due run that finds the previous one still running is recorded as skipped.
  • Recreating a container (extra ports, template apply, variable changes) no longer boots a server that is stopped: it is recreated and stopped again. Suspended servers are refused.
  • TRUST_PROXY takes a hop count or a list of proxy addresses (true still trusts every hop) and is passed through Compose.
  • Second-factor attempts are limited per account; a password reset also revokes the account's API tokens.
  • Template and plugin setting patterns are matched with a time limit; plugins cannot be granted wildcards over shared hosting platforms.
  • Quota checks lock the customer inside the creating transaction.
  • PLUGIN_REGISTRY_URL= (empty) turns the registry off.
  • Minecraft containers are created with CREATE_CONSOLE_IN_PIPE=TRUE. Existing containers pick this up when they are next recreated.
  • Agent version 0.6.1.1.

Fixed ​

  • Stopping a Minecraft server that is still starting. The image's own fallback wrote to a pipe it cannot use ("bad file descriptor") and RCON is not available until the world has loaded, so a stop during first boot (for example while resizing the disk) ended in a kill. The agent now queues the stop on the console pipe as the game user, the server finishes starting, saves and exits with code 0. A bounded wait of three minutes applies before falling back to docker stop; without a pipe yet (first minutes of a brand-new container) it stops directly.
  • Disk resize failing with "e2fsck: ... is mounted". The unmount before a resize is now strict, retries and waits for the loop device to be released.
  • A crash notification could miss its exit information; it is now stored before the status changes.
  • Cross-origin downloads expose their file name; a removed add-on record no longer blocks reinstalling the same project after a failed install.
  • Dependency and code-scanning alerts: nodemailer updated, address checks no longer use backtracking-prone expressions, the plugin sandbox passes the method and arguments as data, and Markdown sanitising repeats until stable.

Verified ​

  • API integration suites (real PostgreSQL, real API and plugin host processes): plugins and the Modrinth flow (208 assertions against a mock shaped like the live API), plugin trust and hostile plugins (128), templates v2 (101), quotas, extra ports and clone (142), schedules, crash policy, notifications and metrics (about 240), sessions, SMTP flows, passkeys with a software authenticator, allow-list, audit export, OpenAPI, headers and backup quota (171), the original smoke test (about 216 to 235 assertions, varying slightly with timing), plus unit tests (15), CORS (3), Pterodactyl (4) and the pack tool (2).
  • Plugin host: 24 sandbox tests (isolation, limits, request and size rules, private addresses and redirects, hooks, storage, upstream-timeout classification).
  • Agent (Go, on Linux): the new file jobs, stop-during-boot logic, exit information.
  • Scripts: the real update.sh against a throw-away Git repository with mocked Docker; installer, connector and update-flow smoke tests; Compose 2.20 gate.
  • Real end to end: a Linux agent on WSL2 with Docker connected to a panel with the plugin host in its hardened container; Lithium (Fabric) and LuckPerms (Paper) installed from live Modrinth with matching SHA-512 and loaded by the servers; disable, enable and remove worked.
  • Stop during boot, on a real Paper server: RCON refused connections while the world loaded; mc-send-to-console stop as the game user queued the stop; the server finished starting, saved all worlds and exited with code 0.
  • Compose: the API, panel, plugin host and updater images built and the stack came up healthy with the plugin host reachable only from the API.
  • Panel in a browser: plugin store and wizard, mods tab with live results, install plan, schedule editor, settings, and the screenshots of the documentation.
  • 25 web helper tests; type check and production build of the panel.

Known limits ​

  • WebAssembly isolation reduces risk; it is not a formal guarantee. Fledge does not scan mod files: a checksum proves a file is the one a catalog named, not that it is safe. The registry ships without a built-in trusted key.
  • Add-ons need agents 0.6.1.1 or newer, apply after a server restart and only install .jar files; modpacks and datapacks are not supported.
  • The plugin interface covers catalogs and event hooks. Custom plugin pages, plugin-defined notification channels and plugin routes are not available.
  • The plugin host runs plugin calls in one process, so a slow catalog can delay other plugin calls.
  • Not exercised in this release: the Compose job on a hosted runner, the PowerShell scripts end to end, passkeys with real browsers and security keys, the disk-resize fix on a real loop volume, the agent binary during a stop-while-booting run (its Docker commands were run for real and the logic is unit-tested), two live API replicas, release signing in GitHub Actions.
  • Schedules do not wait for a game to finish a command; a run interrupted by an API crash may repeat its current step. Crash protection reacts to container exits, not to hung games.
  • /api/metrics can only be read with an administrator session, which makes unattended scraping awkward.
  • Everything listed under earlier releases' known limits still applies (backup-based failover, volumes need root, no production security review).

Upgrading ​

Update from Updates in the panel or with update.sh / update.ps1. The database gains plugin, add-on, notification, schedule-run, passkey, metrics and other tables and columns automatically (additive; nothing is rewritten). Then:

  1. Update node agents to 0.6.1.1 from Nodes (add-ons, the console-pipe stop and exit reporting need it). Older agents keep working for everything else; the Mods/Plugins tab says when a node is too old.
  2. The first update from 0.5.x builds and starts the new plugins service with its network and volume. Existing Minecraft servers get the console pipe the next time they are recreated.
  3. Crash protection is off for existing servers; customers have no quotas; email, passkeys, allow-lists and notification channels are empty until you set them up. Failover continues as before.
  4. Open Plugins to install the Modrinth browsers. Nothing is installed or enabled automatically.
  5. Optional .env settings (see .env.example): PLUGIN_REGISTRY_URL, SMTP_*, WEBAUTHN_*, ADMIN_IP_ALLOW_DISABLE, and TRUST_PROXY (set it to 1 behind one reverse proxy so rate limits and the allow-list see real client addresses).
  6. Docker Compose 2.20 or newer is required.

Released under the AGPL-3.0-only license.