Files
Warp/Docker
tajniak81andClaude Opus 5.5 beb77292d5
CI / Test (ubuntu-latest) (push) Waiting to run
CI / Test (windows-latest) (push) Waiting to run
CI / Storage tests on PostgreSQL (push) Waiting to run
CI / Complement (federation off) (push) Waiting to run
CI / golangci-lint (push) Waiting to run
CI / Smoke test the binary (push) Waiting to run
CI / Admin panel (push) Waiting to run
CI / Web client (push) Waiting to run
CI / Desktop client (ubuntu-24.04) (push) Waiting to run
CI / Desktop client (windows-latest) (push) Waiting to run
Docker, Docker-AIO: WARP_PB_S3_REGION from .env in the SeaweedFS stacks
The SeaweedFS compose files read the region from .env, defaulting to
us-east-1 as before, and their .env examples list it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 17:39:37 +01:00
..

Docker: one container per component

The homeserver (warp), the admin panel (warp-admin) and the web client (warp-web) as separate images, built from Dockerfile, apps/admin/Dockerfile and apps/web/Dockerfile.

File Database Images
docker-compose.sqlite.yml SQLite, in the warp-data volume built here
docker-compose.pocketbase.yml PocketBase, a container of its own, in pb-data built here
docker-compose.postgresql.yml PostgreSQL 17, its own container built here
docker-compose.pocketbase.s3.yml PocketBase, media in an existing S3 bucket elsewhere built here
docker-compose.pocketbase.seaweedfs.yml PocketBase, media in SeaweedFS, one container built here
docker-compose.pocketbase.seaweedfs.split.yml PocketBase, media in SeaweedFS, one container per role, with its admin UI built here
docker-compose.*.prod.yml as above pulled, never built
cd Docker
cp .env.sqlite.example .env      # then edit it
docker compose -f docker-compose.sqlite.yml up -d --build
docker compose -f docker-compose.sqlite.yml exec warp warp create-account --username admin --admin

Homeserver on :8008, admin panel on :8009, web client on :8080 (WARP_PORT, WARP_ADMIN_PORT, WARP_WEB_PORT in .env move them). Put a TLS-terminating reverse proxy in front before exposing them; see docs/deployment.md.

The PocketBase files run PocketBase as a container of its own, from tajniak81/pocketbase-docker-root (WARP_PB_IMAGE picks another; any PocketBase 0.40 or later will do). Its data is in the pb-data volume, and the homeserver reaches it at http://pocketbase:8070, signed in as the superuser in .env. The image creates that superuser on its first start and leaves it alone after, so a new password is set in the admin UI first, at http://localhost:8070/_/ on loopback, and in .env after.

Media in S3

The three pocketbase.s3 and pocketbase.seaweedfs setups keep the PocketBase database in pb-data and put media in an S3 bucket (WARP_PB_S3_BUCKET, default warp). Media already stored on the filesystem is not moved into the bucket when S3 is turned on, so start these on a fresh pb-data or copy the files across first. It is the PocketBase container that talks to the bucket.

  • docker-compose.pocketbase.s3.yml: a bucket that already exists elsewhere (AWS, MinIO, a SeaweedFS on another host). Set WARP_PB_S3_ENDPOINT, WARP_PB_S3_ACCESS_KEY and WARP_PB_S3_SECRET. Path style is on by default; set WARP_PB_S3_FORCE_PATH_STYLE=false for AWS S3. http://host.docker.internal:8333 reaches a gateway on the Docker host. The homeserver waits up to 30 seconds for the endpoint to answer before it starts.
  • docker-compose.pocketbase.seaweedfs.yml: SeaweedFS as one weed server -s3 container, plus a one-shot seaweedfs-init that creates the bucket. The gateway's one identity is the homeserver's key pair, WARP_PB_S3_ACCESS_KEY and WARP_PB_S3_SECRET.
  • docker-compose.pocketbase.seaweedfs.split.yml: master, volume, filer, S3 gateway and admin UI (port 23646) as separate containers. seaweedfs-init writes the homeserver's identity into the filer's IAM store on every start, the store the admin UI writes too, so keys added under Object Store → Users never displace it; the gateway does not start until that identity is there. Set SEAWEED_ADMIN_PASSWORD as well.

The S3 gateway and the admin UI are published on 127.0.0.1 only (SEAWEED_S3_BIND, SEAWEED_ADMIN_BIND); master, volume and filer are not published, since the volume server serves content by id with no authentication. Both SeaweedFS files share a project and the seaweed-data layout, so switching between them needs no migration. SEAWEED_IMAGE pins the SeaweedFS release (4.45).

Prod files

The .prod.yml files pull $WARP_REGISTRY/warp, warp-admin and warp-web at tag $WARP_VERSION (defaults 10.2.1.10:5500/admin and latest). Push the images there first:

docker compose -f docker-compose.sqlite.yml build
for i in warp warp-admin warp-web; do
  docker tag $i:latest $WARP_REGISTRY/$i:$WARP_VERSION
  docker push $WARP_REGISTRY/$i:$WARP_VERSION
done

docker-compose.postgresql.prod.yml refuses to start without WARP_POSTGRES_PASSWORD.

Settings

Every compose file has its own settings file, named after it: docker-compose.<name>.yml takes .env.<name>.example, so docker-compose.pocketbase.seaweedfs.prod.yml takes .env.pocketbase.seaweedfs.prod.example. Each lists only the settings its compose file uses, with their defaults, and names the ones that are required; an empty value means the default. Copy the one you need to .env, which compose reads for the ports, the registry and the passwords, and passes to the homeserver, the admin panel and the web client. .env is not committed. The prod examples start from a public server name rather than localhost.

The compose files set only what makes each one what it is: the database driver and connection string, and the address the admin panel and web client reach the homeserver on.