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 theform
(further down, in the:else
statement) to attempt to create a user inPocketBase
, then callslogin
with the new credentials.logout
empties thepb.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.