Fledge v0.7.1.1 "Rookery"
The Hosting Update. Fledge becomes a panel a hosting business can run: people sign up, create or buy servers, pay by the month or year, and manage them, while you stay in control of limits, abuse, money and email. Everything is off by default: after upgrading, a panel behaves exactly as before until you switch something on.
A rookery is where many birds nest: a place that hosts others.
Highlights
- Sign-up. Open, with approval, or invite-only, with email confirmation, bot protection (Cloudflare Turnstile or hCaptcha), disposable-address and common-password checks, rate limits that pause sign-up during a flood, terms acceptance, email change, data download and account deletion.
- Customers create servers themselves from templates you release, within their limits, with a cooling-off period when they delete one.
- Limits v2. Layered (panel defaults, plans, per-customer overrides), explained (every number says where it comes from), with a master switch, a warn-only mode and many more things to limit.
- Plans, subscriptions and a store. Sell preset servers or allowances monthly, quarterly, half-yearly or yearly, with trials, setup fees, stock and free tiers. Late payments stop servers instead of deleting them.
- Stripe, included. A bundled payment plugin using hosted Checkout and the Customer Portal. Card details never reach Fledge. Verified against Stripe's real test mode.
- Email you can edit. Every email is a template with a live preview, sent through a retrying outbox with a delivery log, plus receipts, reminders and security notices.
Added
Sign-up (Settings, Sign-up)
- Modes: off (default), open, with approval, invite-only. Everyone becomes a customer; the role cannot be chosen by the request.
- A confirmation link (24 hours, single use) before anything can be created. Answers never reveal whether an address has an account; an existing address gets an email saying so.
- Rate limits per network address (5 an hour), per email (3 a day) and overall (200 an hour, then sign-up pauses itself and you are notified). Only attempts that pass every check count, so a typo never locks anyone out.
- Passwords of 12 to 128 characters (your minimum), refusing common passwords, repeating patterns, sequences and the email address; a built-in list of throw-away mailbox providers; allowed and blocked domains; a hidden form field and form timing as quiet bot traps.
- Optional Cloudflare Turnstile or hCaptcha (the content security policy allows those two providers' scripts and frames, and nothing else, on the sign-up form).
- Terms: required or not, with a version, a time and a hashed network address recorded; invitation codes (single or multiple use, optionally for one address, optionally carrying a starting plan); a free starting plan for every new account.
- Customers: change their email (new address confirmed, old address told), download their data (JSON), delete their account (password, no servers or active subscriptions, a waiting time, then anonymised; invoices stay without personal data).
- Administrators: a Waiting for you card in Customers (resend, mark confirmed, approve, decline); unconfirmed accounts are deleted after 7 days.
Customers creating servers (Settings, Customers creating servers)
- Off, plans only, or free choice within limits. Templates are invisible to customers until released (with a description). Locations can be restricted. Ten creations an hour per customer.
- One shared placement path for administrators, customers and the store, with the limit check in the same transaction. Customers get a plain "no capacity" message, never node details.
- Owners can delete their own servers (if allowed): stopped and kept for 24 hours (changeable) with one-click restore; a backup is taken first when backups are on. Servers that belong to a subscription are removed by ending the subscription.
Limits v2 (Settings, Limits)
- New limits: servers running at once, per-server memory, CPU and disk, backups per server, backup storage, people a server is shared with, scheduled tasks per server, allowed templates and locations, and yes/no permissions (create and delete servers, SFTP, add-ons, schedules, sharing, extra ports).
- Three layers with defined rules (totals add up, maxima take the most generous layer, a yes wins, a hand-set value always wins). A pure, table-tested resolver; the customer's page and the usage view show the source of every number.
- Master switch (on after an upgrade, so existing quotas keep working), enforce or warn mode, administrator override choice, warning threshold, customer notifications, hiding usage from customers. Lowering a limit never deletes anything.
- Checked when creating (administrator, customer, store), resizing, cloning, starting, backing up, adding ports, sharing, scheduling, using SFTP and installing add-ons.
- The names
maxServers,maxMemoryMb,maxCpuPercent,maxDiskMb,maxBackupsandmaxExtraPortsare unchanged in the API.
Plans, the store and billing
- Plans (Billing, Plans): server plans (one server per subscription, from a preset) and account plans (an allowance added to limits). Prices for four intervals, trials (once per customer), one-time setup fees, stock, per-customer maximum, visibility (everyone, link only, nobody), badges, highlights, retention, duplicate, archive. Prices are whole cents and are never edited in place: a change creates a new price and existing subscribers keep theirs.
- The store, closed by default and refusing to open until a provider answers, email works, a plan exists, terms are set and test and live records are not mixed. Checkout reads the amount, currency and trial from the database and freezes them on an order; the browser only names a plan and an interval. Stock is counted under a lock, so two buyers cannot take the last one. A plan whose server fits on no node is shown as sold out and cannot be bought.
- Subscriptions with a fixed table of allowed status changes, locked and recorded in a timeline: starting, trial, active, payment overdue, suspended, ended, removed. A late payment is emailed, then (after your days) the server is stopped and held, not deleted; paying lifts only a hold billing placed. Cancel at period end, resume, change plan (provider-prorated, server resized; upgrades at once), complimentary plans with an end date, holds, refunds, disputes (stop the server until resolved), retention, optional automatic termination (off by default, with a last backup first).
- Paid but no room? The subscription stays active, the customer is told, administrators are notified, Fledge retries for 24 hours and you can retry or refund and cancel.
- Reliability. Webhooks are stored once (unique per provider event), acknowledged, and processed in the background with retries; every event is turned into "ask the provider what is true now", so duplicates, delays and reordering are harmless. Events that arrive before their checkout is processed wait and retry. A scheduled comparison with the provider (every 15 minutes) repairs anything a missed event left behind. Fulfilment is guarded by a lock and a unique constraint, so one subscription can never get two servers.
- Billing pages: Overview (recurring revenue, paid this month, trials, overdue, cancellations, readiness checklist), Plans, Subscriptions (detail, timeline, actions), Invoices (CSV), Health (provider, mode, webhook address, events). Customers get Store and Billing pages.
- Billing settings: provider, currencies, reminder days, suspension and termination days, retention, final backup, what customers may do, renewal and trial reminders, stock holding, retry window, comparison interval, and what to do when a paid server can never be created.
Payments
- A payments contract for plugins (
paymentsin the manifest and permission, nine methods; see the payments contract) and the bundled Stripe Payments plugin: Checkout in subscription mode with inline prices (nothing to sync), trials, setup fees, automatic tax, promotion codes, the Customer Portal, plan changes with proration, refunds, signed webhooks with a five-minute window, the pinned API version2024-06-20, a product tax code setting. It can reach onlyapi.stripe.com. - Plugin host:
host.crypto(hmacSha256,sha256,equals,randomHex),host.now()andDELETErequests.
Email
- Editable templates for every email (35 of them, in Account, Billing, Limits, Administrators and System), with variable lists, conditional blocks, buttons, escaping, a linter (unknown variables, unclosed blocks, missing links), live preview and test send.
- An outbox: immediate delivery, retries with growing pauses (a minute to six hours, 8 attempts), a per-minute send rate, a delivery log (30 days, message text removed after 7), manual retry. Reply-To, a copy address for receipts and billing alerts.
- HTML emails in a clean layout that follows Appearance (name or wide logo, light-theme button colour, company footer).
- Security notices when a password or an email address changes.
Documentation, tests, tools
- New guides: Sign-up, Customers creating servers, Limits, Plans, The store, Billing, Email templates, The Stripe plugin, The payments contract, Going live, Recovering from billing problems and a generated email-template reference.
- A local Stripe stand-in (
api/test/stripe-mock.mjs) that signs its webhooks like Stripe, andapi/test/stripe-live.mjs, which drives the real Stripe test mode through the Stripe CLI without reading your API key.
Changed
- Server-written mail now uses templates: invitations, password resets and the test email look different (same facts). Mail is sent immediately and retried instead of failing the request.
- A server's suspension has a reason (
admin,billing,owner-deleted,billing-terminated); administrator suspensions are never lifted by a payment. The server shape addspendingDeleteAt,subscriptionId,suspendedReasonandcreatedVia. - Sidebar: customers see Store and Billing only when they apply; administrators see Billing once a provider, a plan or the store exists. Both pages can be renamed in Appearance (thirteen renameable pages now).
- The content security policy allows two bot-protection providers' scripts and frames (Turnstile, hCaptcha); everything else is unchanged.
- Pattern checks for template and plugin settings allow 300 ms instead of 100 ms, so a busy machine cannot make a good pattern fail.
- Version 0.7.1.1 for the API, panel, plugin host and tools. The agent has no functional change; release builds stamp it with the tag.
Fixed
- A good plugin-setting pattern could be rejected as "invalid format" on a busy machine (see Changed).
Verified
- Unit tests (
test:rookery, 8 groups): the limits resolver across every layer rule, what a change would break, legacy limit names, settings defaults and validators, email filling, escaping and linting for all 35 templates, money maths (integers, formats, intervals), the subscription transition table and the late-payment schedule. Plugin host: 25 tests includinghost.crypto. - End to end against real PostgreSQL, real API and plugin host processes:
test:rookery: sign-up in every mode, confirmation, enumeration resistance, rate limits and flood pause, bot check, domain rules, invitations, email change, export and deletion, email templates and outbox retry, self-service servers, layered limits in enforce, warn and off, owner deletion.test:billing: plugin install and keys, plans and immutable prices, store readiness, checkout (server-side prices, idempotency, stock races), forged, replayed, duplicated and unrelated webhooks, fulfilment, receipts, renewals, dunning, suspension, billing holds versus administrator suspension, cancel and resume, retention and termination, trials, setup fees, plan changes, account plans in limits, free and complimentary plans, failed fulfilment and retry, reconciliation, disputes, refunds.
- Against the real Stripe API in test mode (
stripe-live.mjs, through the Stripe CLI): connection and mode detection, a real Checkout Session (price from the database, order id attached), an expired session, a real subscription on a test clock read and synced, fulfilment, invoices, a renewal, a failed renewal, payment of the open invoice, cancel and resume at Stripe, a prorated plan change, a partial refund, the customer portal, and the end of a cancelled subscription, all through real, signed webhooks. This found two things fixed before release: Stripe's product tax code and Managed Payments defaults. - Regression: every earlier suite still passes (see the counts in the test output of CI). The default panel is unchanged until a feature is switched on; an upgrade from a 0.6.2.1 database keeps users, quotas and templates intact.
- Browser (Chrome): sign-up, store, buy dialog, billing, plan editor, subscriptions, health, settings, email templates, customer limits, the create-server drawer, on desktop and phone widths, with no console errors.
Known limits
- One payment provider (Stripe). Fledge does not calculate tax, issue its own invoices or decide consumer-law questions; those are the provider's features and your responsibility.
- No usage-based billing, prepaid credit, add-ons sold on top of a plan, reseller or affiliate features, or per-customer custom prices.
- The checkout payment itself happens on Stripe's page and is not driven by the automated tests; use the documented test cards.
- Sign-up verification is by email only. The disposable-address list is built in and not exhaustive.
- Email is SMTP only (no DKIM signing or provider APIs); templates are English only.
- Stripe's Managed Payments is switched off for Fledge checkouts (it needs newer API versions than the pinned one).
- Not exercised in this release: real customers and real money, Safari and Firefox, a screen reader on the new screens, the Compose job on a hosted runner.
- Everything under earlier releases' known limits still applies.
Upgrading
Update from Updates or with update.sh / update.ps1. The database gains tables and columns automatically (additive; nothing is rewritten). Then:
- Nothing changes until you switch something on. Sign-up, self-service, the store and plans are off; limits stay on with an empty default layer, so existing customer quotas keep enforcing exactly as before.
- To sell: install the Stripe plugin (Plugins), enter test keys, add the webhook, choose it in Settings, Billing, create a plan and follow Going live.
- Review Settings, Email: the new reply-to, copy address and retry settings have safe defaults.
- Optional: release templates to customers (Settings, Customers creating servers) before turning self-service on; nothing is released by default.
- Node agents report 0.7.1.1 after their next update; there is no functional change, so there is no need to hurry.
- Docker Compose 2.20 or newer is still required.
