This is a complete Sveltekit Template designed to help you release you SvelteKit App on Cloudflare Pages using the following services:
prod
: Upstash Clusterdev/e2e
: Local redis docker containerprod
Neon.Tech Databasedev/e2e
: Local PSQL docker containerprod
: Cloudflare Image Servicedev/e2e
: Thumbor docker containerYou can check out the live example here.
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.
.env.development
file (you can just copy the .env.example
file)docker-compose up -d
)pnpm prep
. This willpnpm psql:seed
command which will generate a admin user and 10 random users.pnpm dev
)You'll need to configure some services and environment variables in the Github Actions to run this in Prod.
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).
I've collected some information I think you might find useful when working with this template.
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
[WHAT]:[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
pnpm psql:dump
- Dumps the content of the current database into a cloudkit-db-dump.sql
file. You can mout this as a volume in the docker-compose.yaml
file in the psql
section with this path - ./cloudkit-db-dump.sql:/docker-entrypoint-initdb.d/init.sql
which will initialize the psql container with those contents on start up every time.pnpm psql:restore
- Restores from the latest cloudkit-db-dump.sql
file, if it exists.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.pnpm clean
- Deletes the ./playwright-report
, ./.wrangler
and ./.svelte-kit
folders for a clean slatepnpm prep
- If your docker containers are running, this will generate the prisma schema, push it to the psql container and seed the databaseAs 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.
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.
The Github PR.yaml action triggers on every opened PR and on fresh pushes to that PR and runs the following jobs:
INSTALL
: Installs depdendencies from pnpm-lock.yaml
and caches themLINT
: Runs prettier and the sveltekit-check commandUNIT_TEST
: Runs unit tests using vitest
E2E_TEST
:ghcr.io/minimalcompact/thumbor
- Image CRUD Serviceredis:6.2
- For keeping track of sessions and avoid hitting the DB for every session validationpostgres:15
- Databasepsql
containerprisma generate
and prisma push
command. This creates the basic DB and schemaprisma seed
command. This will:thumbor
containerpsql
containerplaywright.config.ci.ts