Back to Blog
Tutorial8 min read2026-07-01

How to Deploy PocketBase Backend

PocketBase is a single-binary backend with auth, a database, file storage, and a realtime API. Learn how to deploy it durably and why persistent storage is the one thing you can't skip.

Ajay Kumar
Ajay Kumar
Founder & DevOps, PandaStack

PocketBase is a gem for indie developers: a single Go binary that gives you a SQLite database, authentication, file storage, realtime subscriptions, and an admin dashboard — all in one executable. There's no separate database server, no Redis, no constellation of services. That simplicity is its superpower and also the key to deploying it correctly: because everything lives on disk, persistent storage is non-negotiable. Here's how to ship it.

Why PocketBase is different

Most backends in this series need an external database. PocketBase deliberately doesn't — it embeds SQLite and stores data, file uploads, and config in a single pb_data directory. This makes it incredibly easy to run and reason about, and SQLite (with WAL mode, which PocketBase uses) is genuinely fast for the read-heavy workloads most apps have. The catch: in a stateless container, anything written to disk vanishes on redeploy unless that directory is a persistent volume.

Step 1: The cardinal rule — persist pb_data

Everything important lives in pb_data:

  • The SQLite database (your records, users, schema).
  • Uploaded files.
  • Settings and encryption keys.

Mount a persistent volume there:

volumes:
  - mount: /pb/pb_data
    size: 5Gi

If you forget this, you'll lose all data on the first redeploy. It's the only deployment mistake that really matters with PocketBase.

Step 2: Containerize

PocketBase doesn't ship an official image, but a minimal Dockerfile is trivial:

FROM alpine:3.20
ARG PB_VERSION=0.22.0
RUN apk add --no-cache ca-certificates unzip wget
RUN wget https://github.com/pocketbase/pocketbase/releases/download/v${PB_VERSION}/pocketbase_${PB_VERSION}_linux_amd64.zip \
  && unzip pocketbase_${PB_VERSION}_linux_amd64.zip -d /pb
EXPOSE 8090
CMD ["/pb/pocketbase", "serve", "--http=0.0.0.0:8090"]

Binding to 0.0.0.0 is essential — PocketBase defaults to localhost, which won't accept external traffic in a container.

Step 3: Deploy on PandaStack

  1. 1Put the Dockerfile above in your repo.
  2. 2Create a container app from the repo — PandaStack builds the Dockerfile with rootless BuildKit.
  3. 3Attach a persistent volume at /pb/pb_data.
  4. 4Expose port 8090 (or map to the injected port — adjust the --http flag accordingly).
  5. 5Attach a custom domain with automatic SSL.

On first load, visit /_/ to create your admin account. That account is stored in pb_data, so it persists with the volume.

Step 4: Configure for production

  • Admin account — create it immediately on first boot; the setup page is open until you do.
  • SMTP — configure email (Settings → Mail) so password resets and verification work. PocketBase's built-in mailer is fine for low volume; use a real SMTP provider for production.
  • Backups — PocketBase has a built-in backup feature (Settings → Backups) that can snapshot pb_data and even upload to S3-compatible storage. Enable scheduled backups and point them at a MinIO or S3 bucket.
  • Realtime — the realtime API works over SSE out of the box; no extra config needed.

Step 5: Extend with hooks (optional)

PocketBase can be used as a framework, not just a binary. You can write Go hooks or use JavaScript hooks (pb_hooks/) for custom business logic:

// pb_hooks/main.pb.js
onRecordAfterCreateRequest((e) => {
  console.log('New record:', e.record.id);
}, 'posts');

Drop JS hook files into a pb_hooks directory (also mount it or bake it into the image) and PocketBase loads them automatically.

Resource notes

PocketBase is extraordinarily light — a single Go binary with SQLite. It runs comfortably on the smallest compute tier and handles a surprising amount of traffic, especially read-heavy workloads, thanks to SQLite's WAL mode. This makes it a near-perfect fit for a free-tier deployment of a real side project or MVP.

Honest caveats

The flip side of single-binary simplicity is that PocketBase is single-node by design. You can't run multiple replicas against one SQLite file, so horizontal scaling isn't on the table the way it is with a Postgres-backed app — you scale vertically (a bigger instance). For the vast majority of indie projects and MVPs this is completely fine, but if you anticipate needing multi-node horizontal scale, plan for that from the start (or choose a Postgres-backed backend). Also, PocketBase is pre-1.0; APIs can shift between versions, so pin your version and read release notes before upgrading.

Wrapping up

PocketBase is the fastest way to get a real backend — auth, database, storage, realtime — running, and deploying it is almost entirely about one thing: persisting pb_data on a durable volume. Add scheduled backups to S3, configure SMTP, and you have a complete, self-owned backend in minutes.

PandaStack builds your Dockerfile, attaches a persistent volume, and serves it with automatic SSL — and PocketBase's tiny footprint fits the free tier with room to spare. Deploy yours at https://dashboard.pandastack.io.

References

  • PocketBase documentation: https://pocketbase.io/docs/
  • PocketBase Go releases: https://github.com/pocketbase/pocketbase/releases
  • PocketBase going to production: https://pocketbase.io/docs/going-to-production/
  • PocketBase JS hooks: https://pocketbase.io/docs/js-overview/
  • SQLite WAL mode: https://www.sqlite.org/wal.html

Ready to deploy?

Start free on PandaStack.

Start free on PandaStack

More in Tutorial

Browse all Tutorial articles →

See also