Run PocketBase on fly.io
By Flavio Copes
Learn how to run PocketBase on fly.io with a Dockerfile, then attach a persistent volume with fly volumes create so your data survives deploys.
To run PocketBase on fly.io, you build a small Docker image that downloads the PocketBase binary, then deploy it with a persistent volume attached, so your data survives deploys.
PocketBase is an open source backend packed in a single executable. It gives you a database (SQLite), authentication, file storage, and an admin UI, all from one binary. That makes it a great fit for a tiny Fly machine.
First set up fly.io. See run an app on fly.io.
The Dockerfile
Create an empty folder, add this Dockerfile (update the PB_VERSION value to the latest version of PocketBase available):
FROM alpine:latest
ARG PB_VERSION=0.20.4
RUN apk add --no-cache \
unzip \
ca-certificates
# download and unzip PocketBase
ADD https://github.com/pocketbase/pocketbase/releases/download/v${PB_VERSION}/pocketbase_${PB_VERSION}_linux_amd64.zip /tmp/pb.zip
RUN unzip /tmp/pb.zip -d /pb/
# uncomment to copy the local pb_migrations dir into the image
# COPY ./pb_migrations /pb/pb_migrations
# uncomment to copy the local pb_hooks dir into the image
# COPY ./pb_hooks /pb/pb_hooks
EXPOSE 8080
# start PocketBase
CMD ["/pb/pocketbase", "serve", "--http=0.0.0.0:8080"]
The image downloads the release zip from GitHub, unzips the binary into /pb/, and starts the server on port 8080. Note the base image is Alpine, which is what the apk package manager belongs to.
Create the app and the volume
Run fly launch --build-only to create and build the app but not deploy it, as we need to attach a volume to persist data across deploys (but first we need to initialize it and the fly.toml file).
Why the volume? PocketBase writes everything to the pb_data folder: the SQLite database, uploaded files, all of it. The machine’s filesystem is rebuilt on every deploy, so without a volume you’d lose your data each time you ship a change.
Run fly volumes create pb_data --size=1 to create the volume. Create it in the same region of the app.
Now in fly.toml add:
[mounts]
destination = "/pb/pb_data"
source = "pb_data"
This mounts the volume at the exact path where PocketBase keeps its data.
Deploy
Now run fly deploy --ha=false.
The --ha=false flag matters. By default Fly creates two machines for redundancy, but a volume attaches to a single machine, and SQLite can’t be shared between two of them. One machine is what we want here.
PocketBase will be available at https://<yourapp>.fly.dev/_/. On the first visit you create the admin account, then you land in the admin UI where you define collections.
Only problem I had was internal connection URLs (.internal) in Fly. I haven’t found a way to make both IPv4 (used for external connection) work alongside IPv6 (used for internal connections), so in my app (also in Fly) I used the external URL (hope to fix).
Related posts about services: