SeaweedFS: S3 gateway on the compose network only

PocketBase reaches the gateway over the compose network (or inside the
AIO container), so publishing 8333 on the host only made a second
SeaweedFS stack fail with "port is already allocated". Drop the binding
and SEAWEED_S3_BIND/SEAWEED_S3_PORT.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
tajniak81andClaude Opus 5.5 committed 2026-11-01 18:07:08 +01:00
1 parent 8849fcfb40
commit 0ea562a80a
17 files changed
+33 -83

No files matched your search

+2 -5
View File
@@ -91,11 +91,8 @@ PB_S3_BUCKET=drivervault
# It is mounted at /seaweed/data, the layout `weed server -dir` writes — the
# same one the .split. files use, so the two are interchangeable on it.
SEAWEED_DATA=seaweed_data
# The S3 port is published on loopback only — PocketBase reaches the gateway
# inside the container, and this is for tools like aws-cli. Set
# SEAWEED_S3_BIND=0.0.0.0 to expose it to other hosts, and mean it.
# SEAWEED_S3_BIND=127.0.0.1
# SEAWEED_S3_PORT=8333
# The S3 gateway publishes no host port: PocketBase reaches it inside the
# container.
# Existing uploads are NOT migrated when this is switched on: PocketBase copies
# nothing, so attachments made before the switch stop resolving. Read the file
+4 -9
View File
@@ -97,14 +97,9 @@ PB_S3_BUCKET=drivervault
# docker-compose.prod.seaweedfs.yml are interchangeable on the same volume, with
# nothing to migrate either way.
SEAWEED_DATA=seaweed_data
# The S3 port is published on loopback only — PocketBase reaches the gateway
# inside the container, and this is for tools like aws-cli. Set
# SEAWEED_S3_BIND=0.0.0.0 to expose it to other hosts, and mean it.
# SEAWEED_S3_BIND=127.0.0.1
# SEAWEED_S3_PORT=8333
#
# The master, volume and filer listen on the container's loopback and publish
# no host port at all. The admin UI below shows what they would: the volume
# The S3 gateway publishes no host port: PocketBase reaches it inside the
# container. The master, volume and filer listen on the container's loopback
# and publish no host port at all. The admin UI below shows what they would: the volume
# server in particular serves file content by id with no authentication. Reach
# them with `docker compose exec drivervault wget -qO- http://127.0.0.1:9333/...`
# (volume 8081, filer 8888).
@@ -123,7 +118,7 @@ SEAWEED_ADMIN_PASSWORD=
# Optional view-only login.
SEAWEED_ADMIN_READONLY_USER=
SEAWEED_ADMIN_READONLY_PASSWORD=
# Bound to localhost by default, the same call SEAWEED_S3_BIND makes: storage
# Bound to localhost by default: storage
# plumbing, not one of the app's own panels. On a remote host that means
# unreachable — set 0.0.0.0 and put it behind a reverse proxy.
SEAWEED_ADMIN_BIND=127.0.0.1
-2
View File
@@ -72,8 +72,6 @@ PB_S3_BUCKET=drivervault
PB_S3_REGION=us-east-1
# The gateway image, pinned so a rebuild months from now brings up the same one.
# SEAWEED_IMAGE=chrislusf/seaweedfs:4.45
# Host port for the S3 API, so aws-cli and friends can reach it while developing.
# SEAWEED_S3_PORT=8333
# Existing uploads are NOT migrated when this is switched on: PocketBase copies
# nothing, so attachments made before the switch stop resolving. Read the file
+2 -2
View File
@@ -93,14 +93,14 @@ SEAWEED_ADMIN_PASSWORD=
# --- SeaweedFS host ports (optional; defaults shown) -------------------------
# Published for aws-cli, `weed shell` and poking around while developing. The
# stack itself reaches every one of these over the compose network.
# stack itself reaches every one of these over the compose network, and the S3
# gateway too, which is not published so a second stack cannot clash on it.
# Note SEAWEED_VOLUME_PORT: the volume server serves file content by id with NO
# authentication, so do not carry this mapping over to a shared machine. It
# lands on 8081 because API_PORT already has 8080.
# SEAWEED_MASTER_PORT=9333
# SEAWEED_VOLUME_PORT=8081
# SEAWEED_FILER_PORT=8888
# SEAWEED_S3_PORT=8333
# Existing uploads are NOT migrated when this is switched on: PocketBase copies
# nothing, so attachments made before the switch stop resolving. Read the file
+4 -5
View File
@@ -131,8 +131,8 @@ copied from the official image, pinned by the `SEAWEED_VERSION` build arg), on
a `/seaweed/data` volume of its own, with PocketBase's program creating the
bucket before it serves. One container, two volumes; the cost is that a new
SeaweedFS is a rebuild rather than a tag change. Inside, the volume server sits
on **8081** since 8080 is the API Server, and only the gateway is published, on
loopback by default. The build needs the repo checkout, so either build on the
on **8081** since 8080 is the API Server, and nothing of SeaweedFS is
published: PocketBase reaches the gateway inside the container. The build needs the repo checkout, so either build on the
deploy host or `docker compose push` the image to `AIO_IMAGE` and `pull` it
there. The external-S3 ones add no containers at all: set `PB_S3_ENDPOINT`, and
create the bucket yourself.
@@ -155,8 +155,7 @@ programs. One container, three volumes (`PB_DATA`, `SEAWEED_DATA`,
gateway's program instead of a `seaweedfs-init` container. What survives of
"split" in there is per-role restart, per-role metrics ports and the admin UI;
what does not is spreading the roles over hosts. Inside, every role listens on
loopback, and only the gateway and the admin UI are published, on loopback by
default.
loopback, and only the admin UI is published, on loopback by default.
Identities work differently there, and it matters. SeaweedFS reads credentials
from, in descending priority: an `-s3.config` file, the filer's IAM store, then
@@ -173,7 +172,7 @@ updates that identity in place.
Set `SEAWEED_ADMIN_PASSWORD`: `weed admin` serves the panel with no
authentication when it is empty, and a panel that can mint bucket credentials is
the bucket (the baked-in image refuses to start the panel at all without one).
In the prod file it is bound to loopback like `SEAWEED_S3_BIND` — it is storage
In the prod file it is bound to loopback — it is storage
plumbing, not one of the app's own panels — so a remote host needs
`SEAWEED_ADMIN_BIND=0.0.0.0` behind a reverse proxy. Neither file publishes
anything for master, volume and filer: the volume server serves file content by
@@ -32,8 +32,8 @@ name: drivervault-aio
# mounts here unchanged, and vice versa, with no migration either way.
#
# Inside the container every SeaweedFS role listens on loopback except the S3
# gateway and the admin UI, and those two are published on loopback by default,
# the way the other SeaweedFS files publish them. The volume server serves file
# gateway and the admin UI. Only the admin UI is published, on loopback by
# default; PocketBase reaches the gateway inside. The volume server serves file
# content by id with no authentication at all, so it is never reachable from
# outside; the admin UI shows what its port would.
#
@@ -128,14 +128,10 @@ services:
- "${WEB_PORT:-8090}:80" # Web App
- "${PB_PORT:-8070}:8070" # PocketBase admin UI / API
- "${API_PORT:-8080}:8080" # API Server + panel (root /) + /ocpp/{serial}
# The S3 gateway, loopback only: PocketBase reaches it inside the
# container, so this is here for `aws s3 ls --endpoint-url
# http://127.0.0.1:8333` and nothing else. Set SEAWEED_S3_BIND=0.0.0.0 to
# expose it, and mean it.
- "${SEAWEED_S3_BIND:-127.0.0.1}:${SEAWEED_S3_PORT:-8333}:8333"
# The admin UI, loopback for the same reason: storage plumbing, not one
# of the app's own panels. On a remote host that means unreachable, so
# set SEAWEED_ADMIN_BIND=0.0.0.0 and put it behind a reverse proxy.
# The S3 gateway is not published: PocketBase reaches it inside the
# container. The admin UI is, on loopback: storage plumbing, not one of
# the app's own panels. On a remote host that means unreachable, so set
# SEAWEED_ADMIN_BIND=0.0.0.0 and put it behind a reverse proxy.
- "${SEAWEED_ADMIN_BIND:-127.0.0.1}:${SEAWEED_ADMIN_PORT:-23646}:23646"
volumes:
# Named volumes by default; set any of them to a host path in .env for a
+3 -7
View File
@@ -107,13 +107,9 @@ services:
- "${WEB_PORT:-8090}:80" # Web App
- "${PB_PORT:-8070}:8070" # PocketBase admin UI / API
- "${API_PORT:-8080}:8080" # API Server + panel (root /) + /ocpp/{serial}
# The S3 gateway, loopback only: PocketBase reaches it inside the
# container, so this is here for `aws s3 ls --endpoint-url
# http://127.0.0.1:8333` and nothing else. Set SEAWEED_S3_BIND=0.0.0.0 to
# expose it, and mean it. Nothing else of SeaweedFS is published: the
# volume server (8081 inside) serves file content by id with no
# authentication at all.
- "${SEAWEED_S3_BIND:-127.0.0.1}:${SEAWEED_S3_PORT:-8333}:8333"
# Nothing of SeaweedFS is published: PocketBase reaches the S3 gateway
# inside the container, and the volume server (8081 inside) serves file
# content by id with no authentication at all.
volumes:
# Named volumes by default; set either to a host path in .env for a bind
# mount. The API Server keeps no state on disk, so everything it owns
@@ -179,10 +179,7 @@ services:
# Never serve before an identity exists — see seaweedfs-init above.
seaweedfs-init:
condition: service_completed_successfully
ports:
# The stack reaches the gateway over the compose network; this is here so
# `aws s3 ls --endpoint-url http://localhost:8333` works while developing.
- "${SEAWEED_S3_PORT:-8333}:8333"
# No published port: the stack reaches the gateway over the compose network.
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:8333/healthz || exit 1"]
interval: 10s
+1 -4
View File
@@ -42,10 +42,7 @@ services:
volumes:
# From here on the attachments live here, not on pb_data.
- seaweed_data:/data
ports:
# The stack reaches the gateway over the compose network; this is here so
# `aws s3 ls --endpoint-url http://localhost:8333` works while developing.
- "${SEAWEED_S3_PORT:-8333}:8333"
# No published port: the stack reaches the gateway over the compose network.
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://127.0.0.1:9333/cluster/status || exit 1"]
interval: 10s