Run SeaweedFS for S3-compatible object storage
SeaweedFS runs an S3-compatible object store inside your own cluster. You get buckets and an S3 endpoint on storage you operate, so your uploads, your Velero backups, and the data behind JuiceFS all sit on disks you control rather than on someone else's service. On Syself Autopilot that matters twice over: the data stays on your Hetzner hardware, and backing it with block volumes keeps it off the nodes, where node replacement never touches it.
SeaweedFS has a few moving parts, and how you set replication decides how much failure the data survives. For the full breakdown and the replication values before you deploy, expand the reference below.
SeaweedFS is made of a few parts that work together:
- The master tracks where data lives and assigns storage to writes.
- Volume servers hold the actual bytes on disk.
- The filer provides a directory tree and file metadata on top of the volumes.
- The S3 gateway exposes an S3 API in front of the filer, so clients talk plain S3.
SeaweedFS decides durability by how many copies it keeps and where it puts them. Replication is set per write, encoded as three digits for copies across data centers, racks, and servers. A value of 001 keeps a second copy on a different server in the same rack; 000 keeps a single copy. More copies cost more disk and survive more failures. Set the default replication on the master and match it to how much loss the data can take.
When self-hosted S3 is the right call#
Run your own object store for sovereignty, cost, or egress. The data stays on hardware you own, which answers data-residency questions directly. There are no per-request or per-gigabyte charges from an outside provider, only the cost of the disks. And traffic between your workloads and your buckets stays inside the cluster network, so you do not pay to move data out and back.
SeaweedFS is yours to run: it is not part of the cluster stack, so its health, upgrades, and data are your responsibility rather than part of the managed platform. If you only need a bucket and do not want to operate the store, point your workloads at any S3-compatible endpoint instead. See Use S3-compatible storage from workloads . If you would rather not operate SeaweedFS, the Syself Consulting team can deploy and maintain it for you, or advise on sizing and replication.
Deploy SeaweedFS #
Install the master, volume servers, filer, and S3 gateway from the SeaweedFS Helm chart:
Note
The chart name and values here follow the SeaweedFS Helm chart. Confirm the current chart repository, release name, and value keys against the SeaweedFS chart before you install, since these change between chart versions.
$ helm repo add seaweedfs https://seaweedfs.github.io/seaweedfs/helm
$ helm repo update
$ helm install seaweedfs seaweedfs/seaweedfs \
--namespace seaweedfs --create-namespace \
--set master.replicas=1 \
--set volume.replicas=1 \
--set filer.replicas=1 \
--set s3.enabled=true
Back it with volumes #
The volume servers need real disks. Give them a StorageClass through the chart's persistence values. Two choices fit Syself Autopilot:
- Hetzner Cloud block volumes through the
standardclass. The data detaches and reattaches with the volume server, so it survives node replacement. - Local disks through TopoLVM on a bare metal server. Faster, but the data is tied to that server.
$ helm upgrade seaweedfs seaweedfs/seaweedfs \
--namespace seaweedfs \
--set 'volume.dataDirs[0].name=data' \
--set 'volume.dataDirs[0].type=persistentVolumeClaim' \
--set 'volume.dataDirs[0].storageClass=standard' \
--set 'volume.dataDirs[0].size=100Gi'
Expose the S3 endpoint #
The S3 gateway speaks the S3 API with path-style addressing, so the bucket name goes in the path (http://<endpoint>/<bucket>), not in the hostname. Clients set forcePathStyle (or s3ForcePathStyle) to true.
Create buckets and keys #
Create a bucket and an access key with the s3 admin interface or the gateway's configured identities:
$ echo "s3.bucket.create -name backups" | kubectl exec -i -n seaweedfs sts/seaweedfs-master -- weed shell
The same administration is available in a browser: port-forward the master and open its admin interface, which shows cluster status, volumes, and topology.
$ kubectl -n seaweedfs port-forward svc/seaweedfs-master 9333:9333
Then open http://localhost:9333.
Generate a separate access key ID and secret for each use, and grant each key only the buckets and actions it needs. A key that only writes backups should not be able to read your uploads bucket. Least-privilege keys limit the blast radius if one leaks.
Important
The exact command to create buckets and keys depends on your SeaweedFS version and how you configure S3 identities. Check the SeaweedFS S3 documentation for the syntax your version uses.
Keep the access key ID and secret in a Kubernetes Secret, never in a container image or a plain manifest. Workloads read them from the Secret at runtime:
apiVersion: v1
kind: Secret
metadata:
name: s3-credentials
namespace: default
type: Opaque
stringData:
AWS_ACCESS_KEY_ID: <access-key-id>
AWS_SECRET_ACCESS_KEY: <secret-access-key>
S3_ENDPOINT: http://seaweedfs-s3.seaweedfs.svc.cluster.local:8333
Related: Use S3-compatible storage from workloads to wire an application to the store · ReadWriteMany with JuiceFS to put a shared filesystem on top · Back up with Velero to send cluster backups here.
Choose an RWX backend
When to share data through object storage instead of a shared filesystem on Syself Autopilot, and how to choose JuiceFS or NFS when you do need ReadWriteMany.
Use S3-compatible storage from workloads
Point an application on Syself Autopilot at an S3-compatible endpoint for uploads, artifacts, and exports instead of a block volume.