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>
148 lines
6.0 KiB
Docker
148 lines
6.0 KiB
Docker
# 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 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.
|
|
#
|
|
# Build from the repository root:
|
|
#
|
|
# docker build -t warp-aio-pocketbase-seaweedfs -f Docker-AIO/Dockerfile.PocketBase.SeaweedFS .
|
|
# docker run -p 8008:8008 -p 8009:8009 -p 8080:8080 -p 127.0.0.1:8333:8333 \
|
|
# -v warp-data:/data -v seaweed-data:/seaweed/data \
|
|
# -e WARP_SERVER_NAME=warp.example \
|
|
# -e WARP_PB_S3_ACCESS_KEY=warp -e WARP_PB_S3_SECRET=change-me \
|
|
# warp-aio-pocketbase-seaweedfs
|
|
#
|
|
# WARP_PB_S3_ACCESS_KEY and WARP_PB_S3_SECRET are required: they are the
|
|
# gateway's only identity and what the homeserver signs its requests with.
|
|
#
|
|
# Ports inside the container (publish 8333 on loopback at most; never 8081,
|
|
# the volume server, which serves content by id with no authentication):
|
|
#
|
|
# 8008 homeserver 8333 SeaweedFS S3 gateway
|
|
# 8009 admin panel 8888 SeaweedFS filer
|
|
# 8080 web client 9333 SeaweedFS master
|
|
# 8081 SeaweedFS volume (not its usual 8080, which is the web client)
|
|
|
|
# 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: everything SeaweedFS keeps.
|
|
# Mount a volume on each; a fresh named volume inherits the ownership.
|
|
RUN mkdir -p /data /seaweed/data && 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="server"
|
|
|
|
EXPOSE 8008 8009 8080 8333
|
|
|
|
# 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:8333/healthz && \
|
|
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"]
|