Self-serve hosting: specification
Status: approved, 2026-11-10 (Kevin), with the decisions below; not built yet. It builds on what is decided and built: the hosting plans and their cost model (hosting-plans.md), the Auto plan's hard cap and degrade ladder, and the fleet that provisions sites on Fly.io (fleet.md). The open questions at the end need a decision before work starts.
The idea
WordPress.com sells hosting from the same site people learn about WordPress on: pick a plan, pay, and a site exists a minute later. Spillway has every piece behind that except the front door. The fleet already provisions a site end to end (app, volume, machine, setup, template, domain) when it is called, the plans are priced, and the Auto controller already keeps a month inside a customer's cap.
This spec adds the front door on spillwaycms.com:
- Start a site in a few clicks, with the account people already use for the registry.
- Deploy any theme or kit from its registry page, as the site's starting point.
- Your sites: one place to open each site's admin, see usage against the plan, change plan, manage domains, pay and leave.
Hosting is sold and run as Spillway (decided 2026-11-10): Spillway's storefront, Spillway's accounts, Spillway's Fly.io organization and Cloudflare account, Spillway on the invoice. Accorbis is a separate operation and platform, planned separately. Self-hosting stays first-class: the deploy buttons for Render and Railway, the Docker image and spillway export remain, and a hosted site can leave with its data at any time.
Principles
- Two minutes from "Start a site" to an admin you are signed in to.
- Every customer gets their own instance. Spillway's multisite shares users, content types and modules across the sites of one instance, which suits one organization, not strangers. Each hosted site is its own Fly app with its own volume and database, as the fleet provisions today.
- No bill surprise. Prices are published, usage is visible while it accrues, and nothing is billed above a number the customer set.
- Never hold data hostage. Export is a button on every plan, cancellation keeps the export available for 30 days, and moving to self-hosting (or back) is documented and tested.
Plans: fixed, usage or both
There are three ways to charge, and the decided plans already use two of them:
| Model | Good | Bad |
|---|---|---|
| Fixed plans with included usage (WordPress.com, Pantheon, the decided Site, Campus and Enterprise) | Predictable, easy to buy, easy to approve in a budget | Customers overpay at low use; what happens past the limits must still be decided |
| Pure usage (Fly, Vercel past their included amounts) | Fair, pay for what you use | Hard to predict; a traffic spike or an attack becomes a bill; finance departments dislike it |
| Plan plus overage up to a cap (recommended) | Predictable floor, fair growth, a ceiling the customer controls | One more setting to explain |
Recommendation: keep the decided plans and give every plan an overage budget.
- Each plan includes its allowances (bandwidth, media storage, AI credits), as decided.
- Usage beyond an allowance bills at published rates: bandwidth at the decided $0.10 per GB, storage and AI credits at rates set before launch.
- The customer sets an overage budget per site: $0 makes the plan price a hard cap, any other amount allows that much overage a month. The default is half the plan price (decided 2026-11-10: "50"; $24.50 on Site, $124.50 on Campus).
- When the budget is reached, the Auto controller's ladder takes over for the rest of the month: longer CDN caching, a smaller machine, sleeping between requests. The three rules of Auto hold: never delete data, never stop serving, never bill above the cap. Usage the ladder cannot avoid is Spillway's cost, as Auto already states.
- Emails and the dashboard warn at 50%, 80% and 100% of the allowance and of the budget.
The Auto plan stays as the budget-only option: no fixed allowance, the customer names the monthly maximum (at least $49) and the controller picks the stack.
A lower entry plan. At $49, the Site plan is the cheapest way in, while WordPress.com starts well below that, with a free plan and paid plans from a few dollars a month (third-party summaries of its 2026 prices disagree on the exact figures, so they should be checked on its own pricing page). Per-customer instances keep a low plan viable: the Site stack (shared-1x 512 MB that sleeps when idle, SQLite on the volume) costs $5.14 a month at its limits in ams (hosting-plans.md). A Starter plan on the same stack with tighter limits (for example 25 GB of bandwidth, 5 GB of media, sandboxed modules only, no staging, the platform subdomain plus one custom domain) could sell for $15 to $19 a month with a healthy margin. Price and limits are open questions.
Free tier: not at launch. A free site costs real money every month and attracts abuse (phishing pages, spam). A 14-day trial of Starter or Site, with a card on file and no charge until the trial ends, gives most of the benefit. A free tier can follow once abuse handling is proven.
The decided terms carry over: one price worldwide, pay 10 months get 12, 30% off for education and nonprofits, email support with priority support as an add-on, uptime credits on the published schedule, AI on Spillway's keys with fair use then credits.
What people see
Start a site
Start a site appears in the spillwaycms.com header and on the home page, and Deploy this theme or Deploy this kit on every theme and kit page in the registry.
- Sign in or create an account. The same account as the registry (email or GitHub). New accounts verify their email.
- Choose a starting point. Blank, a sector kit (higher education, city, nonprofit, intranet portal), a theme from the registry with its brand, or Move my site: the domain importer, given a URL, crawls the old site into drafts after provisioning.
- Name it. The site name and its address on the platform domain (
<name>.<platform domain>, checked for availability as you type; see The platform address). A custom domain can be added now or later. - Choose a plan. Starter, Site, Campus or Auto, monthly or yearly, with the allowances side by side and the overage budget (prefilled with the default). Enterprise is Talk to us. Education and nonprofit discounts apply after a short verification.
- Pay. Stripe Checkout with the trial when offered. Taxes are calculated there.
- Watch it build. A progress screen follows the fleet's events (creating, created, setting up, applying the template, domain added, ready), each with a plain sentence. A failure shows what failed and retries; the fleet's steps are already idempotent.
- Open your site. The admin opens signed in, on the onboarding checklist, with the site agent's Ask ready once it is built (site-agents.md).
Your sites
A Your sites page on spillwaycms.com, for anyone with a hosted site, and for the members of a registry organization that owns sites:
- A card per site: name, address, plan, status (building, ready, trial ends in N days, payment due, suspended), this month's usage against the allowance and the budget as bars, and the Spillway version.
- Open admin: a one-time sign-in link into the site's admin as its owner.
- Domains: add a custom domain, see the DNS records to create, watch verification and the certificate, choose the primary domain, redirect the others.
- Plan and usage: change plan (the fleet's plan change keeps data and retires extras without deleting them), set the overage budget, see the month's projection and the Auto steps applied, if any.
- Billing: the Stripe customer portal for cards, invoices, tax details and receipts.
- Team: who may manage the hosting (owners and billing contacts), separate from the site's own admin users.
- Export: a download of
spillway exportplus media, any time. - Cancel: the site stays reachable to the end of the paid period, then turns read-only with a notice for 30 days with the export available, then is deleted, with an email at each step.
Agencies get the same page for an organization: every client site, each on its own plan and invoice, or all on the agency's card.
On spillwaycms.com: accounts, pages and navigation
Hosting needs the public site to have what it does not have today: a way for anyone to create an account and sign in on the public site, and pages that sell, explain and manage hosting. Today the only sign-in is the CMS admin's (/admin/login), registry publishers get accounts through it, and public self-registration does not exist (GitHub sign-in creates accounts only where SSO is set up). Hosting customers must never land in spillwaycms.com's CMS admin, so this adds a public account area beside it.
Site accounts (a core feature)
Site accounts are people with an account on a site's public pages, not its CMS: hosting customers and registry publishers here; members, alumni or partners on other Spillway sites (the intranet portal kit wants the same thing). They are users with the new member role, which grants no admin permission, and they sign in on the public site.
- Pages, rendered by the site in its brand, on the public site rather than the admin:
/account/signup: name, email, password, and Continue with GitHub where GitHub sign-in is set up. Email verification by link before anything else; a CAPTCHA when the site has one (Site settings → Forms)./account/login,/account/logout,/account/forgotand/account/reset(the invite and reset tokens the admin already uses)./account: profile (name, email, password, connected GitHub, delete account), and the sections modules add.
- Header. Log in and a primary action (here Start a site) on the right of the header for visitors; the person's initial with a menu (Your sites, Account, Log out) once signed in. Driven by Site settings → Accounts (Let visitors create accounts, the header links, the primary action's label and target), off by default so other sites are unchanged.
- Separate sessions. The public account session is its own cookie, scoped to the site's public paths, with the same protections as the admin session (HttpOnly, SameSite, CSRF header on writes, rate limits on sign-in and reset). Signing in on the public site never grants admin access; a staff member who also has a site account signs in to each separately.
- Modules extend the account area. A module registers account sections (
registerAccountPage), so the hosting module adds Your sites and Billing, and the registry adds Packages and API tokens for publishers, moving them out of the admin. - Privacy. The privacy policy gains account data (name, email, sign-in history, connected GitHub) and, with hosting, billing data held by Stripe. Accounts can be exported and deleted by their owner.
Pages on spillwaycms.com
| Page | What it holds | When |
|---|---|---|
/hosting | What Spillway hosting is, what each plan includes, how the budget and the cap work, self-hosting as the alternative, FAQ | Before the beta, with Join the beta |
/pricing | The plans side by side (Starter when priced, Site, Campus, Auto, Enterprise), monthly and yearly, allowances, overage rates, discounts | Before the beta, prices from the decided plans |
/start | The Start a site steps, for signed-in accounts; sends visitors to sign up first | Phase 1 |
/account/sites | Your sites | Phase 1 |
/account/billing | Plan and invoices through the Stripe portal | Phase 1 |
| Theme and kit pages | Deploy this theme / Deploy this kit | Phase 2 |
/legal/hosting, /legal/aup, /legal/dpa, /legal/subprocessors | The hosting agreement, acceptable use, data processing agreement, sub-processors | Before the beta, after counsel |
The site kit ships these pages (content stays editable in the admin, as with the other pages); the footer gains Hosting and Pricing, the main menu Pricing.
Build order
- Site accounts in core: the
memberrole, the public account pages and session, Site settings → Accounts, the header links,registerAccountPage, tests, docs. - spillwaycms.com, before the beta: turn on accounts, add
/hosting,/pricing, Join the beta (a form to the mailing list) and the header's Log in and Start a site, and move registry publishing to the account area. - The hosting module and service, private beta: Start a site, Your sites, Billing, Stripe, the fleet calls, the platform domain, the legal pages after counsel.
- Launch, as in Phases.
The platform address
Every hosted site gets an address before it has a domain of its own, and keeps it as the target of its custom domain. Others do it the same way: WordPress.com gives <name>.wordpress.com, Squarespace <name>.squarespace.com, Webflow <name>.webflow.io, Ghost(Pro) <name>.ghost.io, Netlify <name>.netlify.app, Vercel <name>.vercel.app and GitHub Pages <name>.github.io. The newer ones use a domain separate from their main one, and that is the recommendation here.
A separate registrable domain, never a subdomain of spillwaycms.com. Hosted sites run their owners' content and scripts. On subdomains of spillwaycms.com they could set cookies for the parent domain, which the admin and registry accounts use, and a phishing page on one of them would hurt the reputation of the domain that holds the accounts. A domain of its own keeps those apart. Candidates, to check for availability: spillway.site, spillway.page, spillway.app or spillwaysites.com; short, clearly Spillway's, and only ever used for customers' sites.
On the Public Suffix List. Browsers group cookies and history by the "site" the Public Suffix List defines. Listing the platform domain there makes every <name>.<platform domain> its own site, so one customer's site can never read or set another's cookies, as hosting providers that give each user a subdomain do. The listing takes a pull request to the list and a DNS record proving ownership; it is permanent in practice, which suits a domain used only for this.
How it is served.
- A wildcard DNS record and a wildcard certificate for
*.<platform domain>on Spillway's Cloudflare account, so a new site is reachable the moment it is provisioned, with no certificate to wait for. - Cloudflare routes each name to its site's Fly app; the fleet records the mapping when it provisions.
- The admin lives on the site's own address (
<name>.<platform domain>/admin), never on spillwaycms.com, so each site's session cookie stays with its site.
Custom domains. The customer adds a CNAME from www.example.org to <name>.<platform domain>; the apex uses Cloudflare's CNAME flattening or the A and AAAA records shown. Cloudflare for SaaS issues the certificate. Once the custom domain is primary, the platform address answers with a 301 to it, so search engines index one address.
Names. Lowercase letters, digits and hyphens, 3 to 40 characters, unique, checked as typed. Reserved: Spillway's own names (www, admin, api, app, mail, status, docs, registry, support, billing) and look-alikes of well-known brands, which also feeds the abuse checks. A renamed site keeps redirecting from its old name for 90 days.
How it works
spillwaycms.com (storefront, accounts) ──Stripe Checkout / portal──► Stripe Billing
│ ▲ │ webhooks
│ │ site events (progress, usage, status) ▼
▼ │ hosting service (Spillway)
POST /sites, plan changes, domains ───────────────────────► spillway-fleet HTTP service
│
Fly.io apps, volumes, Postgres; R2; Cloudflare
- Storefront. A
hostingmodule on the spillwaycms.com instance adds the Start a site flow, Your sites and the theme and kit deploy buttons. Accounts are the instance's users, the ones the registry already uses; organizations are the registry's organizations. - Hosting service. A small service Spillway runs next to the fleet: it holds
hosting_account(user or organization, Stripe customer),hosted_site(fleet site id, owner, plan, budget, status, domains, trial end), handles Stripe's webhooks, calls the fleet, and relays the fleet's events back to the storefront. The storefront never holds Fly or Stripe secrets. - Lifecycle from Stripe's webhooks.
checkout.session.completedprovisions. A trial ending without payment suspends.invoice.payment_failedstarts a seven-day grace period with emails, then the site turns read-only.customer.subscription.deletedstarts the cancellation steps above. Every transition is audited and emailed. - Usage and overage. The fleet already measures spend from Fly's metrics. The hosting service reports billable usage beyond the allowances to Stripe's usage meters once a day, and the Auto controller enforces the budget with its ladder. Bandwidth is metered at the CDN as well as at Fly's edge, so cached traffic is counted fairly.
- Signing in to a hosted site. Phase 1: the storefront asks the site for a one-time sign-in link for its owner (the invite and password-reset tokens already exist; a short-lived owner token is added). Phase 3: Sign in with Spillway, spillwaycms.com as an OpenID provider that hosted sites trust, one account across every site.
- Templates. The fleet's
templateparameter already applies starter content. It gainskitandthemefrom the registry: the new site runskit installfrom the registry, with the theme's brand landing in the brand draft for review, as Kits → Install from registry does today. - Custom domains. Through Spillway's Cloudflare account (decided): Cloudflare for SaaS custom hostnames for customers' domains, so certificates and the CDN come from one place, with Fly certificates as the fallback the fleet already uses.
- Upgrades. Hosted sites follow the release channel. Updates roll out in waves (a few sites, then all), each wave checked by the status probe, and a customer can hold a site on its version for up to one release.
Does it scale?
- Cost per site is the cost model's, per plan. A self-serve customer is the same Fly app the fleet makes today, so margins are those in hosting-plans.md: $5.14 for the Site stack at its limits against a $49 price.
- Fly limits to check before launch: apps and machines per organization, shared IPv4 addresses (every site uses the shared one plus its own IPv6), volume counts, Prometheus query rates for the Auto controller at a few thousand sites. The fleet's provisioning runs a queue with a concurrency limit so a launch day does not hit Fly's rate limits.
- Operations that grow with the count: the fleet registry (a JSON file today,
FLEET_STATE; a database before a few hundred sites), the Auto controller's pass (shard by site id), backups to R2 (lifecycle rules per plan), the update waves, and support. Every one of these exists in a small form now. - Regions. One region per site, chosen at signup from the regions the cost model prices (the price is the same everywhere).
Trust, safety and legal
- Abuse. Verified email, a card on file, a cap on sites per new account, a phishing and malware check on new sites' content, a report link on the platform subdomain and a takedown process that suspends without deleting.
- Legal pages. A hosting agreement (separate from the website's terms), an acceptable use policy, a data processing agreement, the sub-processor list (Fly.io, Cloudflare, Stripe, the email provider, the AI providers), refund and cancellation terms, and the privacy policy updated for account and billing data. All for counsel.
- Merchant. Spillway sells and invoices (decided). Which legal entity stands behind the Spillway name decides tax registration and the terms; see the questions.
Phases
Phase 1: private beta. Site accounts on spillwaycms.com (see Build order), Start a site for invited accounts, Site plan only, monthly, Stripe Checkout and portal, the platform subdomain, the progress screen, Your sites with Open admin, usage, Export and Cancel, the hosting service with the lifecycle webhooks, and the legal pages. Tests: the whole flow against Stripe's test mode and a Fly test organization, every webhook transition, idempotent retries, a failed payment through to read-only and back.
Phase 2: launch. Starter (once priced), Campus, Auto and yearly billing, the trial, overage budgets with the warnings, custom domains through Cloudflare for SaaS, plan changes, Deploy buttons on theme and kit pages, education and nonprofit verification, update waves.
Phase 3: grow. Sign in with Spillway, Move my site through the importer, agencies (organization billing, client sites, reseller pricing), moving a site between self-hosting and hosting in both directions, more regions.
Open questions
- Legal entity. Spillway sells and invoices (decided); which entity stands behind it for tax registration and the terms (KWALL LLC, which the site's legal pages name as operator, or a new one)?
- Starter. Offer it, and at what price and limits?
- Free tier. None at launch (recommended), or a free sleeping site on the platform subdomain?
- Trial. 14 days with a card on file (recommended), or without a card and with tighter limits?
- Default overage budget. Decided: half the plan price ("50"). If $50 flat was meant instead, it is one number to change.
- Platform domain. Which separate domain to register for hosted sites (The platform address lists candidates)?
- Metered items. Bandwidth is decided at $0.10 per GB. Bill storage and AI credits past the allowance too, or only bandwidth at first?
Spillway 0.1.0 · Edit this page on GitHub