Resources

This tutorial assumes that you have already have a Dockerized SvelteKit project.

If you do not, start with the Run SvelteKit in Docker.

What is PocketBase?

PocketBase is a cloud-based database management service that allows developers to quickly and easily create, manage, and access databases for their applications. It provides an intuitive interface for creating and modifying database schemas built on SQLite.

One of the main benefits of using PocketBase is that it allows developers to quickly and easily create and use a database. It removes the need to manage a separate database server, saving time and effort and allowing developers to focus on building their applications. It supports SQL and NoSQL data models, and you can choose the best data model for your use case. Additionally, PocketBase provides various features like automatic data backup, real-time data syncing, and automatic scaling.

Installing PocketBase

Navigate to the root directory of your “SvelteKit in Docker” project. Here’s what mine looks like.

$ cd svelte-docker; ls
Dockerfile  svelte

Navigate into the root directory for your Svelte project and install the PocketBase SDK. This will allow us to use PocketBase in our project.

$ cd svelte
$ npm install pocketbase

Configuring SvelteKit to use PocketBase

We will use PocketBase to register and authenticate users. Create a directory in src named lib and then create a file named pocketbase.ts in the src/lib with the following contents:

src/lib/pocketbase.ts

import PocketBase from 'pocketbase';
import { writable } from 'svelte/store';

export const pb = new PocketBase('http://127.0.0.1:8090');
export const currentUser = writable(pb.authStore.model);

pb.authStore.onChange(() => {
    currentUser.set(pb.authStore.model);
});

The pocketbase.ts file will import PocketBase and writable to set a constant currentUser and update it when authStore in PocketBase changes (defined in the onChange at the bottom). This lets us authenticate users and keep track of whether they are logged in and we can access the updated value with $currentUser (notice the $, denoting a subscription) from any other part of the application.

The pb object we’re using has a baseUrl value of http://127.0.0.1:8090 since we’ll be using it in Docker, but feel free to change this value in the future.

In the same directory, let’s create an Auth.svelte component file in the lib directory to handle user authentication attempts. The following example code has the basic login, logout, and register functions.

src/lib/Auth.svelte

<script lang="ts">
    import { currentUser, pb } from "./pocketbase";

    let username: string;
    let password: string;

    async function login() {
        await pb.collection('users').authWithPassword(username, password);
    }

    async function register() {
        try { 
            const data = {
                username,
                password,
                passwordConfirm: password
            };
			await pb.collection('users').create(data);
            await login();
        } catch (err) {
            console.log(err);
        }
    }

    function logout() {
        pb.authStore.clear();
    }
</script>

{#if $currentUser}
    <p>Logged in as {$currentUser.username}</p>
    <button on:click={logout}>Logout</button>
{:else}
    <form on:submit|preventDefault>
        <input
            placeholder="Username"
            type="text"
            bind:value={username}
        />
        <input
            placeholder="Password"
            type="password"
            bind:value={password}
        />
        <button on:click={login}>Login</button>
        <button on:click={register}>Register</button>
    </form>
{/if}

These functions above use pb to manage users.

  • login awaits a response that has a collection of users that match the username and password.
  • register uses the form (further down, in the :else statement) to attempt to create a user in PocketBase, then calls login with the new credentials.
  • logout empties the pb.authStore and removes a user’s authentication.

Next, we have an if/else statement. If the $currentUser is defined, then PocketBase has authenticated the user and inform them that they’re logged in and present the option to logout. Otherwise, we present the login/register form. Since we’re subscribed to the value of $currentUser (denoted by the $), the page will update when this value is updated (which is when pb.authStore changes). This causes our content to reload each time a function changes the pb.authStore.

Dockerize PocketBase

We now need to create a new Dockerfile for the PocketBase image that we’ll use with our SvelteKit image. Navigate back to the directory just above your SvelteKit project’s root directory, where your Dockerfile for the SvelteKit project exists and rename Dockerfile to Dockerfile.web. Then, create a new file named Dockerfile.db.

$ cd svelte-docker
$ mv Dockerfile Dockerfile.web
$ touch Dockerfile.db
$ ls
Dockerfile.db  Dockerfile.web  svelte

Populate Dockerfile.db with the following contents:

Dockerfile.db

FROM alpine:3 as downloader

ARG TARGETOS
ARG TARGETARCH
ARG VERSION=0.10.4

ENV BUILDX_ARCH="${TARGETOS:-linux}_${TARGETARCH:-amd64}"

RUN apk add --no-cache \
    ca-certificates \
    unzip \
    wget \
    zip \
    zlib-dev

RUN wget https://github.com/pocketbase/pocketbase/releases/download/v${VERSION}/pocketbase_${VERSION}_${BUILDX_ARCH}.zip \
    && unzip pocketbase_${VERSION}_${BUILDX_ARCH}.zip \
    && chmod +x /pocketbase

FROM scratch

EXPOSE 8090

COPY --from=downloader /pocketbase /usr/local/bin/pocketbase
CMD ["/usr/local/bin/pocketbase", "serve", "--http=0.0.0.0:8090"]

This tells Docker to download and install the dependencies for PocketBase, download the PocketBase application, and create a new container with port 8090 exposed to serve the PocketBase installation. The VERSION argument is set to 0.10.4, but feel free to change this to use a different version of PocketBase.

Local Deployment and Usage

We can specifiy which Dockerfile to use with the -f option. Let’s build our two images and then run them in the detached mode.

$ docker build -t sveltekit-docker -f Dockerfile.web .
$ docker build -t pocketbase-docker -f Dockerfile.db .
$ docker run -d --rm -p 80:80 sveltekit-docker
$ docker run -d --rm pocketbase-docker

Now, we can visit localhost to see our SvelteKit application’s home page. Access the PocketBase admin page by going to localhost:8090/_ (note the /_ at the end).

Try creating a new user from the home page by entering a username and a password (by default, a PocketBase user password needs to be at least 8 characters). The application will register the new user to the PocketBase users collection and log you in.

You can see the new user’s information in PocketBase by logging into the admin page, clicking the “Collections” tab on the left (or navigating to the collections link), and clicking the “users” collection.

Getting Started With kind