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
User
andSession
- CRUD functions for
User
andSession
- Cookie based sessions
- Sign-up screen and flow
- Login screen and flow
- Logged in tenant home screen
- Logout
- Route loaders/hooks
useSession
anduseRequiredSession
- Sending emails
- New
.env.example
fly.toml
replaced byfly.toml.example
- Minor changes:
- Tenant cache now also caches "not found" state.
Tenant.id
renamed toTenant.tenantId
🌰 In a nutshell: Providing tenant context based on subdomain.
Details:
- Prisma client
- DB seed script
- Environment variables validation
BASE_HOSTNAME
env varuseUrlInfo()
route loaderuseTenant()
route loader- Three screens: Base screen + subdomain screens: Tenant not found and tenant found
Dockerfile
that generates prisma clientfly.toml
with env var section
Bootstrapped project that includes:
- Bootstrapped Qwik app
- Prisma installed
- Fastify adapter configured
- Tailwind + DaisyUI installed
fly.toml
createdDockerfile
created- 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.
fly
CLI installedpnpm
installed- 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.sh
3️⃣ Push the database schema:
pnpm prisma db push
Start the dev server:
pnpm start
pnpm serve:build
1️⃣ 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 launch
3️⃣ 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 push
1️⃣ Deploy the application:
fly deploy
2️⃣ 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-v4
4️⃣ Issue certificates:
fly certs add "yourdomain.com"
fly certs add "*.yourdomain.com"