Skip to content

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 (via MINIO_ACCESS_KEY/MINIO_SECRET_KEY env 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) to GET objects 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
Used by Docker Compose's 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.