DEV Community

Royce
Royce

Posted on • Originally published at ossalt.com

Self-Hosting Guide: Deploy PocketBase as Your Backend

Self-Hosting Guide: Deploy PocketBase as Your Backend

PocketBase is the simplest backend you can deploy — a single Go binary with a built-in database (SQLite), admin UI, auth, file storage, and real-time subscriptions. No Docker needed. Download, run, done.

Requirements

  • VPS with 512 MB RAM minimum
  • Domain name (e.g., api.yourdomain.com)
  • 5+ GB disk

Step 1: Download and Run

# Download latest release
wget https://github.com/pocketbase/pocketbase/releases/latest/download/pocketbase_0.25.0_linux_amd64.zip
unzip pocketbase_0.25.0_linux_amd64.zip

# Run
./pocketbase serve --http=0.0.0.0:8090
Enter fullscreen mode Exit fullscreen mode

That's it. Admin UI at http://your-server:8090/_/, API at http://your-server:8090/api/.

Step 2: Reverse Proxy (Caddy)

# /etc/caddy/Caddyfile
api.yourdomain.com {
    reverse_proxy localhost:8090
}
Enter fullscreen mode Exit fullscreen mode
sudo systemctl restart caddy
Enter fullscreen mode Exit fullscreen mode

Step 3: Create Admin Account

  1. Open https://api.yourdomain.com/_/
  2. Create your admin account on first visit

Step 4: Create Collections (Tables)

In the admin UI:

  1. Click New collection
  2. Name it (e.g., posts)
  3. Add fields:
Field Type Options
title Text Required, max 200
content Editor Rich text
published Bool Default false
author Relation → users collection
image File Max 5MB, jpg/png/webp
tags JSON Array of strings
  1. Configure API Rules (who can read/write):
    • List/Search: @request.auth.id != ""
    • View: "" (public)
    • Create: @request.auth.id != ""
    • Update: @request.auth.id = author.id
    • Delete: @request.auth.id = author.id

Step 5: Authentication

PocketBase includes built-in auth:

Email/password (default):


const pb = new PocketBase('https://api.yourdomain.com')

// Sign up
const user = await pb.collection('users').create({
  email: 'user@example.com',
  password: 'password123',
  passwordConfirm: 'password123',
  name: 'John Doe',
})

// Login
const auth = await pb.collection('users').authWithPassword(
  'user@example.com',
  'password123'
)
console.log(auth.token)
Enter fullscreen mode Exit fullscreen mode

OAuth2 providers:
Configure in Admin UI → Settings → Auth providers:

  • Google, GitHub, Microsoft, Apple, Discord, GitLab, Facebook, Twitter, Spotify
// OAuth2 login
const auth = await pb.collection('users').authWithOAuth2({ provider: 'google' })
Enter fullscreen mode Exit fullscreen mode

Step 6: Use the API


const pb = new PocketBase('https://api.yourdomain.com')

// Create
const post = await pb.collection('posts').create({
  title: 'My First Post',
  content: '<p>Hello world</p>',
  published: true,
})

// List with filters
const posts = await pb.collection('posts').getList(1, 20, {
  filter: 'published = true',
  sort: '-created',
  expand: 'author',
})

// Real-time subscriptions
pb.collection('posts').subscribe('*', (e) => {
  console.log(e.action) // 'create', 'update', 'delete'
  console.log(e.record)
})

// File upload
const formData = new FormData()
formData.append('title', 'Post with image')
formData.append('image', fileInput.files[0])
const post = await pb.collection('posts').create(formData)

// Get file URL
const imageUrl = pb.files.getURL(post, post.image)
Enter fullscreen mode Exit fullscreen mode

Step 7: Set Up as a Systemd Service

sudo nano /etc/systemd/system/pocketbase.service
Enter fullscreen mode Exit fullscreen mode
[Unit]
Description=PocketBase
After=network.target

[Service]
Type=simple
User=pocketbase
Group=pocketbase
WorkingDirectory=/opt/pocketbase
ExecStart=/opt/pocketbase/pocketbase serve --http=0.0.0.0:8090
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
Enter fullscreen mode Exit fullscreen mode
sudo systemctl enable pocketbase
sudo systemctl start pocketbase
Enter fullscreen mode Exit fullscreen mode

Step 8: Configure SMTP

In Admin UI → SettingsMail settings:

Setting Value
Sender address noreply@yourdomain.com
Sender name My App
SMTP host smtp.resend.com
SMTP port 587
Username resend
Password re_your_api_key

Required for email verification, password reset, and notifications.

Production Hardening

Backups:

# Copy the SQLite database (daily cron)
# PocketBase stores everything in pb_data/
cp /opt/pocketbase/pb_data/data.db /backups/pocketbase-$(date +%Y%m%d).db

# Or use PocketBase's backup API
curl -X POST 'https://api.yourdomain.com/api/backups' \
  -H 'Authorization: admin-token'
Enter fullscreen mode Exit fullscreen mode

Updates:

# Download new version
wget https://github.com/pocketbase/pocketbase/releases/latest/download/pocketbase_NEW_VERSION_linux_amd64.zip
unzip -o pocketbase_*_linux_amd64.zip -d /opt/pocketbase/

# Restart
sudo systemctl restart pocketbase
# PocketBase auto-migrates the database
Enter fullscreen mode Exit fullscreen mode

Security:

  • Restrict admin UI access by IP if possible
  • Always use HTTPS (Caddy handles this)
  • Set proper API rules on all collections
  • Enable email verification for users

Performance:

  • PocketBase handles 10K+ concurrent connections
  • SQLite is surprisingly fast for reads
  • For write-heavy apps at scale, consider PostgreSQL-based alternatives

Resource Usage

Users RAM CPU Disk
1-100 128 MB 1 core 1 GB
100-1K 256 MB 1 core 5 GB
1K-10K 512 MB 2 cores 20 GB

PocketBase is the most lightweight backend you can deploy.

VPS Recommendations

Provider Spec Price
Hetzner 2 vCPU, 2 GB RAM €4.50/month
DigitalOcean 1 vCPU, 1 GB RAM $6/month
Linode 1 vCPU, 1 GB RAM $5/month
Fly.io 1 vCPU, 256 MB Free tier

Compare backend platforms on OSSAlt — features, scalability, and self-hosting options side by side.

Top comments (0)