Published

SeaweedFS

Self-hosted S3-compatible object storage, written in Go and licensed Apache-2.0. One container serves the S3 API for backups, app uploads and media. Fits a single server that needs its own buckets instead of a cloud bucket.

Resources by load level

What the app itself needs at each level, next to what we recommend for a server that runs only this app.

LevelWhat it meansApp requirementsRecommended
LightEstimateUp to 50 GiB stored, about 250,000 objects in a few buckets, up to 5 transfers at once (backups of a few machines, one app's uploads).0.5 vCPU · 0.5 GiB RAM · 64 GiB disk0.72 vCPU · 2.1 GiB RAM · 82.915 GiB disk
MediumEstimateUp to 500 GiB stored, about 2 million objects, up to 20 transfers at once (several apps and nightly backups of a small office).1 vCPU · 1 GiB RAM · 626 GiB disk1.32 vCPU · 2.7 GiB RAM · 729.215 GiB disk
HeavyEstimateUp to 2,000 GiB stored, about 10 million objects, up to 50 transfers at once, still one node with no replication.2 vCPU · 2 GiB RAM · 2,501 GiB disk2.52 vCPU · 3.9 GiB RAM · 2,885.465 GiB disk

Recommended = app requirements + system baseline + safety headroom, under sizing policy 2026.10.0. Options stay at their defaults. “Estimate” means the sources give no number for that case, so it is worked out from them by the method stated under Components. How the numbers are built

Size it in the Stack Sizer

Ready-to-run files

Support level Supported

Compose template from the official sources; not yet verified by a run.

Create docker-compose

Components

What each component needs at each load level, before baseline and headroom.

vCPU / GiB RAM / GiB disk
ComponentLightMediumHeavySources
SeaweedFS (weed mini) (app)0.5 / 0.5 / 641 / 1 / 6262 / 2 / 2,501[1][5][6][19][20][22][34][36]
How the estimates are worked out
  • SeaweedFS (weed mini) · Light: No upstream total for mini. RAM: index ~20 B per file × 250,000 = 5 MB, reads 5 × 4 MB chunks = 20 MB, plus ~0.2 GiB assumed for the Go runtime of master, volume, filer, S3, admin and worker in one process; ×2 for Go GC headroom → 0.5 GiB. vCPU: SigV4 checks and MD5 ETags of every upload → half a core. Disk: image 193,556,478 B compressed (0.18 GiB) + 529,553,408 B unpacked (0.493 GiB), both kept by the containerd store = 0.673 GiB; stored data ×1.25 for deleted space not yet vacuumed (a volume is compacted at 30% garbage) and filer metadata (an assumed margin). 0.673 + 50 × 1.25 = 63.2 → 64.
  • SeaweedFS (weed mini) · Medium: RAM: index 20 B × 2,000,000 = 40 MB, 20 reads and 20 uploads × 4 MB chunks = 160 MB, runtime 0.2 GiB → about 0.4 GiB live, ×2 for Go GC → 0.8, rounded to 1 GiB for the filer's LevelDB caches. vCPU: one core for signature checks, hashing and the background vacuum. Disk: image 193,556,478 B compressed (0.18 GiB) + 529,553,408 B unpacked (0.493 GiB), both kept by the containerd store = 0.673 GiB; stored data ×1.25 for deleted space not yet vacuumed (a volume is compacted at 30% garbage) and filer metadata (an assumed margin). 0.673 + 500 × 1.25 = 625.7 → 626.
  • SeaweedFS (weed mini) · Heavy: RAM: index 20 B × 10,000,000 = 200 MB (the wiki's leveldb index cuts this), 50 reads and 50 uploads × 4 MB = 400 MB, runtime 0.2 GiB → about 0.8 GiB live, ×2 for Go GC → 1.6, rounded to 2 GiB. vCPU: two cores for hashing at higher throughput plus vacuum and compaction of 1 GiB volumes. Disk: image 193,556,478 B compressed (0.18 GiB) + 529,553,408 B unpacked (0.493 GiB), both kept by the containerd store = 0.673 GiB; stored data ×1.25 for deleted space not yet vacuumed (a volume is compacted at 30% garbage) and filer metadata (an assumed margin). 0.673 + 2,000 × 1.25 = 2,500.7 → 2,501.

Ports

Public ports are meant to be reached from outside the stack, usually through a reverse proxy; internal ones stay on the stack's own network.

ComponentPortExposurePurposeSources
SeaweedFS (weed mini)8333/tcpPublic, through a proxyS3 API (SigV4, path-style) and the /healthz probe; serve only through an HTTPS reverse proxy[1][6][8]
SeaweedFS (weed mini)9333/tcpInternal onlyMaster HTTP API and UI (volume assignment); no authentication[6][25]
SeaweedFS (weed mini)19333/tcpInternal onlyMaster gRPC (HTTP port + 10000); mutual TLS only when configured[6][25]
SeaweedFS (weed mini)9340/tcpInternal onlyVolume server HTTP (object data); writes unprotected without a JWT signing key[6][25]
SeaweedFS (weed mini)19340/tcpInternal onlyVolume server gRPC (HTTP port + 10000)[6][25]
SeaweedFS (weed mini)8888/tcpInternal onlyFiler HTTP API and UI; reads and writes every file without auth unless JWT keys are set[6][25]
SeaweedFS (weed mini)18888/tcpInternal onlyFiler gRPC (HTTP port + 10000), used by the S3 gateway[6][25]
SeaweedFS (weed mini)18333/tcpInternal onlyS3 gateway gRPC (HTTP port + 10000)[6]
SeaweedFS (weed mini)23646/tcpInternal onlyAdmin server; with -admin.ui=false only /health and /metrics[6][11]
SeaweedFS (weed mini)33646/tcpInternal onlyAdmin worker gRPC (HTTP port + 10000) for the maintenance worker; no password auth[6][28]

Every port in the catalog, with conflicts between apps

User and permissions (UID/GID)

The user each container's process runs as, and the paths it writes to. A bind mount for one of these paths must be writable by that UID:GID.

ComponentUID:GIDUserStarts as rootWrites toSources
SeaweedFS (weed mini)1000:1000seaweedYes, prepares its directories, then drops to this user/data[4][5][12]
  • SeaweedFS (weed mini): The image has no USER: entrypoint.sh starts as root, chowns /data to seaweed (1000:1000) only when the owner differs, and drops privileges with su-exec. A bind mount of /data therefore needs no manual chown.

Storage growth

How much each component's data grows per month at each load level, on top of the disk in the profile. A value marked Assumption is ANAROQ's stated assumption, not a figure from the sources; the notes say what it rests on.

GiB per month
ComponentLightMediumHeavySources
SeaweedFS (weed mini)Assumption22080[6][22]
What the growth figures rest on
  • SeaweedFS (weed mini): Growth is what clients upload minus what they delete; SeaweedFS expires nothing by itself (no lifecycle rule is set). Assumed net upload: 2, 20 and 80 GiB a month. Deleted objects free space only when vacuum compacts a volume with 30% garbage (checked every 840 s).

Upgrade and rollback

How to move to a new version safely, and how to go back if it fails.

Back up first

Stop the container (docker compose stop seaweedfs) and copy the whole /data volume: volume .dat/.idx files, the filer's LevelDB metadata, the master state and the .mini_* key files. Data and metadata must come from the same moment. [6][21][27]

Upgrade steps

  1. Back up /data first (see backup). Then set the new pinned tag in the Compose file and run docker compose pull and docker compose up -d. Stay on the standard tag: _large_disk builds use another index format and cannot share the same data. [20][35]
  2. Check docker compose logs seaweedfs and the /healthz check, then list a bucket with an S3 client. mini's defaults (volume size, ports, bundled services) can change between releases, so compare the flags in the new mini.go. [1][6][8]

Roll back

Stop the stack, restore the /data copy taken before the upgrade, pin the previous tag and run docker compose up -d. [20][27]DerivedThe FAQ promises backward-compatible upgrades but documents no downgrade, so running an older binary on data a newer one wrote is not assumed safe; restoring the copy is.

Known breaking changes

  • In 4.41: mini and master report anonymous cluster statistics to telemetry.seaweedfs.com by default (before: off). Opt out with -master.telemetry=false, as the template does. [6][33]DerivedRelease notes were not reachable from the research environment; taken from the flag default in mini.go at 4.40 (false) and 4.41 (true).
  • In 4.23: The image's default command became mini -dir=/data (before: no command, the container needed one such as server). Compose files that pass their own command are unaffected. [32]DerivedTaken from docker/Dockerfile.go_build at 4.22 and 4.23; the release notes were not reachable.
  • In 4.00: The image stopped running as root: 4.00 set USER seaweed (uid 1000), so data written by 3.x as root could not be opened. Since 4.01 the entrypoint starts as root and chowns /data first; upgrade 3.x straight to 4.01 or later. [30][31]DerivedTaken from docker/Dockerfile.go_build at 3.99 and 4.00 and docker/entrypoint.sh at 4.01; the release notes were not reachable.

Limits

  • One node, no replication: weed mini runs a single master and keeps one copy of each object, so a failed disk loses data. Protect /data with RAID or backups; multi-master and replication need the multi-component setup. [1][6]
  • Clients must use path-style addressing (https://host/bucket/key): the template sets no -s3.domainName, so bucket.host URLs are not routed. Most SDKs and rclone have a force-path-style setting. [8][13]
  • The S3 API covers buckets, objects, multipart, versioning, object lock and lifecycle, but not bucket notifications, bucket replication, SelectObjectContent or Object Lambda; check the wiki's API list before relying on a feature. [23][24]
  • The template has one admin identity from environment variables, with full access to every bucket. Scoped users need weed shell (s3.configure) or an -s3.config file, and the env keys change only with a restart. [1][15]
  • Behind a reverse proxy, uploads must stream: request buffering breaks chunked SigV4 signatures, and a body size limit caps object size. Caddy streams by default. [13]

Security

  • Without AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY the S3 gateway runs in Allow-All mode and accepts unsigned requests. The template makes both required; never remove them from .env. [1][7][15]
  • Only port 8333 is S3-authenticated. The master (9333), volume (9340) and filer (8888) HTTP ports and the gRPC ports have no login and are not published, but containers on the same Docker network can reach them; in the caddy or proxy-network mode that includes the proxy's network. [6][25]
  • To close the filer and volume HTTP ports, the wiki documents JWT keys as env vars (WEED_JWT_SIGNING_KEY, WEED_JWT_FILER_SIGNING_KEY and their _READ_ variants), which the S3 gateway then uses. Not in the template; test it before relying on it. [25][26]
  • The Admin UI is off: without a password its UI and /api routes are open to anyone who reaches port 23646. To turn it on, set WEED_ADMIN_PASSWORD, drop -admin.ui=false and reach it through an SSH tunnel only. [11][28][29]
  • Images are signed with cosign since September 2026; verify chrislusf/seaweedfs:4.48 against the release workflow identity in docker/README.md and deploy by the digest you checked. [18]

Backup

  • Simplest consistent backup: stop the container and copy the whole /data volume, or sync every bucket to another S3 target with an S3 client while it runs. Keep the .mini_sse_kek and .mini_kek_passphrase files: SSE-S3 objects cannot be read without them. [6][27]
  • Volume files and filer metadata must match: the wiki pairs weed backup of each volume with fs.meta.save of the metadata, taken while writes are paused. A copy of the volumes alone cannot restore object names. [27]

Latest release

Newest upstream release
SeaweedFS 4.48 [35]
This profile was checked against

SeaweedFS 4.48

This profile was checked against the newest release.

Checked on
14 Oct 2026
State
Checked within the last 90 days
Where releases are published
Docker Hub tags

Latest releases of every app

Version

Profile status
Published
Checked against release
SeaweedFS 4.48
Profile version
1.0.0
Figures verified
14 Oct 2026
Catalog release
2026.10.10
Sizing policy
2026.10.0
Compose file
Unverified

Sources

  1. SeaweedFS wiki: Quick Start with weed mini (docker run with /data, AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY, S3_BUCKET; no keys = Allow All; -s3.externalUrl behind a proxy) (Official docs · read 14 Oct 2026)
  2. SeaweedFS wiki: Docker Compose for S3 (weed server -s3 with an inline config.json, port 8333, no data volume) (Official Compose · read 14 Oct 2026)
  3. docker/seaweedfs-compose.yml at 4.48: one container per component (master, volume, filer, s3, webdav), untagged image (Official Compose · read 14 Oct 2026)
  4. docker/Dockerfile.go_build at 4.48: Alpine, curl installed, user seaweed (1000:1000), VOLUME /data, ENTRYPOINT /entrypoint.sh, CMD mini -dir=/data, no HEALTHCHECK (Official repository · read 14 Oct 2026)
  5. docker/entrypoint.sh at 4.48: as root, chown -R /data to seaweed when ownership differs, then su-exec seaweed; mini adds -dir=/data unless given (Official repository · read 14 Oct 2026)
  6. weed/command/mini.go at 4.48: ports 8333/9333/9340/8888/23646 (gRPC +10000), -webdav, -admin.ui, -s3.port.iceberg/lance, -master.telemetry (on), auto volume size (Official repository · read 14 Oct 2026)
  7. weed/s3api/auth_credentials.go at 4.48: AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY add a static admin identity; auth is enforced once any identity exists (Official repository · read 14 Oct 2026)
  8. weed/s3api/s3api_server.go at 4.48: /status, /healthz and /readyz probes; -domainName for virtual-host style; a host-less path-style route always registered (Official repository · read 14 Oct 2026)
  9. weed/s3api/s3api_status_handlers.go at 4.48: StatusHandler answers 200 with an empty body (Official repository · read 14 Oct 2026)
  10. weed/command/s3.go at 4.48: externalUrl falls back to the S3_EXTERNAL_URL env var and is tried first when verifying signatures behind a proxy (Official repository · read 14 Oct 2026)
  11. weed/admin/handlers/admin_handlers.go at 4.48: /health and /metrics without auth; with the UI disabled no other route; without a password every UI and /api route is public (Official repository · read 14 Oct 2026)
  12. Registry config of chrislusf/seaweedfs:4.48 (linux/amd64): no User, Entrypoint /entrypoint.sh, Cmd mini -dir=/data, Volumes /data, 8 ExposedPorts, no Healthcheck (Measurement · read 14 Oct 2026)
  13. SeaweedFS wiki: S3 Nginx Proxy (SigV4 signs the Host header; X-Forwarded-Host or -s3.externalUrl; no request buffering; path or virtual-host style) (Official docs · read 14 Oct 2026)
  14. SeaweedFS wiki: WebDAV (current implementation does not enforce authentication yet) (Official docs · read 14 Oct 2026)
  15. SeaweedFS wiki: S3 Credentials (env vars give one global admin, restart to change them; Allow-All mode until any credential exists; config file, filer or weed shell for more users) (Official docs · read 14 Oct 2026)
  16. SeaweedFS README at 4.48: blob store with O(1) disk reads, filer, S3 gateway; compares itself with MinIO, which it says ceased development on Apr 25, 2026 (Official repository · read 14 Oct 2026)
  17. SeaweedFS LICENSE at 4.48: Apache License 2.0 (image label Apache-2.0) (Official repository · read 14 Oct 2026)
  18. docker/README.md at 4.48: images on Docker Hub and ghcr.io signed with cosign (keyless) since September 2026 (Official repository · read 14 Oct 2026)
  19. SeaweedFS wiki: Optimization (in-memory index about 20 bytes per file; memory for concurrent reads = file or chunk size × readers; leveldb index variants) (Official docs · read 14 Oct 2026)
  20. SeaweedFS wiki: FAQ (16 bytes per index entry, 17 in large_disk builds, which cannot be mixed with standard ones; upgrades backward compatible unless noted) (Official docs · read 14 Oct 2026)
  21. SeaweedFS wiki: Production Setup (leveldb index for many volumes; filer.toml leveldb2 store keeps metadata on local disk and supports one filer) (Official docs · read 14 Oct 2026)
  22. SeaweedFS wiki: Volume Management (maintenance worker script every 17 min: volume.deleteEmpty, s3.clean.uploads -timeAgo=24h for unfinished multipart uploads) (Official docs · read 14 Oct 2026)
  23. SeaweedFS wiki: Amazon S3 API (supported operations: buckets, objects, multipart, versioning, object lock and retention, lifecycle without transition rules) (Official docs · read 14 Oct 2026)
  24. SeaweedFS wiki: Supported APIs vs MinIO (no bucket notifications, bucket replication, SelectObjectContent or Object Lambda) (Official docs · read 14 Oct 2026)
  25. SeaweedFS wiki: Security Overview (master HTTP unsecured; filer HTTP and volume writes secured only with JWT keys; gRPC with mutual TLS) (Official docs · read 14 Oct 2026)
  26. SeaweedFS wiki: Security Configuration (security.toml values as WEED_* env vars, e.g. WEED_JWT_SIGNING_KEY and WEED_JWT_FILER_SIGNING_KEY) (Official docs · read 14 Oct 2026)
  27. SeaweedFS wiki: Data Backup (weed backup per volume, fs.meta.save for filer metadata; volumes and metadata must be copied while writes are paused) (Official docs · read 14 Oct 2026)
  28. SeaweedFS wiki: Admin UI (adminPassword enables login; worker gRPC has no password auth; WEED_ADMIN_* env vars) (Official docs · read 14 Oct 2026)
  29. weed/command/admin.go at 4.48: admin interface password, if empty auth is disabled; startAdminServer serves the routes on the given ip (Official repository · read 14 Oct 2026)
  30. docker/Dockerfile.go_build at 4.00: USER seaweed (uid 1000) added, image no longer runs as root; 3.99 had no USER (Official repository · read 14 Oct 2026)
  31. docker/entrypoint.sh at 4.01: starts as root, chowns /data to seaweed when needed, then su-exec (USER line removed from the Dockerfile) (Official repository · read 14 Oct 2026)
  32. docker/Dockerfile.go_build at 4.23: first release with CMD mini -dir=/data (4.22 has no CMD, a command had to be given) (Official repository · read 14 Oct 2026)
  33. weed/command/mini.go at 4.41: -master.telemetry defaults to true (anonymous cluster statistics; 4.40 defaulted to false) (Official repository · read 14 Oct 2026)
  34. Docker Hub tag chrislusf/seaweedfs:4.48 (linux/amd64): 193,556,478 B compressed; 10 layers decompressed and counted: 529,553,408 B (Measurement · read 14 Oct 2026)
  35. Docker Hub tags of chrislusf/seaweedfs (4.48 newest release on 2026-10-14, pushed 2026-09-28; dev is an unreleased build; _large_disk and _full are variants) (Official repository · read 14 Oct 2026)
  36. Docker: containerd image store is the default on fresh Engine 29+ installs and keeps images compressed and uncompressed (Official docs · read 14 Oct 2026)
  37. Amazon Web Services: Amazon S3 pricing (hosted object storage) (Official docs · read 14 Oct 2026)

All self-hosted apps