PocketBase as a standalone database server
CI / Test (ubuntu-latest) (push) Canceled after 0s
CI / Test (windows-latest) (push) Canceled after 0s
CI / Storage tests on PostgreSQL (push) Canceled after 0s
CI / Complement (federation off) (push) Canceled after 0s
CI / golangci-lint (push) Canceled after 0s
CI / Smoke test the binary (push) Canceled after 0s
CI / Admin panel (push) Canceled after 0s
CI / Web client (push) Canceled after 0s
CI / Desktop client (ubuntu-24.04) (push) Canceled after 0s
CI / Desktop client (windows-latest) (push) Canceled after 0s

The pocketbase driver no longer embeds PocketBase: Warp keeps its data as
PocketBase collections on a server of its own and reaches it only through
the REST API, the way the postgres driver reaches PostgreSQL.
database.connection_string is the server's URL, and Warp signs in as the
superuser in WARP_PB_SUPERUSER_EMAIL / WARP_PB_SUPERUSER_PASSWORD (or a
WARP_PB_SUPERUSER_FILE of the two).

Every SQL table is a superuser-only collection of the same name and
columns, created by warp migrate. Reads go through PocketBase's SQL
endpoint with the SQL drivers' queries, via a read-only database/sql
driver that inlines arguments, moves long ones into warp_params and pages
past 1000 rows. Writes are record operations in batch requests under one
write lock in the Warp process. Media is a protected file field in
warp_media, local or in the S3 bucket Warp writes into PocketBase's
settings. Search matches word prefixes with LIKE. The storage tests run
against an in-process PocketBase and pass as on SQLite.

Docker: the PocketBase stacks get a pocketbase service running
tajniak81/pocketbase-docker-root (WARP_PB_IMAGE), with a pb-data volume
and its admin UI on loopback; the AIO images run that PocketBase binary
as a process beside the homeserver, making up a superuser when none is
set. The .env examples, READMEs, docs and warp.yaml.example follow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
tajniak81andClaude Opus 5.5 committed 2026-10-26 16:31:08 +01:00
1 parent 0994156705
commit a47e15cc1c
69 files changed
+8209 -374

No files matched your search

+15 -1
View File
@@ -20,10 +20,24 @@ WARP_PORT=8008
WARP_ADMIN_PORT=8009
WARP_WEB_PORT=8080
# PocketBase's port, for its admin UI at http://localhost:8070/_/. It is
# on loopback unless the bind address says otherwise; put the UI behind a
# reverse proxy before binding it to 0.0.0.0.
WARP_PB_BIND=127.0.0.1
WARP_PB_PORT=8070
# The PocketBase superuser the homeserver signs in as, and so can you, in
# the admin UI. Its password is set to this one on every start, and needs 8
# characters or more. Empty: the container makes one up on first start and
# keeps it in /data/pocketbase-superuser.env.
WARP_PB_SUPERUSER_EMAIL=
WARP_PB_SUPERUSER_PASSWORD=
# Where the data lives. Empty keeps the named volume in brackets; a
# host path (starting with . or /) bind-mounts that directory instead.
# The container runs as UID 10001, so its directory must be writable by it.
# The homeserver's /data (warp-data).
# The container's /data (warp-data): the signing key, and PocketBase's
# pb_data, with the database and media unless it is in S3.
WARP_DATA_VOLUME=
# ------------------------------------------------------------------- aio
+15 -1
View File
@@ -25,10 +25,24 @@ WARP_WEB_PORT=8080
WARP_REGISTRY=10.2.1.10:5500/admin
WARP_VERSION=latest
# PocketBase's port, for its admin UI at http://localhost:8070/_/. It is
# on loopback unless the bind address says otherwise; put the UI behind a
# reverse proxy before binding it to 0.0.0.0.
WARP_PB_BIND=127.0.0.1
WARP_PB_PORT=8070
# The PocketBase superuser the homeserver signs in as, and so can you, in
# the admin UI. Its password is set to this one on every start, and needs 8
# characters or more. Empty: the container makes one up on first start and
# keeps it in /data/pocketbase-superuser.env.
WARP_PB_SUPERUSER_EMAIL=
WARP_PB_SUPERUSER_PASSWORD=
# Where the data lives. Empty keeps the named volume in brackets; a
# host path (starting with . or /) bind-mounts that directory instead.
# The container runs as UID 10001, so its directory must be writable by it.
# The homeserver's /data (warp-data).
# The container's /data (warp-data): the signing key, and PocketBase's
# pb_data, with the database and media unless it is in S3.
WARP_DATA_VOLUME=
# ------------------------------------------------------------------- aio
+16 -2
View File
@@ -23,10 +23,24 @@ WARP_PORT=8008
WARP_ADMIN_PORT=8009
WARP_WEB_PORT=8080
# PocketBase's port, for its admin UI at http://localhost:8070/_/. It is
# on loopback unless the bind address says otherwise; put the UI behind a
# reverse proxy before binding it to 0.0.0.0.
WARP_PB_BIND=127.0.0.1
WARP_PB_PORT=8070
# The PocketBase superuser the homeserver signs in as, and so can you, in
# the admin UI. Its password is set to this one on every start, and needs 8
# characters or more. Empty: the container makes one up on first start and
# keeps it in /data/pocketbase-superuser.env.
WARP_PB_SUPERUSER_EMAIL=
WARP_PB_SUPERUSER_PASSWORD=
# Where the data lives. Empty keeps the named volume in brackets; a
# host path (starting with . or /) bind-mounts that directory instead.
# The container runs as UID 10001, so its directory must be writable by it.
# The homeserver's /data (warp-data).
# The container's /data (warp-data): the signing key, and PocketBase's
# pb_data, with the database and media unless it is in S3.
WARP_DATA_VOLUME=
# ------------------------------------------------------------------- aio
@@ -37,7 +51,7 @@ WARP_AIO_WEB=true
# ------------------------------------------------------------- media (S3)
# Media goes to this bucket; the database stays in /data/pb_data. The bucket
# Media goes to this bucket; the database stays in PocketBase. The bucket
# must already exist: nothing here runs a gateway or creates it. For a
# gateway on the Docker host, use http://host.docker.internal:8333. Media
# stored before S3 was on is not moved into the bucket.
+16 -2
View File
@@ -28,10 +28,24 @@ WARP_WEB_PORT=8080
WARP_REGISTRY=10.2.1.10:5500/admin
WARP_VERSION=latest
# PocketBase's port, for its admin UI at http://localhost:8070/_/. It is
# on loopback unless the bind address says otherwise; put the UI behind a
# reverse proxy before binding it to 0.0.0.0.
WARP_PB_BIND=127.0.0.1
WARP_PB_PORT=8070
# The PocketBase superuser the homeserver signs in as, and so can you, in
# the admin UI. Its password is set to this one on every start, and needs 8
# characters or more. Empty: the container makes one up on first start and
# keeps it in /data/pocketbase-superuser.env.
WARP_PB_SUPERUSER_EMAIL=
WARP_PB_SUPERUSER_PASSWORD=
# Where the data lives. Empty keeps the named volume in brackets; a
# host path (starting with . or /) bind-mounts that directory instead.
# The container runs as UID 10001, so its directory must be writable by it.
# The homeserver's /data (warp-data).
# The container's /data (warp-data): the signing key, and PocketBase's
# pb_data, with the database and media unless it is in S3.
WARP_DATA_VOLUME=
# ------------------------------------------------------------------- aio
@@ -42,7 +56,7 @@ WARP_AIO_WEB=true
# ------------------------------------------------------------- media (S3)
# Media goes to this bucket; the database stays in /data/pb_data. The bucket
# Media goes to this bucket; the database stays in PocketBase. The bucket
# must already exist: nothing here runs a gateway or creates it. For a
# gateway on the Docker host, use http://host.docker.internal:8333. Media
# stored before S3 was on is not moved into the bucket.
+16 -2
View File
@@ -22,10 +22,24 @@ WARP_PORT=8008
WARP_ADMIN_PORT=8009
WARP_WEB_PORT=8080
# PocketBase's port, for its admin UI at http://localhost:8070/_/. It is
# on loopback unless the bind address says otherwise; put the UI behind a
# reverse proxy before binding it to 0.0.0.0.
WARP_PB_BIND=127.0.0.1
WARP_PB_PORT=8070
# The PocketBase superuser the homeserver signs in as, and so can you, in
# the admin UI. Its password is set to this one on every start, and needs 8
# characters or more. Empty: the container makes one up on first start and
# keeps it in /data/pocketbase-superuser.env.
WARP_PB_SUPERUSER_EMAIL=
WARP_PB_SUPERUSER_PASSWORD=
# Where the data lives. Empty keeps the named volume in brackets; a
# host path (starting with . or /) bind-mounts that directory instead.
# The container runs as UID 10001, so its directory must be writable by it.
# The homeserver's /data (warp-data).
# The container's /data (warp-data): the signing key, and PocketBase's
# pb_data, with the database and media unless it is in S3.
WARP_DATA_VOLUME=
# SeaweedFS's data (seaweed-data).
SEAWEED_DATA_VOLUME=
@@ -39,7 +53,7 @@ WARP_AIO_WEB=true
# -------------------------------------------------------------- seaweedfs
# Media goes to this bucket in SeaweedFS, created on start; the database
# stays in /data/pb_data. The key pair is the homeserver's S3 identity:
# stays in PocketBase. The key pair is the homeserver's S3 identity:
# the gateway's only one, and what the homeserver signs with.
# Media stored before S3 was on is not moved into the bucket.
WARP_PB_S3_BUCKET=warp
@@ -27,10 +27,24 @@ WARP_WEB_PORT=8080
WARP_REGISTRY=10.2.1.10:5500/admin
WARP_VERSION=latest
# PocketBase's port, for its admin UI at http://localhost:8070/_/. It is
# on loopback unless the bind address says otherwise; put the UI behind a
# reverse proxy before binding it to 0.0.0.0.
WARP_PB_BIND=127.0.0.1
WARP_PB_PORT=8070
# The PocketBase superuser the homeserver signs in as, and so can you, in
# the admin UI. Its password is set to this one on every start, and needs 8
# characters or more. Empty: the container makes one up on first start and
# keeps it in /data/pocketbase-superuser.env.
WARP_PB_SUPERUSER_EMAIL=
WARP_PB_SUPERUSER_PASSWORD=
# Where the data lives. Empty keeps the named volume in brackets; a
# host path (starting with . or /) bind-mounts that directory instead.
# The container runs as UID 10001, so its directory must be writable by it.
# The homeserver's /data (warp-data).
# The container's /data (warp-data): the signing key, and PocketBase's
# pb_data, with the database and media unless it is in S3.
WARP_DATA_VOLUME=
# SeaweedFS's data (seaweed-data).
SEAWEED_DATA_VOLUME=
@@ -44,7 +58,7 @@ WARP_AIO_WEB=true
# -------------------------------------------------------------- seaweedfs
# Media goes to this bucket in SeaweedFS, created on start; the database
# stays in /data/pb_data. The key pair is the homeserver's S3 identity:
# stays in PocketBase. The key pair is the homeserver's S3 identity:
# the gateway's only one, and what the homeserver signs with.
# Media stored before S3 was on is not moved into the bucket.
WARP_PB_S3_BUCKET=warp
@@ -23,10 +23,24 @@ WARP_PORT=8008
WARP_ADMIN_PORT=8009
WARP_WEB_PORT=8080
# PocketBase's port, for its admin UI at http://localhost:8070/_/. It is
# on loopback unless the bind address says otherwise; put the UI behind a
# reverse proxy before binding it to 0.0.0.0.
WARP_PB_BIND=127.0.0.1
WARP_PB_PORT=8070
# The PocketBase superuser the homeserver signs in as, and so can you, in
# the admin UI. Its password is set to this one on every start, and needs 8
# characters or more. Empty: the container makes one up on first start and
# keeps it in /data/pocketbase-superuser.env.
WARP_PB_SUPERUSER_EMAIL=
WARP_PB_SUPERUSER_PASSWORD=
# Where the data lives. Empty keeps the named volume in brackets; a
# host path (starting with . or /) bind-mounts that directory instead.
# The container runs as UID 10001, so its directory must be writable by it.
# The homeserver's /data (warp-data).
# The container's /data (warp-data): the signing key, and PocketBase's
# pb_data, with the database and media unless it is in S3.
WARP_DATA_VOLUME=
# SeaweedFS's data (seaweed-data).
SEAWEED_DATA_VOLUME=
@@ -42,7 +56,7 @@ WARP_AIO_WEB=true
# -------------------------------------------------------------- seaweedfs
# Media goes to this bucket in SeaweedFS, created on start; the database
# stays in /data/pb_data. The key pair is the homeserver's S3 identity:
# stays in PocketBase. The key pair is the homeserver's S3 identity:
# written into the filer's IAM store on every start, beside any identity
# added in the admin UI, so a new secret here lands on the next start.
# Media stored before S3 was on is not moved into the bucket.
@@ -28,10 +28,24 @@ WARP_WEB_PORT=8080
WARP_REGISTRY=10.2.1.10:5500/admin
WARP_VERSION=latest
# PocketBase's port, for its admin UI at http://localhost:8070/_/. It is
# on loopback unless the bind address says otherwise; put the UI behind a
# reverse proxy before binding it to 0.0.0.0.
WARP_PB_BIND=127.0.0.1
WARP_PB_PORT=8070
# The PocketBase superuser the homeserver signs in as, and so can you, in
# the admin UI. Its password is set to this one on every start, and needs 8
# characters or more. Empty: the container makes one up on first start and
# keeps it in /data/pocketbase-superuser.env.
WARP_PB_SUPERUSER_EMAIL=
WARP_PB_SUPERUSER_PASSWORD=
# Where the data lives. Empty keeps the named volume in brackets; a
# host path (starting with . or /) bind-mounts that directory instead.
# The container runs as UID 10001, so its directory must be writable by it.
# The homeserver's /data (warp-data).
# The container's /data (warp-data): the signing key, and PocketBase's
# pb_data, with the database and media unless it is in S3.
WARP_DATA_VOLUME=
# SeaweedFS's data (seaweed-data).
SEAWEED_DATA_VOLUME=
@@ -47,7 +61,7 @@ WARP_AIO_WEB=true
# -------------------------------------------------------------- seaweedfs
# Media goes to this bucket in SeaweedFS, created on start; the database
# stays in /data/pb_data. The key pair is the homeserver's S3 identity:
# stays in PocketBase. The key pair is the homeserver's S3 identity:
# written into the filer's IAM store on every start, beside any identity
# added in the admin UI, so a new secret here lands on the next start.
# Media stored before S3 was on is not moved into the bucket.
+14 -5
View File
@@ -1,7 +1,8 @@
# warp-aio-pocketbase — the homeserver, the admin panel and the web client
# in one image, on PocketBase. PocketBase is the homeserver's embedded
# database driver: its data directory, with media in its storage, is
# /data/pb_data. Set WARP_PB_S3_* to keep media in an S3 bucket instead.
# in one image, on PocketBase. PocketBase runs as a process of its own in
# the container, on port 8070, with its pb_data — the database, and media
# in its storage — in /data/pb_data. Set WARP_PB_S3_* to keep media in an
# S3 bucket instead.
#
# Build from the repository root:
#
@@ -11,6 +12,10 @@
#
# The database, signing key and media live in /data; mount a volume on it.
# PocketBase itself: the binary of this image, PocketBase 0.40 or later.
ARG PB_IMAGE=tajniak81/pocketbase-docker-root:latest
FROM ${PB_IMAGE} AS pocketbase
FROM node:22-alpine AS web
WORKDIR /src
@@ -74,6 +79,8 @@ RUN apk add --no-cache ca-certificates tzdata curl tini && \
adduser -D -u 10001 -h /data warp
COPY --from=build /out/warp /out/warp-admin /out/warp-web /usr/local/bin/
# PocketBase, from the same image the separate-container stacks run.
COPY --from=pocketbase /pb/pocketbase /usr/local/bin/pocketbase
COPY warp.yaml.example /etc/warp/warp.yaml.example
COPY --chmod=755 Docker-AIO/entrypoint.sh /usr/local/bin/warp-aio
@@ -85,7 +92,7 @@ USER warp
ENV WARP_LISTEN_ADDRESS=":8008" \
WARP_PRIVATE_KEY="/data/signing.key" \
WARP_DB_DRIVER="pocketbase" \
WARP_DB_CONNECTION_STRING="/data/pb_data" \
WARP_DB_CONNECTION_STRING="http://127.0.0.1:8070" \
WARP_LOG_FORMAT="json" \
WARP_ADMIN_LISTEN=":8009" \
WARP_ADMIN_HOMESERVER="http://127.0.0.1:8008" \
@@ -95,9 +102,11 @@ ENV WARP_LISTEN_ADDRESS=":8008" \
WARP_WEB_LOG_FORMAT="json" \
WARP_AIO_ADMIN="true" \
WARP_AIO_WEB="true" \
WARP_AIO_POCKETBASE="true" \
WARP_PB_SUPERUSER_FILE="/data/pocketbase-superuser.env" \
WARP_AIO_EMBEDDED_POSTGRES="false"
EXPOSE 8008 8009 8080
EXPOSE 8008 8009 8080 8070
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
CMD curl -fsS http://127.0.0.1:8008/healthz && \
+12 -3
View File
@@ -1,7 +1,8 @@
# warp-aio-pocketbase-seaweedfs — the homeserver, the admin panel and the
# web client on PocketBase, with SeaweedFS in the same image as the media
# store: one `weed server -s3` process, master, volume, filer and S3 gateway
# in one. The homeserver keeps its database in /data/pb_data and its media
# in one. PocketBase runs beside the homeserver, its database in
# /data/pb_data; the homeserver keeps its media
# in the bucket WARP_PB_S3_BUCKET (default warp) on the gateway at
# 127.0.0.1:8333. For per-role processes and SeaweedFS's admin UI, see
# Dockerfile.PocketBase.SeaweedFS.split.
@@ -31,6 +32,10 @@
# it.
ARG SEAWEED_VERSION="4.45"
# PocketBase itself: the binary of this image, PocketBase 0.40 or later.
ARG PB_IMAGE=tajniak81/pocketbase-docker-root:latest
FROM ${PB_IMAGE} AS pocketbase
FROM node:22-alpine AS web
WORKDIR /src
@@ -98,6 +103,8 @@ RUN apk add --no-cache ca-certificates tzdata curl tini && \
adduser -D -u 10001 -h /data warp
COPY --from=build /out/warp /out/warp-admin /out/warp-web /usr/local/bin/
# PocketBase, from the same image the separate-container stacks run.
COPY --from=pocketbase /pb/pocketbase /usr/local/bin/pocketbase
COPY --from=seaweed /usr/bin/weed /usr/local/bin/weed
COPY warp.yaml.example /etc/warp/warp.yaml.example
COPY --chmod=755 Docker-AIO/entrypoint.sh /usr/local/bin/warp-aio
@@ -116,7 +123,7 @@ USER warp
ENV WARP_LISTEN_ADDRESS=":8008" \
WARP_PRIVATE_KEY="/data/signing.key" \
WARP_DB_DRIVER="pocketbase" \
WARP_DB_CONNECTION_STRING="/data/pb_data" \
WARP_DB_CONNECTION_STRING="http://127.0.0.1:8070" \
WARP_PB_S3_ENABLED="true" \
WARP_PB_S3_ENDPOINT="http://127.0.0.1:8333" \
WARP_PB_S3_BUCKET="warp" \
@@ -131,10 +138,12 @@ ENV WARP_LISTEN_ADDRESS=":8008" \
WARP_WEB_LOG_FORMAT="json" \
WARP_AIO_ADMIN="true" \
WARP_AIO_WEB="true" \
WARP_AIO_POCKETBASE="true" \
WARP_PB_SUPERUSER_FILE="/data/pocketbase-superuser.env" \
WARP_AIO_EMBEDDED_POSTGRES="false" \
WARP_AIO_SEAWEEDFS="server"
EXPOSE 8008 8009 8080 8333
EXPOSE 8008 8009 8080 8070 8333
# Every process must answer, so a wedged one shows in `docker ps`.
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
@@ -38,6 +38,10 @@
# it.
ARG SEAWEED_VERSION="4.45"
# PocketBase itself: the binary of this image, PocketBase 0.40 or later.
ARG PB_IMAGE=tajniak81/pocketbase-docker-root:latest
FROM ${PB_IMAGE} AS pocketbase
FROM node:22-alpine AS web
WORKDIR /src
@@ -105,6 +109,8 @@ RUN apk add --no-cache ca-certificates tzdata curl tini && \
adduser -D -u 10001 -h /data warp
COPY --from=build /out/warp /out/warp-admin /out/warp-web /usr/local/bin/
# PocketBase, from the same image the separate-container stacks run.
COPY --from=pocketbase /pb/pocketbase /usr/local/bin/pocketbase
COPY --from=seaweed /usr/bin/weed /usr/local/bin/weed
COPY warp.yaml.example /etc/warp/warp.yaml.example
COPY --chmod=755 Docker-AIO/entrypoint.sh /usr/local/bin/warp-aio
@@ -124,7 +130,7 @@ USER warp
ENV WARP_LISTEN_ADDRESS=":8008" \
WARP_PRIVATE_KEY="/data/signing.key" \
WARP_DB_DRIVER="pocketbase" \
WARP_DB_CONNECTION_STRING="/data/pb_data" \
WARP_DB_CONNECTION_STRING="http://127.0.0.1:8070" \
WARP_PB_S3_ENABLED="true" \
WARP_PB_S3_ENDPOINT="http://127.0.0.1:8333" \
WARP_PB_S3_BUCKET="warp" \
@@ -139,11 +145,13 @@ ENV WARP_LISTEN_ADDRESS=":8008" \
WARP_WEB_LOG_FORMAT="json" \
WARP_AIO_ADMIN="true" \
WARP_AIO_WEB="true" \
WARP_AIO_POCKETBASE="true" \
WARP_PB_SUPERUSER_FILE="/data/pocketbase-superuser.env" \
WARP_AIO_EMBEDDED_POSTGRES="false" \
WARP_AIO_SEAWEEDFS="split" \
WEED_ADMIN_USER="admin"
EXPOSE 8008 8009 8080 8333 23646
EXPOSE 8008 8009 8080 8070 8333 23646
# Every process must answer, so a wedged one shows in `docker ps`.
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
+12 -4
View File
@@ -1,7 +1,7 @@
# warp-aio-pocketbase-s3 — the homeserver, the admin panel and the web client
# in one image, on PocketBase, with media in an S3 bucket that already exists
# somewhere else: AWS, MinIO, a SeaweedFS on another host. The database stays
# in /data/pb_data. For a SeaweedFS that comes up inside the container, see
# somewhere else: AWS, MinIO, a SeaweedFS on another host. PocketBase runs
# beside the homeserver, its database in /data/pb_data. For a SeaweedFS that comes up inside the container, see
# Dockerfile.PocketBase.SeaweedFS.
#
# Build from the repository root:
@@ -19,6 +19,10 @@
# WARP_PB_S3_FORCE_PATH_STYLE=false for AWS S3 proper. The container waits up
# to 30 seconds for the endpoint to answer before it starts the homeserver.
# PocketBase itself: the binary of this image, PocketBase 0.40 or later.
ARG PB_IMAGE=tajniak81/pocketbase-docker-root:latest
FROM ${PB_IMAGE} AS pocketbase
FROM node:22-alpine AS web
WORKDIR /src
@@ -82,6 +86,8 @@ RUN apk add --no-cache ca-certificates tzdata curl tini && \
adduser -D -u 10001 -h /data warp
COPY --from=build /out/warp /out/warp-admin /out/warp-web /usr/local/bin/
# PocketBase, from the same image the separate-container stacks run.
COPY --from=pocketbase /pb/pocketbase /usr/local/bin/pocketbase
COPY warp.yaml.example /etc/warp/warp.yaml.example
COPY --chmod=755 Docker-AIO/entrypoint.sh /usr/local/bin/warp-aio
@@ -94,7 +100,7 @@ USER warp
ENV WARP_LISTEN_ADDRESS=":8008" \
WARP_PRIVATE_KEY="/data/signing.key" \
WARP_DB_DRIVER="pocketbase" \
WARP_DB_CONNECTION_STRING="/data/pb_data" \
WARP_DB_CONNECTION_STRING="http://127.0.0.1:8070" \
WARP_PB_S3_ENABLED="true" \
WARP_PB_S3_BUCKET="warp" \
WARP_PB_S3_REGION="us-east-1" \
@@ -108,9 +114,11 @@ ENV WARP_LISTEN_ADDRESS=":8008" \
WARP_WEB_LOG_FORMAT="json" \
WARP_AIO_ADMIN="true" \
WARP_AIO_WEB="true" \
WARP_AIO_POCKETBASE="true" \
WARP_PB_SUPERUSER_FILE="/data/pocketbase-superuser.env" \
WARP_AIO_EMBEDDED_POSTGRES="false"
EXPOSE 8008 8009 8080
EXPOSE 8008 8009 8080 8070
HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
CMD curl -fsS http://127.0.0.1:8008/healthz && \
+12 -1
View File
@@ -8,7 +8,7 @@ policy brings the set back.
| Dockerfile | Image | Database |
| --- | --- | --- |
| [`Dockerfile`](Dockerfile) | `warp-aio` | SQLite, `/data/warp.db` |
| [`Dockerfile.PocketBase`](Dockerfile.PocketBase) | `warp-aio-pocketbase` | PocketBase (embedded driver), `/data/pb_data` |
| [`Dockerfile.PocketBase`](Dockerfile.PocketBase) | `warp-aio-pocketbase` | PocketBase, a process in the container, `/data/pb_data` |
| [`Dockerfile.PostgreSQL`](Dockerfile.PostgreSQL) | `warp-aio-postgresql` | PostgreSQL 17 in the container, `/data/postgres` |
| [`Dockerfile.PocketBase.s3`](Dockerfile.PocketBase.s3) | `warp-aio-pocketbase-s3` | PocketBase, media in an existing S3 bucket elsewhere |
| [`Dockerfile.PocketBase.SeaweedFS`](Dockerfile.PocketBase.SeaweedFS) | `warp-aio-pocketbase-seaweedfs` | PocketBase, media in SeaweedFS (`weed server -s3`) in the container |
@@ -42,6 +42,17 @@ inside the container, so it needs no password and is not reachable from
outside. To point that image at a PostgreSQL elsewhere instead, set
`WARP_AIO_EMBEDDED_POSTGRES=false` and `WARP_DB_CONNECTION_STRING`.
The four PocketBase images run PocketBase as a process of its own beside
the homeserver, the binary taken from `tajniak81/pocketbase-docker-root`
(the `PB_IMAGE` build argument picks another, PocketBase 0.40 or later).
Its `pb_data` is `/data/pb_data`, and its admin UI is on `:8070`,
published on loopback. The homeserver signs in as the superuser in
`WARP_PB_SUPERUSER_EMAIL` and `WARP_PB_SUPERUSER_PASSWORD`, whose password
is set again on every start; without them, the first start makes one up
and keeps it in `/data/pocketbase-superuser.env`, where the admin UI's
login can be read back. To point an image at a PocketBase elsewhere, set
`WARP_AIO_POCKETBASE=false` and `WARP_DB_CONNECTION_STRING`.
The Dockerfiles share their build stages line for line; only the header,
the SeaweedFS stage and the final stage differ. Keep the build stages in
step when changing one.
@@ -5,9 +5,11 @@
# cp .env.pocketbase.prod.example .env # then edit it
# docker compose -f docker-compose.pocketbase.prod.yml up -d
#
# PocketBase is embedded in the homeserver (the pocketbase database driver):
# its data directory, with media in its storage, is /data/pb_data in the
# warp-data volume. Set WARP_PB_S3_* in .env to keep media in an
# PocketBase runs in the container as a server of its own, which the
# homeserver signs in to as the superuser in .env (or one the container
# makes up, kept in /data/pocketbase-superuser.env): its pb_data, with media
# in its storage, is /data/pb_data in the warp-data volume. Its admin UI is
# http://localhost:8070/_/ on loopback. Set WARP_PB_S3_* in .env to keep media in an
# S3 bucket instead (docs/configuration.md).
#
# Homeserver http://localhost:8008, admin panel http://localhost:8009, web
@@ -37,6 +39,7 @@ services:
- "${WARP_PORT:-8008}:8008"
- "${WARP_ADMIN_PORT:-8009}:8009"
- "${WARP_WEB_PORT:-8080}:8080"
- "${WARP_PB_BIND:-127.0.0.1}:${WARP_PB_PORT:-8070}:8070"
volumes:
warp-data:
@@ -6,7 +6,8 @@
# cp .env.pocketbase.s3.prod.example .env # then edit it
# docker compose -f docker-compose.pocketbase.s3.prod.yml up -d
#
# The database stays in /data/pb_data (warp-data); media goes to the bucket
# PocketBase runs in the container, its database in /data/pb_data
# (warp-data), admin UI on loopback at http://localhost:8070/_/; media goes to the bucket
# WARP_PB_S3_BUCKET (default warp) on WARP_PB_S3_ENDPOINT, which must already
# exist: nothing here runs a gateway or creates the bucket. For a gateway on
# this Docker host, use http://host.docker.internal:8333; the host entry below
@@ -54,6 +55,7 @@ services:
- "${WARP_PORT:-8008}:8008"
- "${WARP_ADMIN_PORT:-8009}:8009"
- "${WARP_WEB_PORT:-8080}:8080"
- "${WARP_PB_BIND:-127.0.0.1}:${WARP_PB_PORT:-8070}:8070"
volumes:
warp-data:
+3 -1
View File
@@ -6,7 +6,8 @@
# cp .env.pocketbase.s3.example .env # then edit it
# docker compose -f docker-compose.pocketbase.s3.yml up -d --build
#
# The database stays in /data/pb_data (warp-data); media goes to the bucket
# PocketBase runs in the container, its database in /data/pb_data
# (warp-data), admin UI on loopback at http://localhost:8070/_/; media goes to the bucket
# WARP_PB_S3_BUCKET (default warp) on WARP_PB_S3_ENDPOINT, which must already
# exist: nothing here runs a gateway or creates the bucket. For a gateway on
# this Docker host, use http://host.docker.internal:8333; the host entry below
@@ -50,6 +51,7 @@ services:
- "${WARP_PORT:-8008}:8008"
- "${WARP_ADMIN_PORT:-8009}:8009"
- "${WARP_WEB_PORT:-8080}:8080"
- "${WARP_PB_BIND:-127.0.0.1}:${WARP_PB_PORT:-8070}:8070"
volumes:
warp-data:
@@ -7,7 +7,8 @@
# cp .env.pocketbase.seaweedfs.prod.example .env # then edit it
# docker compose -f docker-compose.pocketbase.seaweedfs.prod.yml up -d
#
# The database stays in /data/pb_data (warp-data); media goes to the bucket
# PocketBase runs in the container, its database in /data/pb_data
# (warp-data), admin UI on loopback at http://localhost:8070/_/; media goes to the bucket
# WARP_PB_S3_BUCKET in SeaweedFS (seaweed-data), whose gateway has exactly
# one identity: the homeserver's. Media stored before S3 was on is not moved
# into the bucket.
@@ -56,6 +57,7 @@ services:
- "${WARP_PORT:-8008}:8008"
- "${WARP_ADMIN_PORT:-8009}:8009"
- "${WARP_WEB_PORT:-8080}:8080"
- "${WARP_PB_BIND:-127.0.0.1}:${WARP_PB_PORT:-8070}:8070"
- "${SEAWEED_S3_BIND:-127.0.0.1}:${SEAWEED_S3_PORT:-8333}:8333"
volumes:
@@ -7,7 +7,8 @@
# cp .env.pocketbase.seaweedfs.split.prod.example .env # then edit it
# docker compose -f docker-compose.pocketbase.seaweedfs.split.prod.yml up -d
#
# The database stays in /data/pb_data (warp-data); media goes to the bucket
# PocketBase runs in the container, its database in /data/pb_data
# (warp-data), admin UI on loopback at http://localhost:8070/_/; media goes to the bucket
# WARP_PB_S3_BUCKET in SeaweedFS (seaweed-data). The homeserver's S3 identity
# is seeded into the filer's IAM store on every boot, beside any added in
# the admin UI under Object Store → Users. Media stored before S3 was on is
@@ -64,6 +65,7 @@ services:
- "${WARP_PORT:-8008}:8008"
- "${WARP_ADMIN_PORT:-8009}:8009"
- "${WARP_WEB_PORT:-8080}:8080"
- "${WARP_PB_BIND:-127.0.0.1}:${WARP_PB_PORT:-8070}:8070"
- "${SEAWEED_S3_BIND:-127.0.0.1}:${SEAWEED_S3_PORT:-8333}:8333"
- "${SEAWEED_ADMIN_BIND:-127.0.0.1}:${SEAWEED_ADMIN_PORT:-23646}:23646"
@@ -7,7 +7,8 @@
# cp .env.pocketbase.seaweedfs.split.example .env # then edit it
# docker compose -f docker-compose.pocketbase.seaweedfs.split.yml up -d --build
#
# The database stays in /data/pb_data (warp-data); media goes to the bucket
# PocketBase runs in the container, its database in /data/pb_data
# (warp-data), admin UI on loopback at http://localhost:8070/_/; media goes to the bucket
# WARP_PB_S3_BUCKET in SeaweedFS (seaweed-data). The homeserver's S3 identity
# is seeded into the filer's IAM store on every boot, beside any added in
# the admin UI under Object Store → Users. Media stored before S3 was on is
@@ -63,6 +64,7 @@ services:
- "${WARP_PORT:-8008}:8008"
- "${WARP_ADMIN_PORT:-8009}:8009"
- "${WARP_WEB_PORT:-8080}:8080"
- "${WARP_PB_BIND:-127.0.0.1}:${WARP_PB_PORT:-8070}:8070"
- "${SEAWEED_S3_BIND:-127.0.0.1}:${SEAWEED_S3_PORT:-8333}:8333"
- "${SEAWEED_ADMIN_BIND:-127.0.0.1}:${SEAWEED_ADMIN_PORT:-23646}:23646"
@@ -6,7 +6,8 @@
# cp .env.pocketbase.seaweedfs.example .env # then edit it
# docker compose -f docker-compose.pocketbase.seaweedfs.yml up -d --build
#
# The database stays in /data/pb_data (warp-data); media goes to the bucket
# PocketBase runs in the container, its database in /data/pb_data
# (warp-data), admin UI on loopback at http://localhost:8070/_/; media goes to the bucket
# WARP_PB_S3_BUCKET in SeaweedFS (seaweed-data), whose gateway has exactly
# one identity: the homeserver's. Media stored before S3 was on is not moved
# into the bucket.
@@ -54,6 +55,7 @@ services:
- "${WARP_PORT:-8008}:8008"
- "${WARP_ADMIN_PORT:-8009}:8009"
- "${WARP_WEB_PORT:-8080}:8080"
- "${WARP_PB_BIND:-127.0.0.1}:${WARP_PB_PORT:-8070}:8070"
- "${SEAWEED_S3_BIND:-127.0.0.1}:${SEAWEED_S3_PORT:-8333}:8333"
volumes:
+6 -3
View File
@@ -5,9 +5,11 @@
# cp .env.pocketbase.example .env # then edit it
# docker compose -f docker-compose.pocketbase.yml up -d --build
#
# PocketBase is embedded in the homeserver (the pocketbase database driver):
# its data directory, with media in its storage, is /data/pb_data in the
# warp-data volume. Set WARP_PB_S3_* in .env to keep media in an
# PocketBase runs in the container as a server of its own, which the
# homeserver signs in to as the superuser in .env (or one the container
# makes up, kept in /data/pocketbase-superuser.env): its pb_data, with media
# in its storage, is /data/pb_data in the warp-data volume. Its admin UI is
# http://localhost:8070/_/ on loopback. Set WARP_PB_S3_* in .env to keep media in an
# S3 bucket instead (docs/configuration.md).
#
# Homeserver http://localhost:8008, admin panel http://localhost:8009, web
@@ -33,6 +35,7 @@ services:
- "${WARP_PORT:-8008}:8008"
- "${WARP_ADMIN_PORT:-8009}:8009"
- "${WARP_WEB_PORT:-8080}:8080"
- "${WARP_PB_BIND:-127.0.0.1}:${WARP_PB_PORT:-8070}:8070"
volumes:
warp-data:
+34
View File
@@ -16,6 +16,10 @@
# $PGDATA (/data/postgres); the default
# in warp-aio-postgresql, the only image
# that has PostgreSQL
# WARP_AIO_POCKETBASE=true PocketBase in the container, on port
# 8070, its pb_data in /data/pb_data; set
# by the warp-aio-pocketbase* images, the
# only ones that have it
# WARP_AIO_SEAWEEDFS=server SeaweedFS as one `weed server -s3`
# WARP_AIO_SEAWEEDFS=split SeaweedFS as master, volume, filer, S3
# gateway and admin UI, one process each;
@@ -195,6 +199,36 @@ if [ "${WARP_PB_S3_ENABLED:-false}" = true ] && [ -z "$seaweedfs" ] && [ -n "${W
done
fi
# PocketBase is the homeserver's database server. Its superuser is the one
# the homeserver signs in as; without one in the environment, the first
# start makes one up and keeps it in the volume, so a bare `docker run`
# works and the admin UI can still be signed in to. Every start sets the
# password again, which is how a changed one lands.
if [ "${WARP_AIO_POCKETBASE:-false}" = true ]; then
if ! command -v pocketbase >/dev/null; then
log "WARP_AIO_POCKETBASE=true, but this image has no PocketBase; use warp-aio-pocketbase"
exit 1
fi
# The homeserver reads the same file through WARP_PB_SUPERUSER_FILE, so
# that `docker exec ... warp create-account` finds the account too.
superuser="${WARP_PB_SUPERUSER_FILE:-/data/pocketbase-superuser.env}"
if [ -z "${WARP_PB_SUPERUSER_EMAIL:-}" ] || [ -z "${WARP_PB_SUPERUSER_PASSWORD:-}" ]; then
if [ ! -f "$superuser" ]; then
log "no WARP_PB_SUPERUSER_EMAIL and WARP_PB_SUPERUSER_PASSWORD; making up a superuser, kept in $superuser"
umask 077
printf 'WARP_PB_SUPERUSER_EMAIL=warp@warp.local\nWARP_PB_SUPERUSER_PASSWORD=%s\n' \
"$(head -c 24 /dev/urandom | base64 | tr -d '/+=')" >"$superuser"
fi
set -a
. "$superuser"
set +a
fi
pocketbase superuser upsert "$WARP_PB_SUPERUSER_EMAIL" "$WARP_PB_SUPERUSER_PASSWORD" \
--dir=/data/pb_data >/dev/null
run pocketbase pocketbase serve --http=0.0.0.0:8070 --dir=/data/pb_data
wait_http PocketBase http://127.0.0.1:8070/api/health
fi
# The signing key is created on first start and kept in the volume: losing
# it means other servers no longer recognise this one.
if [ ! -f "$WARP_PRIVATE_KEY" ]; then