Self-Hosting Guide: Deploy PocketBase as Your Backend
·OSSAlt Team
pocketbasebackendself-hostingguide
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
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
}
sudo systemctl restart caddy
Step 3: Create Admin Account
- Open
https://api.yourdomain.com/_/ - Create your admin account on first visit
Step 4: Create Collections (Tables)
In the admin UI:
- Click New collection
- Name it (e.g.,
posts) - 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 |
- 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
- List/Search:
Step 5: Authentication
PocketBase includes built-in auth:
Email/password (default):
import PocketBase from 'pocketbase'
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)
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' })
Step 6: Use the API
import PocketBase from 'pocketbase'
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)
Step 7: Set Up as a Systemd Service
sudo nano /etc/systemd/system/pocketbase.service
[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
sudo systemctl enable pocketbase
sudo systemctl start pocketbase
Step 8: Configure SMTP
In Admin UI → Settings → Mail 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'
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
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.