Dockerfile.PocketBase.SeaweedFS bakes SeaweedFS into the PocketBase all-in-one image as one `weed server -s3` process; Dockerfile.PocketBase.SeaweedFS.split runs master, volume, filer, S3 gateway and the admin UI as separate processes, with the homeserver's S3 identity seeded into the filer's IAM store on every boot. Media goes to the bucket, the database stays in /data/pb_data, and both layouts share /seaweed/data, so switching between them needs no migration. The entrypoint now tracks every process in one list and stops them in reverse start order, and it refuses to start an open S3 gateway or admin UI. Each image gets a build and a prod compose file, and .env.example and the README cover the new settings. Modelled on DriverVault's Docker-AIO SeaweedFS images. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
160 lines
6.7 KiB
Docker
160 lines
6.7 KiB
Docker
# warp-aio-pocketbase-seaweedfs-split — the homeserver, the admin panel and
|
|
# the web client on PocketBase, with SeaweedFS in the same image as the
|
|
# media store, split into its roles: master, volume, filer, S3 gateway and
|
|
# admin UI, one process each. Over Dockerfile.PocketBase.SeaweedFS that buys
|
|
# per-role restart, per-role metrics ports and the admin UI, where S3
|
|
# identities are minted and revoked under Object Store → Users.
|
|
#
|
|
# The homeserver's identity lives in the filer's IAM store, seeded on every
|
|
# boot, the same store the admin UI writes; so a key added there never
|
|
# displaces the homeserver's. /seaweed/data has the layout `weed server -dir`
|
|
# writes, so it moves between the two SeaweedFS images unchanged.
|
|
#
|
|
# Build from the repository root:
|
|
#
|
|
# docker build -t warp-aio-pocketbase-seaweedfs-split -f Docker-AIO/Dockerfile.PocketBase.SeaweedFS.split .
|
|
# docker run -p 8008:8008 -p 8009:8009 -p 8080:8080 \
|
|
# -p 127.0.0.1:8333:8333 -p 127.0.0.1:23646:23646 \
|
|
# -v warp-data:/data -v seaweed-data:/seaweed/data -v seaweed-admin:/seaweed/admin \
|
|
# -e WARP_SERVER_NAME=warp.example \
|
|
# -e WARP_PB_S3_ACCESS_KEY=warp -e WARP_PB_S3_SECRET=change-me \
|
|
# -e WEED_ADMIN_PASSWORD=change-me \
|
|
# warp-aio-pocketbase-seaweedfs-split
|
|
#
|
|
# WARP_PB_S3_ACCESS_KEY, WARP_PB_S3_SECRET and WEED_ADMIN_PASSWORD are
|
|
# required; the container refuses to start an open gateway or admin UI.
|
|
#
|
|
# Ports inside the container (publish 8333 and 23646 on loopback at most;
|
|
# master, volume and filer listen on loopback only):
|
|
#
|
|
# 8008 homeserver 8333 SeaweedFS S3 gateway
|
|
# 8009 admin panel 8888 SeaweedFS filer
|
|
# 8080 web client 9333 SeaweedFS master
|
|
# 8081 SeaweedFS volume 23646 SeaweedFS admin UI
|
|
# 9324-9328 SeaweedFS metrics: master, volume, filer, S3, admin
|
|
|
|
# SeaweedFS release to bake in, pinned so a rebuild later brings up the same
|
|
# one; --build-arg SEAWEED_VERSION=... to upgrade. Global, because a FROM uses
|
|
# it.
|
|
ARG SEAWEED_VERSION="4.45"
|
|
|
|
FROM node:22-alpine AS web
|
|
|
|
WORKDIR /src
|
|
RUN corepack enable
|
|
|
|
# Lockfile and manifests first, so the package store survives source changes.
|
|
COPY package.json pnpm-workspace.yaml pnpm-lock.yaml ./
|
|
COPY apps/ui/package.json ./apps/ui/
|
|
COPY apps/admin/package.json ./apps/admin/
|
|
COPY apps/web/package.json ./apps/web/
|
|
RUN pnpm install --frozen-lockfile --filter @warp/admin... --filter @warp/web...
|
|
|
|
COPY apps/ui ./apps/ui
|
|
COPY apps/admin ./apps/admin
|
|
COPY apps/web ./apps/web
|
|
RUN pnpm --filter @warp/admin build && pnpm --filter @warp/web build
|
|
|
|
|
|
FROM golang:1.26-alpine AS build
|
|
|
|
ARG VERSION=0.0.0-dev
|
|
ARG COMMIT=unknown
|
|
ARG BUILD_DATE=unknown
|
|
ENV CGO_ENABLED=0
|
|
|
|
WORKDIR /src
|
|
|
|
# The homeserver. Dependencies first, so the module cache survives source
|
|
# changes.
|
|
COPY server/go.mod server/go.sum ./server/
|
|
RUN cd server && go mod download
|
|
COPY server ./server
|
|
RUN cd server && go build -trimpath \
|
|
-ldflags "-s -w \
|
|
-X github.com/dariuszjaniak/warp/server/internal/buildinfo.Version=${VERSION} \
|
|
-X github.com/dariuszjaniak/warp/server/internal/buildinfo.Commit=${COMMIT} \
|
|
-X github.com/dariuszjaniak/warp/server/internal/buildinfo.BuildDate=${BUILD_DATE}" \
|
|
-o /out/warp ./cmd/warp
|
|
|
|
# The admin panel and the web client, each with its frontend embedded.
|
|
COPY apps/admin/go.mod ./apps/admin/
|
|
COPY apps/admin/cmd ./apps/admin/cmd
|
|
COPY apps/admin/internal ./apps/admin/internal
|
|
COPY --from=web /src/apps/admin/internal/panel/build/dist ./apps/admin/internal/panel/build/dist
|
|
RUN cd apps/admin && GOWORK=off go build -trimpath -ldflags "-s -w -X main.version=${VERSION}" \
|
|
-o /out/warp-admin ./cmd/warp-admin
|
|
|
|
COPY apps/web/go.mod ./apps/web/
|
|
COPY apps/web/cmd ./apps/web/cmd
|
|
COPY apps/web/host ./apps/web/host
|
|
COPY apps/web/client/client.go ./apps/web/client/
|
|
COPY --from=web /src/apps/web/client/build/dist ./apps/web/client/build/dist
|
|
RUN cd apps/web && GOWORK=off go build -trimpath -ldflags "-s -w -X main.version=${VERSION}" \
|
|
-o /out/warp-web ./cmd/warp-web
|
|
|
|
|
|
# The one static weed binary from the official image.
|
|
FROM chrislusf/seaweedfs:${SEAWEED_VERSION} AS seaweed
|
|
|
|
|
|
FROM alpine:3.21
|
|
|
|
# tini is PID 1 so signals reach the entrypoint and zombies are reaped.
|
|
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/
|
|
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
|
|
|
|
# /data: the database, signing key and anything stored before S3 was on.
|
|
# /seaweed/data: master, volume and filer, sharing it.
|
|
# /seaweed/admin: the admin UI's session key and maintenance state.
|
|
# Mount a volume on each; a fresh named volume inherits the ownership.
|
|
RUN mkdir -p /data /seaweed/data /seaweed/admin && chown -R warp:warp /data /seaweed
|
|
WORKDIR /data
|
|
USER warp
|
|
|
|
# Media goes to the bucket on the gateway inside this image: a fixed
|
|
# loopback address, path style because a self-hosted gateway has no
|
|
# per-bucket DNS, and a region SeaweedFS ignores. Media stored on the
|
|
# filesystem before S3 was on is not moved into the bucket.
|
|
ENV WARP_LISTEN_ADDRESS=":8008" \
|
|
WARP_PRIVATE_KEY="/data/signing.key" \
|
|
WARP_DB_DRIVER="pocketbase" \
|
|
WARP_DB_CONNECTION_STRING="/data/pb_data" \
|
|
WARP_PB_S3_ENABLED="true" \
|
|
WARP_PB_S3_ENDPOINT="http://127.0.0.1:8333" \
|
|
WARP_PB_S3_BUCKET="warp" \
|
|
WARP_PB_S3_REGION="us-east-1" \
|
|
WARP_PB_S3_FORCE_PATH_STYLE="true" \
|
|
WARP_LOG_FORMAT="json" \
|
|
WARP_ADMIN_LISTEN=":8009" \
|
|
WARP_ADMIN_HOMESERVER="http://127.0.0.1:8008" \
|
|
WARP_ADMIN_LOG_FORMAT="json" \
|
|
WARP_WEB_LISTEN=":8080" \
|
|
WARP_WEB_HOMESERVER="http://127.0.0.1:8008" \
|
|
WARP_WEB_LOG_FORMAT="json" \
|
|
WARP_AIO_ADMIN="true" \
|
|
WARP_AIO_WEB="true" \
|
|
WARP_AIO_EMBEDDED_POSTGRES="false" \
|
|
WARP_AIO_SEAWEEDFS="split" \
|
|
WEED_ADMIN_USER="admin"
|
|
|
|
EXPOSE 8008 8009 8080 8333 23646
|
|
|
|
# Every process must answer, so a wedged one shows in `docker ps`.
|
|
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
|
|
CMD curl -fsS -o /dev/null http://127.0.0.1:9333/cluster/status && \
|
|
curl -fsS -o /dev/null http://127.0.0.1:8081/healthz && \
|
|
curl -fsS -o /dev/null http://127.0.0.1:8888/healthz && \
|
|
curl -fsS -o /dev/null http://127.0.0.1:8333/healthz && \
|
|
curl -fsS -o /dev/null http://127.0.0.1:23646/health && \
|
|
curl -fsS -o /dev/null http://127.0.0.1:8008/healthz && \
|
|
{ [ "$WARP_AIO_ADMIN" != true ] || curl -fsS -o /dev/null http://127.0.0.1:8009/healthz; } && \
|
|
{ [ "$WARP_AIO_WEB" != true ] || curl -fsS -o /dev/null http://127.0.0.1:8080/healthz; } || exit 1
|
|
|
|
ENTRYPOINT ["/sbin/tini", "--", "warp-aio"]
|