Why host PocketBase on a VPS instead of a cloud BaaS
Firebase, Supabase and similar cloud BaaS platforms charge per read, per write, per GB of storage and per active user. A small app with a few thousand users can easily run up a $50–$200/month bill — before any traffic spike. PocketBase on a VPS replaces that entire stack for a single fixed monthly fee. Your data stays on your server under your control, you choose when to upgrade, and there is no per-request billing to worry about. Because the binary embeds SQLite, you skip the database provisioning step entirely: no Postgres connection string, no DB user, no security group to configure.
What you get with a self-hosted PocketBase
- Embedded SQLite database — no separate DB server, just one file to back up.
- Realtime WebSocket subscriptions — update your frontend UI the moment a record changes.
- Built-in auth: email/password, OAuth2 (Google, GitHub, Apple, GitLab…), OTP and magic link.
- File storage with on-the-fly image resizing and per-collection access control.
- Auto-generated REST API with filtering, sorting, pagination and field-level visibility.
- Web admin dashboard — create collections, manage records and invite admins from your browser.
- JavaScript and Dart SDKs for instant integration with React, Vue, Flutter, React Native.
Prerequisites
PocketBase is extremely light. A 1-vCPU VPS with 1–2 GB RAM handles thousands of daily active users comfortably. Plan for 10 GB of disk minimum if you store user-uploaded files; add more as your file storage grows. You need Docker installed, a domain name pointed to your VPS IP, and ports 80 and 443 open. If you process payments or sensitive data, enable automated backups of the Docker volume.
Deploy PocketBase with Docker and HTTPS
Install Docker
Connect via SSH, update the system and install Docker: curl -fsSL https://get.docker.com | sh. Verify with docker --version.
Run PocketBase
Start the container: docker run -d -p 127.0.0.1:8090:8090 -v pocketbase:/pb/pb_data --name pocketbase --restart always ghcr.io/muchobien/pocketbase:latest. Binding to 127.0.0.1 keeps the API off the public internet until you add a reverse proxy.
Create your admin account
PocketBase is temporarily accessible on port 8090 for initial setup: curl http://localhost:8090/_/. Open http:// in your browser, fill in an email and password, and you land on the admin dashboard.
Add a reverse proxy with HTTPS
Install Caddy: apt install -y caddy. Add a Caddyfile entry: pb.yourdomain.com { reverse_proxy localhost:8090 }. Run systemctl reload caddy. Your PocketBase instance is now at https://pb.yourdomain.com with a valid Let's Encrypt certificate — realtime WebSocket connections work transparently.
Create your first collection
In the admin dashboard, click New Collection, name it (e.g. posts), add fields (title: text, body: text, author: relation → users), and set access rules. PocketBase instantly generates REST endpoints: GET /api/collections/posts/records, POST /api/collections/posts/records, etc.
Connect your frontend
Install the JS SDK: npm install pocketbase. In your frontend: import PocketBase from 'pocketbase'; const pb = new PocketBase('https://pb.yourdomain.com');. Subscribe to realtime updates: pb.collection('posts').subscribe('*', ({ action, record }) => { console.log(action, record) }).
Schedule automatic backups of the pocketbase Docker volume to a remote S3-compatible bucket using rclone. A daily docker run --rm -v pocketbase:/data -v ~/.config/rclone:/config/rclone rclone/rclone copy /data your-remote:pocketbase-backup/ keeps a rolling off-site copy — critical since SQLite stores everything in one file.