SeaweedFS Setup Guide
Overview
SeaweedFS is used as the S3-compatible object store for all media assets in
PlayTelly. CoreAPI writes to it via the S3 gateway (through the minio-go
client) and via the Filer HTTP API for move/rename operations. A single
bucket (playtelly) holds all tenants, separated by path prefix.
playtelly/<tenant>/<folder>/<file>
Example: playtelly/jastv/banner/hero.jpg
Components and Ports
SeaweedFS runs as a single container in local/Quickstart environments, exposing three distinct interfaces:
| Port | Interface | Purpose |
|---|---|---|
8333 |
S3 API gateway | S3-compatible read/write access. This is what CoreAPI's minio-go client and cproxy's passthrough origin both talk to. |
9333 |
Master API | Cluster/volume topology management. Used internally by SeaweedFS and for healthchecks (/dir/status). |
8888 |
Filer HTTP API / UI | Directory-tree abstraction over the underlying volumes. CoreAPI uses this for mv operations (moving files from temp/<uploadID> to their final tenant/folder path) and mkdir. Browsable UI available at http://localhost:8888. |
Compose Service
seaweedfs:
image: chrislusf/seaweedfs:latest
command: >
server
-s3
-s3.port=8333
-s3.config=/etc/seaweedfs/s3.json
-filer
-filer.maxMB=256
-master.volumeSizeLimitMB=1024
ports:
- "8333:8333"
- "9333:9333"
- "8888:8888"
volumes:
- seaweedfs_data:/data
- ./seaweedfs/seaweedfs_s3.json:/etc/seaweedfs/s3.json:ro
-filer.maxMB=256 caps individual filer-proxied upload/transfer chunk size.
-master.volumeSizeLimitMB=1024 caps the size of each underlying volume file
before SeaweedFS rolls over to a new one — this is a storage-layer detail and
doesn't cap individual object size.
S3 Identity Config (seaweedfs_s3.json)
SeaweedFS's S3 gateway uses its own identity/credentials file, independent of any AWS IAM concept — this is SeaweedFS-specific config, not a real AWS account.
{
"signingKey": "any-random-string-here",
"identities": [
{
"name": "admin",
"credentials": [{ "accessKey": "admin", "secretKey": "password" }],
"actions": ["Admin", "Read", "Write", "List", "Tagging"]
},
{
"name": "anonymous",
"credentials": [],
"actions": ["Read", "List"]
}
]
}
Two identities are defined:
admin— full read/write/list/tagging access, used by CoreAPI (viaMINIO_ACCESS_KEY/MINIO_SECRET_KEYenv vars) for uploads, thumbnail writes, and filer move operations.anonymous— read/list only, no credentials required. This is what allows cproxy (or any other internal service) toGETobjects from the S3 gateway without needing to sign requests or hold credentials — relevant to the cproxy passthrough-caching setup, which reads from SeaweedFS unauthenticated.
signingKey should be replaced with a real random string in any
non-local environment — it's used internally by SeaweedFS for
request-signing validation, not exposed to clients.
Bucket Initialization
Buckets don't exist by default — they're created by a one-shot init
container (seaweedfs_init) that runs after SeaweedFS reports healthy:
curl -X PUT http://seaweedfs:8333/<bucket-name> \
--user admin:password \
--aws-sigv4 aws:amz:us-east-1:s3
Default buckets created: MINIO_BUCKET (default cms; PlayTelly's actual
value is playtelly per CoreAPI's .env) and MINIO_TEMP_BUCKET (default
cms-temp). The init container is idempotent — re-running on an existing
bucket just logs a warning and continues.
Relevant CoreAPI env vars
| Var | Value | Purpose |
|---|---|---|
MINIO_ENDPOINT |
seaweedfs:8333 |
S3 gateway host:port CoreAPI connects to |
MINIO_ACCESS_KEY |
admin |
Matches seaweedfs_s3.json admin identity |
MINIO_SECRET_KEY |
password |
Matches seaweedfs_s3.json admin identity |
MINIO_USE_SSL |
false |
Local dev only — no TLS between CoreAPI and SeaweedFS |
MINIO_BUCKET |
playtelly |
The single bucket all tenant media lives under |
SEAWEEDFS_FILER |
http://seaweedfs:8888 |
Filer endpoint for mv/mkdir operations during upload processing |
Health Check
curl -sf http://localhost:9333/dir/status
healthcheck: to gate startup of the init container
and any dependent services (e.g. cproxy_vod, which should also depends_on
SeaweedFS being healthy before starting).
Verifying Setup
# Confirm S3 gateway is up and bucket exists
curl -I http://localhost:8333/playtelly/ \
--user admin:password --aws-sigv4 aws:amz:us-east-1:s3
# Browse filer UI
open http://localhost:8888
# Confirm anonymous read access works (relevant for cproxy passthrough)
curl -I http://localhost:8333/playtelly/<known-existing-key>
The last command should succeed without the --user/--aws-sigv4 flags
— that's the anonymous-read identity being exercised, and is exactly the
access path cproxy's passthrough origin depends on.