How to Install PocketBase on a VPS

Most backend projects start the same way: you need a database, some auth, file storage and an API — and suddenly you’re stitching together five separate services before you’ve written a single line of your actual app. PocketBase flips that script entirely. It’s a single open-source binary that ships with a real-time database, built-in authentication, file storage and a clean REST API all bundled together. One binary. One port. Zero ceremony.

Running it on a VPS with Docker gives you the best of both worlds: the simplicity PocketBase was designed around plus the portability and upgrade safety that containerization brings. By the time you finish this guide, you’ll have a fully operational PocketBase instance sitting behind an Nginx reverse proxy with SSL — production-ready out of the box.

What Is PocketBase?

PocketBase is an open-source backend framework written in Go. Think of it as a self-hosted alternative to Firebase or Supabase — but without the cloud bill and without the vendor lock-in. It bundles SQLite as its database engine, which sounds modest until you realize SQLite handles millions of reads per day without breaking a sweat on modern hardware.

Out of the box you get collection-based data modeling, real-time subscriptions via server-sent events, OAuth2 and email/password authentication, file and media storage, and a slick admin dashboard UI accessible right from the browser. Developers use it to back mobile apps, internal tools, side projects and lightweight SaaS products. It’s especially popular in the indie dev community because the entire backend can live in a single folder.

Prerequisites

Before diving in, make sure your VPS meets the following requirements. PocketBase is impressively lean so even modest servers handle it well.

Requirement Minimum Recommended
OS Ubuntu 22.04 LTS Ubuntu 24.04 LTS
CPU 1 vCPU 2 vCPUs
RAM 512 MB 1 GB+
Disk 10 GB SSD 20 GB+ SSD
Network Public IPv4 address Public IPv4 address
Domain Optional (for SSL) Required for SSL/HTTPS

You’ll also need a non-root sudo user on the server, a domain name pointed at your VPS IP (for SSL), and ports 80 and 443 open in your firewall. That’s it.

Step 1: Update Your Server

Start clean. SSH into your VPS and pull in the latest package lists and security patches before touching anything else.

sudo apt update && sudo apt upgrade -y

Reboot if the kernel updated, then reconnect and move on.

sudo reboot

Step 2: Install Docker Engine

Skip the Ubuntu package repository version of Docker — it tends to lag several releases behind. Install directly from Docker’s official repository instead.

First, install the required packages to allow apt to fetch packages over HTTPS:

sudo apt install -y ca-certificates curl gnupg

Add Docker’s official GPG key:

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

Add the Docker repository to your apt sources:

echo /
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu /
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | /
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Now install Docker Engine and the Compose plugin:

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Add your user to the docker group so you don’t have to prefix every command with sudo:

sudo usermod -aG docker $USER
newgrp docker

Verify Docker is running:

docker --version
docker compose version

Step 3: Install Nginx

Nginx will act as the reverse proxy in front of PocketBase, handling SSL termination and forwarding public traffic to your container. Install it from the Ubuntu package manager:

sudo apt install -y nginx

Enable and start the Nginx service:

sudo systemctl enable nginx
sudo systemctl start nginx

Confirm it’s active:

sudo systemctl status nginx

Step 4: Configure the Firewall

Open the ports Nginx needs. PocketBase itself will never face the public internet directly — that’s Nginx’s job.

sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
sudo ufw status

You should see ports 22, 80 and 443 listed as allowed. Nothing else needs to be open.

Step 5: Set Up the Project Directory

Create a dedicated directory for PocketBase. Keeping all related files in one place makes backups and upgrades straightforward.

sudo mkdir -p /opt/pocketbase/pb_data
sudo mkdir -p /opt/pocketbase/pb_migrations
sudo chown -R $USER:$USER /opt/pocketbase
cd /opt/pocketbase

The pb_data directory is where PocketBase stores your SQLite database, uploaded files and logs. Mount it as a volume so your data survives container rebuilds.

Step 6: Create the Docker Compose File

Create a docker-compose.yml file in /opt/pocketbase:

nano /opt/pocketbase/docker-compose.yml

Paste in the following configuration:

services:
  pocketbase:
    image: ghcr.io/muchobien/pocketbase:latest
    container_name: pocketbase
    restart: unless-stopped
    ports:
      - "127.0.0.1:8090:8090"
    volumes:
      - ./pb_data:/pb/pb_data
      - ./pb_migrations:/pb/pb_migrations
    healthcheck:
      test: ["CMD", "wget", "--spider", "-q", "http://localhost:8090/api/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 10s

A few things worth noting here. The port binding 127.0.0.1:8090:8090 keeps PocketBase off the public internet — only Nginx can reach it via localhost. The restart: unless-stopped policy means the container comes back up automatically after a server reboot or a crash. And the healthcheck gives Docker a reliable way to verify PocketBase is actually responding before declaring the container healthy.

Save and close the file (Ctrl+X, then Y, then Enter in nano).

Step 7: Start PocketBase

Spin up the container in detached mode:

cd /opt/pocketbase
docker compose up -d

Docker pulls the image and starts the container. Give it a few seconds then check the status:

docker compose ps

You want to see healthy or running in the status column. You can also tail the logs to confirm PocketBase started cleanly:

docker compose logs -f

Look for a line similar to Server started at http://0.0.0.0:8090. That confirms PocketBase is up and listening. Press Ctrl+C to exit the log stream.

Step 8: Configure Nginx as a Reverse Proxy

Create a new Nginx server block for your domain. Replace your-domain.com with your actual domain throughout this section.

sudo nano /etc/nginx/sites-available/pocketbase

Paste in the following configuration:

server {
    listen 80;
    server_name your-domain.com;

    location / {
        proxy_pass http://127.0.0.1:8090;
        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;

        # Required for PocketBase real-time subscriptions (SSE)
        proxy_read_timeout 3600;
        proxy_buffering off;
        proxy_cache off;
        chunked_transfer_encoding on;
    }
}

The proxy_buffering off and proxy_read_timeout 3600 lines are important. PocketBase’s real-time subscriptions use server-sent events (SSE) — long-lived HTTP connections that Nginx would otherwise close or buffer incorrectly without these settings.

Enable the site and test the configuration:

sudo ln -s /etc/nginx/sites-available/pocketbase /etc/nginx/sites-enabled/
sudo nginx -t

You should see syntax is ok and test is successful. If not, recheck the config file for typos. Then reload Nginx:

sudo systemctl reload nginx

Step 9: Secure the Installation with SSL

Install Certbot and the Nginx plugin:

sudo apt install -y certbot python3-certbot-nginx

Run Certbot against your domain. It will automatically detect your Nginx config, request a certificate from Let’s Encrypt and rewrite the server block to redirect HTTP to HTTPS:

sudo certbot --nginx -d your-domain.com

Follow the prompts: enter your email address for renewal notifications and agree to the terms of service. Certbot handles everything else automatically.

Verify auto-renewal works:

sudo certbot renew --dry-run

A successful dry run means your certificates will renew automatically before they expire. No manual intervention needed.

Step 10: Create Your Admin Account

Open your browser and navigate to https://your-domain.com/_/. The trailing slash matters — that’s the path to the PocketBase admin dashboard.

PocketBase will prompt you to create a superuser account on first launch. Enter a valid email address and a strong password. This account has full control over all collections, settings and users so treat those credentials with care.

Once logged in, you’ll land on the admin dashboard. From here you can create collections (analogous to database tables), define field types, set up authentication rules, manage API access rules and browse your stored data — all without writing a single line of backend code.

Step 11: Verify the API Is Responding

PocketBase exposes a health endpoint you can hit from anywhere to confirm the API layer is functioning:

curl https://your-domain.com/api/health

A healthy instance returns:

{"code":200,"message":"API is healthy."}

That’s your green light. PocketBase is live, SSL is terminating correctly and Nginx is proxying traffic without issues.

How to Update PocketBase

Updating is painless with Docker Compose. Pull the latest image, stop the running container and restart it. Your data in pb_data is untouched because it lives in a mounted volume — not inside the container.

cd /opt/pocketbase
docker compose pull
docker compose down
docker compose up -d

Check the logs after restarting to confirm the new version started cleanly:

docker compose logs -f

PocketBase runs its own database migrations automatically on startup so you don’t need to run migration commands manually between versions. That said, always read the release notes before pulling a new major version — breaking changes do occasionally appear.

Troubleshooting

Container Exits Immediately After Starting

If docker compose ps shows the container has exited right after you brought it up, check the logs first:

docker compose logs pocketbase

The most common culprits are a permission problem on the pb_data directory or a port conflict. Verify directory ownership:

ls -la /opt/pocketbase/

If the ownership looks wrong, fix it and try again:

sudo chown -R $USER:$USER /opt/pocketbase
docker compose up -d

502 Bad Gateway from Nginx

A 502 means Nginx is running but can’t reach PocketBase on port 8090. First confirm the container is actually up:

docker compose ps
curl http://127.0.0.1:8090/api/health

If the curl fails, PocketBase isn’t listening. Restart the container. If the curl succeeds but Nginx still returns 502, check your Nginx config for a typo in the proxy_pass directive and confirm the port matches what’s defined in the Compose file.

Real-Time Subscriptions Disconnect Immediately

If SSE connections drop after a few seconds, Nginx is likely buffering the response. Open your Nginx config and verify these lines are present in the location / block:

proxy_buffering off;
proxy_cache off;
proxy_read_timeout 3600;
chunked_transfer_encoding on;

After editing, test and reload Nginx:

sudo nginx -t && sudo systemctl reload nginx

Admin Dashboard Returns a Blank Page

Make sure you’re navigating to https://your-domain.com/_/ with the trailing slash. Without it, the redirect to the admin UI can fail depending on how your browser handles the redirect. If the page still loads blank, clear your browser cache or try an incognito window. A cached 301 redirect from an earlier HTTP-only setup is a common cause.

SSL Certificate Not Issuing

Certbot needs port 80 open and your domain’s DNS pointing to the correct server IP before it can issue a certificate. Verify DNS propagation first:

dig +short your-domain.com

The returned IP should match your VPS. If DNS isn’t propagated yet, wait and try again. Also confirm UFW allows port 80:

sudo ufw status

Both 80/tcp and 443/tcp need to show as ALLOW.

What to Build Next

With PocketBase running, you’ve got a production-grade backend ready to power real applications. A few natural next steps worth exploring:

  • Connect a frontend framework — PocketBase ships official SDKs for JavaScript and Dart. Pair it with a SvelteKit or Next.js frontend and you have a full-stack app with very little infrastructure to manage.
  • Set up automated backups — The entire database lives in a single SQLite file inside pb_data. A simple cron job copying that directory to object storage (S3, Backblaze B2, etc.) gives you point-in-time recovery without a complex backup strategy.
  • Harden authentication rules — Visit the Collections section of the admin dashboard and tighten the API rules for each collection. By default PocketBase is open — restrict read and write access based on user roles before going live.
  • Add a monitoring stack — Pair PocketBase with Uptime Kuma (easily deployed as a second Docker container) to get uptime alerts and a public status page with minimal overhead.

PocketBase proves that backend infrastructure doesn’t have to be complicated. A single Go binary running in a container gives you everything most apps actually need — authentication, data storage, file handling and a real-time API — without the operational overhead of managing separate services. Self-hosting it on your own VPS keeps your data under your control and your costs predictable. That’s a combination worth building on.

The post How to Install PocketBase on a VPS appeared first on GreenGeeks.

版权声明:
作者:zhangchen
链接:https://www.techfm.club/p/236977.html
来源:TechFM
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>