Welcome to CloudKit

A production ready sveltekit cloudflare template

Author: Daniel Einars

This is a complete Sveltekit Template designed to help you release your SvelteKit App on Cloudflare Pages using the following services:

Sensible Defaults for Dev Tooling
TypeScript, ESLint, Prettier & Husky for pre-commit hooks
Cloudflare Pages
Cloudflare Pages
Automatic publication for preview branches and production deployment on push-to-master
Authentication
Lucia Auth with a production-ready Sign Up/In/Out flow and Delete Account flow.
Prisma
Prisma
Integration with Postgres & Redis, locally and in production. Clean and simple data access layer with specific Repository Classes.
GitHub Actions
Github Actions
Runs Linting, Type-Verification, Unit & E2E Tests automatically.
Playwright
E2E Tests
Playwright for E2E Tests in Github Actions and for local development
Vite
Unit Tests
Preconfigured ViteTest for Unit Tests in Github Actions and for local development
Redis
Redis
Preconfigured to use a local redis docker container for dev and e2e tests and a Upstash Cluster for production
PostgreSQL
Postgres
Preconfigured to use a local psql docker container for dev and e2e tests and a Neon.Tech Database for production
Cloudflare
Image hosting & processing
Preconfigured to use Cloudflare Image Service for production and a Thumbor docker container for dev and e2e tests
Skeleton.Dev
Configured to use the Sveltekit Skeleton Library

Auth Flow

You can try out the Auth Flow right here. Either create a new user by signing up or use one of the existing users. The default Username and Password is [email protected]. Feel free to try it out! This website will be redeployed every 24h.

Prerequisites

Becase PR.yaml action uses docker containers, you'll have to configure the following Github Action Secrets in a CI environment in order for the Workflow to run through without errors. Example Values of these can be cound in the .env.ci file.

Running this locally

  1. 1.Create a .env.development file (you can just copy the .env.example file)
  2. 2.Start up the docker containers (docker-compose up -d)
  3. 3.Run pnpm prep. This will generate the prisma schema, push it to the DB and seed the PSQL & Thumbor containers
  4. 3.Run the correct prisma generate command
  5. 4.Push the schma to the local psql db
  6. 6.Run the pnpm psql:seed command which will generate a admin user and 10 random users.
  7. 7.Start the dev server (pnpm dev)

Running this in Production

You'll need to configure some services and environment variables in the Github Actions to run this in Prod.
1.
Cloudflare Pages

There is a free tier but even the paid tier isn't very expensive.

You'll also have to create the project in Cloudflare and set it up. For the sake of convenience I've included the cloudflare:init script. You'll have to set up the .env.production file.

Note: If you look at createCloudflareProject.js you'll see that the build & publishing configuration is disabled. This is because the Github Action will take care of that.

2.
Cloudflare Images
This one is paid only. It's 5 USD / Month / 100'000 Image served with 20 configured variations (the variations do not count to the 100'000 image limit). Delivering images is 1 USD for every 100'000 images. There's also a enterprise version. Check out the details here.
3.
Neon.Tech
Database - I've been using their free tier for ages without hitting any limits so far. The only reason I went ahead and upgraded was because you can only have one project on the free tier. They don't charge you for a month if the bill is under 50 Cent. It's very affordable for what you're getting. Seriously, check them out.
4.
Upstash
They have a generous free tier. Personally, I use the "Pay As You Go" option and set a low budget limit. Check out their pricing here.
5.
Prisma Cloud
You will not be able to hack your way around this one because prisma's edge client doesn't allow connecting to a database directly. They have a generous free tier and that's the only thing I use them for. Create a project [here](https://cloud.prisma.io/), create the Connection String and use this. Their DataExplorer will then be linked to the production database, which can be quite handy as well.

Github Actions Environemnts

I've configured the actions using a CI and a PREVIEW environment. The Variables keys for both are the same (see .env.example). The CI environment values should use the same values as in the .env.example file, as these are used to run the e2e tests against the docker containers. The PREVIEW values need to be set values from the relevant services.

In addition to these you'll have to configure CLOUDFLARE_API_TOKEN and CLOUDFLARE_ACCOUNT_ID to enable preview & production publishing. You can optain the CLOUDFLARE_API_TOKEN in the cloudflare dashboard. Create a new token which allows editing for Cloudflare Pages. Then set up a Pages Project. The Github Action should then deply accordingly. You can also assign it to a domain if you use cloudlfare to manage your domains (I highly reccomend this, it makes life so much easier).

Scripts in package.json

I've included a lot of scripts in the package.json file. The mostly depend on each other. The naming follows this pattern in general
[COMMAND]:[ACTION]:[ENV]
For example, If I want to generate my prisma schema for local development I would run pnpm prisma:gen:dev.
Here are some useful scripts
1.
pnpm psql:dump
Dumps the content of the current database into a cloudkit-db-dump.sql file. You can ./cloudkit-db-dump.sql:/docker-entrypoint-initdb.d/init.sql which will initialize the psql container with those contents on start up every time.
2.
pnpm psql:restore
Restores from the latest cloudkit-db-dump.sql file, if it exists.
2.
pnpm test:e2e:dev
Runs the sveltekit development server and Playwright in UI mode. This way you can code and verify your tests at the same time.
2.
pnpm clean
Deletes the ./playwright-report, ./.wrangler and ./.svelte-kit folders for a clean slate
2.
pnpm prep
If your docker containers are running, this will generate the prisma schema, push it to the psql container and seed the database

Data Proxy

As previously mentioned, prisma doesn't a direct connection to Databases form edge functions. You need to create a Data Proxy, which does some prisma magic and then you can use Prisma in Edge Functions. This is why there are two prisma schemas. The "normal" way of defining your data source is this

		datasource db {
			provider = "postgresql"
			url = env("DATABASE_URL")
		}
	

If you're using the Data Proxy, you have to declare it like this

		datasource db {
			provider = "postgresql"
			url = env("DATA_PROXY")
			directUrl = env("DATABASE_URL")
		}
	

The DATABASE_URL refers to the standard Database URL and DATA_PROXY refers to the connection string you generate when creating a Cloud Prisma Project - Its free for mostly everything.

Prisma Code Organization

I couldn't find a good way to keep all my prisma relevant code together so I came up with the following solution. There are two Repository classes. One for managing Users and one for managing Images. I've split the Prisma code up like this in order to keep the primsa imports to a bare minimum. All DB Actions I do via these classes and they are called only from the server.

Note: The ImageRepository can interchangebly be used with the local thumbor container or with Cloudflare's Image Service.

Understanding the PR.yaml Github Action

The Github PR.yaml action triggers on every opened PR and on fresh pushes to that PR and runs the following jobs:
1.
INSTALL
Installs depdendencies from pnpm-lock.yaml and caches them
2.
LINT
Runs prettier and the sveltekit-check command
3.
UNIT_TEST
Runs unit tests using vitest
4.
E2E_TEST
Launches docker containers, seeds the database and thumbor and runs all e2e tests

Notes about this Project

This project is a work in progress. I'm using it to build a few projects and will update it accordingly. If you have any questions, feel free to reach out by creating an issue or discussion on GitHUb.