The goal of this project is to demonstrate how easy it can be to create a multi-tenant web application using Qwik.js, Prisma, PlanetScale and Fly.io. 🏎️
- ⚡️ Multi-tenancy demonstration using Qwik
- 📚 Table of contents
- 🍭 Blog articles and YouTube videos
- 📡 Involved technologies
- 🏷️ Git tags
- 🌩️ Hosting
- ✅ Requirements
- 🛠️ Development
- 🛫 Fly.io deployment
- 📝 Blog article: coming
- 📽️ YouTube video: https://youtu.be/P6ioPj7ZfNA
- 📝 Blog article: https://peter-kuhmann.de/blog/0003
- 📽️ YouTube video: https://youtu.be/dV0Svun5_ws
- 📝 Blog article: https://peter-kuhmann.de/blog/0002
- 📽️ YouTube video: https://youtu.be/Q7nNbJomC0I
- Permissions
- User management
- Tenant management
- "Posts" feature
- Cache invalidations
- Session replacement
- New URL paths
- New UI layout
🌰 In a nutshell: User sign-up, login, logout and cookie based sessions.
Details:
- Prisma models
UserandSession - CRUD functions for
UserandSession - Cookie based sessions
- Sign-up screen and flow
- Login screen and flow
- Logged in tenant home screen
- Logout
- Route loaders/hooks
useSessionanduseRequiredSession - Sending emails
- New
.env.example fly.tomlreplaced byfly.toml.example- Minor changes:
- Tenant cache now also caches "not found" state.
Tenant.idrenamed toTenant.tenantId
🌰 In a nutshell: Providing tenant context based on subdomain.
Details:
- Prisma client
- DB seed script
- Environment variables validation
BASE_HOSTNAMEenv varuseUrlInfo()route loaderuseTenant()route loader- Three screens: Base screen + subdomain screens: Tenant not found and tenant found
Dockerfilethat generates prisma clientfly.tomlwith env var section
Bootstrapped project that includes:
- Bootstrapped Qwik app
- Prisma installed
- Fastify adapter configured
- Tailwind + DaisyUI installed
fly.tomlcreatedDockerfilecreated- Initial
README.md
The app is meant to be hosted on Fly.io 🔗.
Therefor, I created the Dockerfile 🔗, so that Fly can build a working docker image to be used for the Fly app.
I use the Fastify adapter 🔗 to host the Qwik app as a server instance.
flyCLI installedpnpminstalled- Node 18+ installed
- Docker installed
1️⃣ Copy .env.example as .env and add all the variable values.
2️⃣ First spin up the local test database (or use PlanetScale):
./.infra/start.sh3️⃣ Push the database schema:
pnpm prisma db pushStart the dev server:
pnpm startpnpm serve:build1️⃣ Copy fly.toml.example as fly.toml and add all the variable values.
Use your PlanetScale connection string for DATABASE_URL!
2️⃣ First you need to create a new Fly app via:
fly launch3️⃣ Now, set the following two secrets via fly:
fly secrets set AUTH_FLOW_JWT_PRIVATE_KEY="...add_value..." AUTH_FLOW_JWT_PUBLIC_KEY="...add_value..."4️⃣ Update PlanetScale schema:
pnpm prisma db push1️⃣ Deploy the application:
fly deploy2️⃣ Configure your DNS records to point to fly:
After deploying your app, you get a fly.dev URL.
Create two CNAME records:
yourdomain.com > your-fly-url.fly.dev*.yourdomain.com > your-fly-url.fly.dev
3️⃣ Allocate a dedicated IP v4 address: This is necessary, to issue an SSL certificate for the wildcard subdomains.
fly ips allocate-v44️⃣ Issue certificates:
fly certs add "yourdomain.com"
fly certs add "*.yourdomain.com"