Skip to content

RustFS (S3 storage)

Curated name rustfs. Adds RustFS - S3-compatible object storage with a MinIO-compatible API - to the workbench in compose mode.

RustFS gives you a real object store on your machine, so code that uploads, stores, or serves files via the S3 API can run locally without touching AWS or any cloud account. Anything that speaks S3 - the AWS SDKs, aws s3, presigned URLs, multipart uploads - works against it. Use it for file uploads, generated assets, backups, or as a stand-in for production S3 in dev and tests. Nothing leaves the machine.

At init, or to an existing workbench:

Terminal window
monoceros init acme --with-services=rustfs
monoceros add-service acme rustfs

Need more than one store (say one for uploads, one for backups)? Add the same image again under a different name with --as - each instance gets its own host, data dir, and connection env:

Terminal window
monoceros add-service acme rustfs --as=uploads
monoceros add-service acme rustfs --as=backups
Terminal window
monoceros remove-service acme rustfs

Or delete the service’s block from acme.yml by hand and re-run monoceros apply acme - the yml is the source of truth. (Its data volume monoceros-acme-data-rustfs is removed with the workbench on monoceros remove, which backs it up first.)

acme.yml
services:
- name: rustfs # host name in the container + data dir name
image: rustfs/rustfs:latest
user: '0:0' # run as root so it can write its bind-mounted /data (see tip)
port: 9000 # in-container S3 port (feeds `monoceros tunnel`)
httpPort: 9001 # the console, shared by `monoceros share`
env:
RUSTFS_ACCESS_KEY: ${RUSTFS_ACCESS_KEY} # value lives in acme.env
RUSTFS_SECRET_KEY: ${RUSTFS_SECRET_KEY}
volumes:
- data:/data # the service's own Docker volume
restart: unless-stopped
healthcheck: # workspace waits for service_healthy
test: [CMD, curl, -f, 'http://localhost:9000/minio/health/live']
interval: 10s
timeout: 5s
retries: 5
connectionEnv: # → the workspace env vars below
URL: http://${host}:${port}
HOST: ${host}
PORT: ${port}
ACCESS_KEY: ${RUSTFS_ACCESS_KEY}
SECRET_KEY: ${RUSTFS_SECRET_KEY}

The access/secret keys are ${VAR} references; the real values live in acme.env (dev default rustfsadmin for both), so the yml stays shareable without baking credentials in (see Workbench configuration).

Monoceros injects a connection env into the workspace container, prefixed with the service name, so the app/agent reaches the store without hardcoding anything:

VariableValue (defaults)
RUSTFS_URLhttp://rustfs:9000
RUSTFS_HOSTrustfs
RUSTFS_PORT9000
RUSTFS_ACCESS_KEYrustfsadmin
RUSTFS_SECRET_KEYrustfsadmin
RUSTFS_PUBLIC_URLhttp://acme-rustfs.localhost

The prefix is the service name, uppercased. A second instance added with --as=uploads gets UPLOADS_URL, UPLOADS_ACCESS_KEY, … - so multiple stores never collide.