This project is a SaaS web application built with SvelteKit, showcasing a multi-tenancy implementation using Turso for database management and Cloudflare for hosting and domain management.
Demo : https://miloudi-mutli-tenancy.software/
Before you begin, ensure you have the following:
For development copy .env.example
to .env
, For build and production, export the environment variables to the build environment. If that's Cloudflare Workers, add them to build environment.
TURSO_PLATFORM_AUTH_TOKEN=
TURSO_GROUP_AUTH_TOKEN=
TURSO_CENTRAL_DATABASE_URL=libsql://<db-name>-<org-name>.turso.io
TURSO_SCHEMA_DATABASE_NAME=
TURSO_ORGANIZATION_NAME=
TURSO_GROUP_NAME=default
CLOUDFLARE_ZONE_ID=
CLOUDFLARE_TOKEN=
PUBLIC_DOMAIN=localhost:5173
TURSO_PLATFORM_AUTH_TOKEN
: Run turso auth api-tokens mint <api-token-name>
. This token allows you to create new databases for tenants.TURSO_GROUP_AUTH_TOKEN
: Run turso group tokens create
. This token allows you to access all the databases in TURSO_GROUP_NAME
.TURSO_CENTRAL_DATABASE_URL
: Create a central database in Turso and use the provided URL, Command turso db create <db-name>
. This database manages all the tenants including their domains and subdomains. This is where you would track usage for subscription and allow/disallow/limit features if this were a SaaS.TURSO_SCHEMA_DATABASE_NAME
: Create a database with the schema flag in Turso, Command : turso db create <db-name> --type schema
.This database will not have any rows, but it's used to synchronize the tenants db. docsTURSO_ORGANIZATION_NAME
: Run turso org list
and use the slug of your organization.TURSO_GROUP_NAME
: Default is "default".CLOUDFLARE_ZONE_ID
: After having added your domain to cloudflare. Go to Cloudflare Dashboard -> Websites -> (your domain) -> you can find the Zone ID in the right sidebar.CLOUDFLARE_TOKEN
: Generate a token with access to your zone with permission SSL and Certificates:Edit
. This is used to manage custom tenant domains.PUBLIC_DOMAIN
: Use localhost:5173
for local development, change to your domain in production. Note: If you don't put the right PUBLIC_DOMAIN you won't be able to access your app normally because the right domain will be treated as a custom tenant domain which probably does not exist.Clone the repository:
git clone https://github.com/ricin9/sveltekit-multi-tenancy
Navigate to the project directory:
cd sveltekit-multi-tenancy
Install dependencies:
pnpm install
Set up your environment variables as described above.
Migrate your central and schema databases
pnpm db:central migrate
pnpm db:tenant migrate
Run the development server:
pnpm run dev
To deploy your SvelteKit app to Cloudflare Workers, follow these steps:
Create a Cloudflare Workers project:
Add environment variables to build environment:
.env
fileModify Worker routes:
Assuming your domain is example.com
, add the following routes:
example.com
*.example.com
*/*
(This route is for custom domains added through Cloudflare for SaaS)To add these routes:
*/*
select Routes, for the zone select your PUBLIC_DOMAIN
.Enable Custom Hostname SSL:
Deploy your application:
wrangler deploy
.Remember to update your PUBLIC_DOMAIN
environment variable to your production domain when deploying.
As of the date of writing this readme, there is no way to add wildcard subdomain to pages *.example.com
, and you cannot add */*
route so that custom tenant domains are routes automatically to your worker.
You can use Cloudflare Pages, but you would have to add each created subdomain and custom tenant domain either manually or by using the Cloudflare API. I prefer automatically for this demo this is why I used Cloudflare Workers instead.
There are two methods: HTTP and TXT, (Source), HTTP is the fastest one as it only required the tenant to point their domain towards your PUBLIC_DOMAIN
with CNAME dns record after having added it through the tenant settings in the web app and the domain ssl will be installed automatically and will be routed to your app.
It is not required unless you do not have the Entreprise plan. Because of you were to set PUBLIC_DOMAIN
to sub.example.com
, Cloudflare will not install SSL Certificates for 3rd layer *.sub.example.com
unless you are on Entreprise Plan
. So it's just easier using an apex domain.
Yes you can deploy this anywhere, Cloudflare for SaaS would still work, but you will have to configure your proxy to route the wildcard subdomain of your apex, and the custom tenant domains to your application. You can therefore skip all steps of Deployment to Cloudflare Workers
except for the activation of Cloudflare For SaaS
step.
Contributions are welcome! Please feel free to submit a Pull Request.