Open-source backend with embedded SQLite, real-time subscriptions, authentication, file storage, and admin dashboard — all in a single Go binary.
api.yourdomain.com)sudo apt update && sudo apt upgrade -y
sudo apt install -y wget unzip curl ufwRunning services as root is a security risk. Create a dedicated user for PocketBase.
sudo adduser --system --group --home /opt/pocketbase pocketbasePocketBase ships as a single precompiled binary. Download the latest release, extract, and install.
Check the PocketBase GitHub releases for the latest version.
cd /tmp
wget https://github.com/pocketbase/pocketbase/releases/download/v0.36.3/pocketbase_0.36.3_linux_amd64.zip
unzip pocketbase_0.36.3_linux_amd64.zip -d pocketbase💡 If your VPS uses an ARM64 processor, download the linux_arm64 variant instead.
sudo mv /tmp/pocketbase/pocketbase /opt/pocketbase/pocketbase
sudo chown -R pocketbase:pocketbase /opt/pocketbase
sudo chmod +x /opt/pocketbase/pocketbasesudo -u pocketbase /opt/pocketbase/pocketbase --versionpocketbase version 0.36.3Create a systemd unit file to keep PocketBase running persistently and start on boot.
sudo nano /etc/systemd/system/pocketbase.service[Unit]
Description=PocketBase Backend Service
After=network.target
[Service]
Type=simple
User=pocketbase
Group=pocketbase
WorkingDirectory=/opt/pocketbase
ExecStart=/opt/pocketbase/pocketbase serve --http=127.0.0.1:8090
Restart=on-failure
RestartSec=5
LimitNOFILE=4096
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target💡 The --http=127.0.0.1:8090 flag binds PocketBase to localhost only. External traffic flows through the Nginx reverse proxy.
sudo systemctl daemon-reload
sudo systemctl enable pocketbase
sudo systemctl start pocketbase
sudo systemctl status pocketbaseIf you encounter errors, check logs with journalctl -u pocketbase -f.
Place PocketBase behind Nginx for SSL termination, HTTP/2, and clean URLs.
sudo apt install -y nginx certbot python3-certbot-nginxsudo nano /etc/nginx/sites-available/pocketbaseserver {
listen 80;
listen [::]:80;
server_name api.yourdomain.com;
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;
}
}💡 The Upgrade and Connection headers are essential for PocketBase's real-time subscriptions via WebSocket.
sudo ln -s /etc/nginx/sites-available/pocketbase /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginxsudo certbot --nginx -d api.yourdomain.comCertbot automatically configures HTTPS, redirects HTTP, and sets up auto-renewal via systemd timer.
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow 'Nginx Full'
sudo ufw enable
sudo ufw status verbosePort 8090 is not opened because PocketBase only listens on localhost behind Nginx.
Access the admin dashboard to create your first superuser account.
Navigate to https://api.yourdomain.com/_/ in your browser. PocketBase will prompt you to create a superuser account.
sudo -u pocketbase /opt/pocketbase/pocketbase superuser create admin@yourdomain.com YourSecurePasswordThe admin dashboard at /_/ provides a GUI for managing collections (database tables), configuring auth providers, viewing logs, and adjusting mail and S3 storage settings.
PocketBase stores all data in a SQLite file at /opt/pocketbase/pb_data/data.db.
sudo nano /opt/pocketbase/backup.sh#!/bin/bash
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="/opt/pocketbase/backups"
mkdir -p "$BACKUP_DIR"
# Use SQLite online backup to safely copy the database
sqlite3 /opt/pocketbase/pb_data/data.db ".backup '$BACKUP_DIR/data_$TIMESTAMP.db'"
# Also archive uploaded files
tar -czf "$BACKUP_DIR/pb_data_$TIMESTAMP.tar.gz" -C /opt/pocketbase pb_data
# Remove backups older than 7 days
find "$BACKUP_DIR" -type f -mtime +7 -delete
echo "Backup completed: $TIMESTAMP"sudo chmod +x /opt/pocketbase/backup.sh
sudo chown pocketbase:pocketbase /opt/pocketbase/backup.shsudo crontab -u pocketbase -e0 3 * * * /opt/pocketbase/backup.sh >> /opt/pocketbase/backups/backup.log 2>&1For additional redundancy, consider using rsync or rclone to copy backups to offsite or S3-compatible storage.
Always create a backup before updating.
sudo systemctl stop pocketbase
sudo -u pocketbase /opt/pocketbase/pocketbase update
sudo systemctl start pocketbasesudo systemctl stop pocketbase
cd /tmp
wget https://github.com/pocketbase/pocketbase/releases/download/vX.X.X/pocketbase_X.X.X_linux_amd64.zip
unzip pocketbase_X.X.X_linux_amd64.zip -d pocketbase-update
sudo mv /tmp/pocketbase-update/pocketbase /opt/pocketbase/pocketbase
sudo chown pocketbase:pocketbase /opt/pocketbase/pocketbase
sudo systemctl start pocketbase⚠️ Check the PocketBase changelog before each update for breaking changes or migration steps.
Disable root login and password authentication.
sudo nano /etc/ssh/sshd_configPermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yessudo systemctl restart sshdEnsure you have uploaded your SSH public key before disabling password authentication.
sudo apt install -y fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2banAdd an IP-based restriction in your Nginx configuration to limit admin dashboard access.
location /_/ {
allow YOUR_IP_ADDRESS;
deny all;
proxy_pass http://127.0.0.1:8090;
proxy_http_version 1.1;
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;
}Replace YOUR_IP_ADDRESS with your static IP to restrict admin access while keeping the API publicly available.
journalctl -u pocketbase -f --no-pager -n 50Common causes: incorrect file permissions on /opt/pocketbase or a port conflict on 8090.
Verify PocketBase is running and that the Nginx proxy_pass address matches the --http flag in your systemd unit.
sudo certbot renew --dry-runEnsure ports 80 and 443 are open in UFW and Nginx is running.
Under heavy concurrent writes, increase the LimitNOFILE value in your systemd unit and ensure no external processes are accessing the database file directly.
Get started with a RamNode VPS for as little as $4/month.