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](/docs/hetzner/apalla/storage/object/use-s3-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](https://github.com/seaweedfs/seaweedfs/tree/master/k8s/charts/seaweedfs) before you install, since these change between chart versions. ```console $ 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 `standard` class. The data detaches and reattaches with the volume server, so it survives node replacement. - **Local disks** through [TopoLVM](/docs/hetzner/apalla/storage/local/local-nvme-with-topolvm) on a bare metal server. Faster, but the data is tied to that server. ```console $ 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:///`), 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: ```console $ 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. ```console $ kubectl -n seaweedfs port-forward svc/seaweedfs-master 9333:9333 ``` Then open [http://localhost:9333](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: ```yaml title="s3-credentials.yaml" apiVersion: v1 kind: Secret metadata: name: s3-credentials namespace: default type: Opaque stringData: AWS_ACCESS_KEY_ID: AWS_SECRET_ACCESS_KEY: S3_ENDPOINT: http://seaweedfs-s3.seaweedfs.svc.cluster.local:8333 ``` **Related:** [Use S3-compatible storage from workloads](/docs/hetzner/apalla/storage/object/use-s3-from-workloads) to wire an application to the store · [ReadWriteMany with JuiceFS](/docs/hetzner/apalla/storage/shared/readwritemany-with-juicefs) to put a shared filesystem on top · [Back up with Velero](/docs/hetzner/apalla/storage/backup/back-up-with-velero) to send cluster backups here.