Autonnel v0.1.0
Back to blog

Twelve offers, one deployment: multi-domain funnels

Autonnel binds as many domains as you need to one deployment, with no agency tier. What actually changes when twelve offers share one install.

· 9 min read

Launchtic prices this capability. Their pricing page reads “Pay only if you’re running Launchtic for clients”, with an Agency tier at $997/year, and they ship under a Fair-code Sustainable Use License rather than an OSI-approved one (source: launchtic.com/pricing, checked 2026-08-03).

I do not think that is outrageous pricing. I think it is evidence. Somebody built a billing tier around running more than one brand, which means enough operators are doing it that it became a line item.

Autonnel is Apache-2.0 and the commercial limit is none: run it for yourself, for clients, or as part of a paid service. Multi-domain is not a tier. A single deployment takes as many domains as you need, and there is no upgrade path to unlock it, because there is nothing to unlock.

That is the marketing half of the story. The useful half is what actually changes in your day when twelve offers live in one install, including the parts that get worse.

What “one deployment” means mechanically

A single deployment can have multiple domain names. Exactly one is marked primary. All domains serve the same set of pages. You add domains from Settings → Domains by pasting the hostname with no protocol and no trailing slash; the first domain you add is marked primary automatically, and everything after it lands as non-primary. There is no intermediate “site” container between the deployment and the domain, which is why there is no per-site anything to configure.

Which hostname serves the admin is decided by ADMIN_DOMAIN. Every hostname that is not in ADMIN_DOMAIN serves the storefront, which is the correct failure mode for a commerce product: a misconfiguration shows a customer a page, not your dashboard. It accepts comma-separated lists and a single-label wildcard like *.example.com.

So the shape is: one admin hostname, twelve customer-facing hostnames, one Postgres, one process. Details in multi-domain and domain settings.

Read this before you add domain number two

Non-primary domains redirect to the primary domain with a 301. Whether that redirect is active depends on your deployment configuration, and if you are running genuinely different offers on each hostname you want it off. Leave it on and eleven of your twelve offers bounce to the first one you ever added.

Two things make this worse than a normal misconfiguration. First, 301 is permanent, and some crawlers cache permanent redirects aggressively, so a redirect you served for an afternoon can outlive the fix. Second, the primary flag is not decorative: you cannot delete the primary domain without promoting another one first, and promoting a new primary demotes the old one automatically. Test the redirect behavior on a throwaway hostname before you point real traffic at it.

What genuinely gets better

One upgrade. docker compose pull then docker compose up -d. The one-shot schema service re-runs on every up, so a schema change that ships with a new image is applied before the app starts. Twelve installs means twelve of those, twelve rollback decisions, and twelve chances to skip one and forget which. One install means one. Pin an exact tag like :1.3.0 in production and you know precisely what all twelve offers are running.

One admin, one login model. Registration is invitation-only; there is no open sign-up. You invite from Settings → Users, and a person who already has an account joins by entering that account’s current password, which never gets changed by an invitation. A contractor who works across your offers gets one account, not twelve.

A per-offer kill switch that is one click. Delete a non-primary domain row and it is gone with no redirect left behind. Visitors to that hostname get a domain-not-configured error page until DNS is updated. That is a blunt instrument, and blunt is what you want when an offer has to come down now.

Shared everything by default. Components, storage, cache, payment and commerce configuration are configured once in Settings and apply to the deployment. When you fix a checkout component, it is fixed on all twelve.

Now the part nobody advertises

All domains serve the same set of pages

This is the sentence to sit with. Domains are not namespaces. Your twelve offers are twelve groups of pages sharing one slug space, and a page published in that space is reachable from every hostname bound to the deployment.

Practically: name your slugs like you expect that. offer-a-checkout and offer-b-checkout, not two pages both wanting /checkout. If your mental model is “each domain gets its own tidy /, /checkout, /thanks”, change it now rather than after you have built four funnels.

Branding is per deployment, not per domain

The branding fields are display name, favicon and logo, and they are singular. The favicon URL is written into <link rel="icon"> in the head of every storefront page. The display name shows in the admin header and in transactional email subjects and footers. The logo shows in the admin header and in transactional email headers for order confirmation, shipping notification and refund notices.

So the per-offer look you can actually have is at the page level: Puck components like StoreNavBar and CheckoutHeroSection pull from global branding when they are set to, which is a choice you make per component. What you cannot get from one deployment is twelve different favicons and twelve different email headers. Every order confirmation from that install carries the same logo and the same name.

If your twelve offers are your own portfolio, that is usually fine and arguably desirable. If they are twelve clients who each expect their own logo on the receipt, one deployment is the wrong architecture and you should stop reading here.

Permissions are feature-scoped, not domain-scoped

Worth being blunt because it decides the agency question. The permission model assigns features to roles and roles to users, where a feature is a menu or sub-menu: pages, pages.edit, orders, orders.refund, settings. The sidebar hides what a user’s roles do not include, and a direct URL to something they lack returns 403.

There is no domain dimension in that model. A role that grants orders grants orders, all of them, across every domain on the deployment. You cannot hand a client a login that shows only their funnel’s orders.

The isolation boundary that does exist is the workspace: on Autonnel Cloud, one person joins multiple organizations with the same email and password and signs in on each organization’s own console domain. Self-hosted, the equivalent is separate deployments. So the honest rule is: one deployment per trust boundary, as many domains as you like inside it. Twelve of your own offers, one deployment. Twelve clients who must not see each other’s revenue, twelve deployments. See permissions.

Shared blast radius

Twelve offers on one install means one bad publish can touch all of them, and the publishing model is deliberately thin: one draft and one published version per page, no version history. Publishing overwrites the previous published version permanently. If two people publish the same page from different tabs, last write wins and the earlier publish is silently overwritten. The documented way to preserve a version is to duplicate the page before you change it.

That is a fine trade at one operator and one offer. At twelve offers and three people it is a coordination problem you now own, and the cheapest fix is a convention about who touches what, not a feature. On Cloudflare Workers there is one more wrinkle: KV is eventually consistent, so a request served from a different edge node can briefly return stale content right after a publish. It resolves within seconds. See publishing.

DNS and TLS stay your problem, twelve times

Autonnel does not manage DNS and does not issue or renew TLS certificates. Each domain needs its own CNAME (or A record if your host gives you an IP) and its own certificate, whether that comes from a Cloudflare proxied record, Caddy in front of a Node server, or your platform’s certificate manager.

Two limits in the open-source edition are worth knowing before you plan: there is no wildcard domain support, so every subdomain needs its own explicit domain row, and there is no domain verification. Adding a row does not check that DNS points anywhere. A missing certificate produces a browser TLS error that Autonnel cannot detect or surface to you, so the failure looks like silence in the admin and a scary warning to the customer. Verification, including the Cloudflare for SaaS flow, is managed-only.

There is also one static asset domain per deployment. Leave it blank and it derives from your primary domain by prefixing static., so shop.example.com gives static.example.com. All twelve offers serve their uploaded images from that one host.

The arithmetic

Twelve offers on one Autonnel install costs one server or one Workers deployment, one Postgres, and twelve DNS records. On Cloudflare Workers, static assets are unmetered and typical funnel traffic stays inside the free tier, so the marginal cost of offer number thirteen is a DNS record and whatever the pages generate in requests.

The comparison worth making is not feature-by-feature, it is what happens at renewal. A $997/year agency tier is a recurring decision about whether the client roster still justifies it. Apache-2.0 with no commercial limit is not a decision at all. We keep the licence claims for every product in this space, with the command to re-verify each one, in open-source funnel builders compared, and our own pricing is on pricing.

Start with installation: docker compose up, then add your second domain and deliberately break the redirect on a hostname nobody is watching. It is the cheapest hour you will spend on this.