PocketBase on a VPS: Single-Binary Backend as a Service for Rapid App Development

PocketBase on a VPS: Single-Binary Backend as a Service for Rapid App Development

PocketBase is an open-source backend-as-a-service in a single Go binary — it provides a SQLite database with a REST API, real-time subscriptions (SSE), built-in authentication (email/password + OAuth), file storage, and a admin dashboard, all running on 32 MB RAM. It’s the polar opposite of heavy BaaS stacks: no Docker, no multiple services, just one binary. For side projects, MVPs, and small-to-medium applications, PocketBase eliminates backend infrastructure complexity entirely.

PocketBase vs Appwrite vs Supabase

Factor PocketBase Appwrite Supabase
Min RAM 32 MB (!) 2 GB 4 GB
Setup Single binary Docker Compose Docker Compose
Database SQLite Document DB PostgreSQL
Realtime SSE WebSocket WebSocket
Scalability Single server Good Excellent
Best for Side projects, MVPs, small apps Medium teams Production scale

Step 1: Install PocketBase

<code"># Download PocketBase (single binary)
mkdir -p /opt/pocketbase && cd /opt/pocketbase

wget https://github.com/pocketbase/pocketbase/releases/download/v0.22.0/pocketbase_0.22.0_linux_amd64.zip
unzip pocketbase_0.22.0_linux_amd64.zip
rm pocketbase_0.22.0_linux_amd64.zip
chmod +x pocketbase

# Start PocketBase
./pocketbase serve --http="127.0.0.1:8090"

# That's it — no Docker, no dependencies, nothing else
<code">sudo nano /etc/systemd/system/pocketbase.service
<code">[Unit]
Description=PocketBase Backend
After=network.target

[Service]
Type=simple
User=ubuntu
WorkingDirectory=/opt/pocketbase
ExecStart=/opt/pocketbase/pocketbase serve --http="127.0.0.1:8090"
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
<code">sudo systemctl daemon-reload
sudo systemctl enable pocketbase
sudo systemctl start pocketbase

Step 2: Nginx Reverse Proxy

<code">sudo nano /etc/nginx/sites-available/pocketbase
<code">server {
    listen 443 ssl http2;
    server_name api.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/api.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/api.yourdomain.com/privkey.pem;

    client_max_body_size 50M;

    location / {
        proxy_pass http://127.0.0.1:8090;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
<code">sudo certbot --nginx -d api.yourdomain.com
sudo systemctl reload nginx

Step 3: Admin Setup and Collections

<code"># First time setup:
# Visit https://api.yourdomain.com/_/
# Create admin email and password

# Create a "posts" collection:
# Admin → Collections → New Collection → "posts"
# Add fields:
# - title (text, required)
# - content (editor/text)
# - author (relation → users, required)
# - published (bool, default false)
# - created_at (auto date)

# API rules (set who can read/write):
# List/View: ""  (anyone can read)
# Create: "@request.auth.id != ''"  (logged-in users only)
# Update: "@request.auth.id = author"  (only the author)
# Delete: "@request.auth.id = author || @request.auth.verified = true"

Step 4: JavaScript SDK Integration

<code">npm install pocketbase
<code">import PocketBase from 'pocketbase';

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

// Authentication
await pb.collection('users').authWithPassword('user@example.com', 'password');
console.log(pb.authStore.isValid);    // true
console.log(pb.authStore.model.id);  // user ID

// CRUD operations
// Create a post
const newPost = await pb.collection('posts').create({
    title: 'Hello World',
    content: 'My first PocketBase post!',
    author: pb.authStore.model.id,
    published: true,
});

// List posts with filter and sort
const posts = await pb.collection('posts').getList(1, 20, {
    filter: 'published = true',
    sort: '-created',
    expand: 'author',   // Include author details
});
console.log(posts.items);

// Real-time subscriptions (SSE)
pb.collection('posts').subscribe('*', function(e) {
    console.log(e.action);   // "create", "update", "delete"
    console.log(e.record);   // The changed record
});

// File upload
const formData = new FormData();
formData.append('document', fileInput.files[0]);
const result = await pb.collection('files').create(formData);

Step 5: Custom Logic with Hooks

<code"># PocketBase can be extended with Go code using the jsvm or Go embed pattern
# For server-side hooks without recompiling, use the JS VM:

# pb_hooks/main.pb.js
onRecordBeforeCreateRequest((e) => {
    // Auto-set author to current user
    e.record.set("author", e.httpContext.get("authRecord")?.id);
}, "posts");

onRecordAfterCreateRequest((e) => {
    // Send webhook notification after post creation
    $http.send({
        url: "https://your-webhook.com/new-post",
        method: "POST",
        body: JSON.stringify({ title: e.record.get("title") }),
        headers: { "Content-Type": "application/json" },
    });
}, "posts");

Step 6: Backup

<code"># PocketBase data is in a single SQLite file:
# /opt/pocketbase/pb_data/data.db

# Backup (works while running — SQLite WAL mode):
sqlite3 /opt/pocketbase/pb_data/data.db ".backup /opt/backups/pb-$(date +%Y%m%d).db"

# Or use restic:
restic backup /opt/pocketbase/pb_data --tag pocketbase

# Admin UI backup: Settings → Export → downloads complete backup ZIP

Getting Started

PocketBase runs on literally any Ubuntu VPS at VPS.DO — even the smallest 512 MB RAM plan. At 32 MB RAM idle and a single file for all data, it’s the lightest-weight full BaaS available. For side projects, hackathon prototypes, and small production apps (under 10,000 active users), PocketBase eliminates the need to provision databases, configure auth, build file upload infrastructure, or write REST API boilerplate.

Conclusion

PocketBase compresses a full BaaS stack — database, REST API, realtime, authentication, file storage, and admin UI — into a single 30 MB binary that runs on 32 MB RAM. No containers, no dependencies, no configuration files beyond the admin UI. For developers who want to focus on frontend and product rather than backend infrastructure, PocketBase is the fastest path from database schema to functional API. Scale limits (SQLite on single server) are real, but for most applications, those limits are reached at millions of users — far beyond typical side project scale.

Post Your Comment

Fast • Reliable • Affordable VPS - DO It Now!

Get top VPS hosting with VPS.DO’s fast, low-cost plans. Try risk-free with our 7-day no-questions-asked refund and start today!