Replacing MinIO in tutor-minio: Why We Chose Garage (and What Comes Next)

Replacing MinIO in tutor-minio: Why We Chose Garage (and What Comes Next)Context

MinIO has been the S3-compatible storage backend for the tutor-minio plugin since the plugin was created. The situation upstream has changed:

  • In May 2025 MinIO removed the full admin console from the community edition, leaving only a stripped-down object browser (Blocks & Files).
  • In December 2025 the minio/minio repository was put into “maintenance mode,” and in February 2026 it was officially archived (InfoQ).
  • Community forks (OpenMaxIO, pgsty/minio) exist, but relying on a forked, no-longer-blessed upstream isn’t a great long-term posture for a plugin that ships with Tutor.

So the question for tutor-minio was: what do we build on next? We evaluated three open-source, S3-compatible candidates and prototyped two of them as feature branches.

What we cared about, in priority order

This is a Tutor plugin that needs to “just work” for both small single-node Tutor installations and Kubernetes deployments. Our priorities were:

  1. Stability today. Open edX operators expect a fresh tutor dev launch to come up green. We can’t ship something that says “do not use in production” on the tin.
  2. Minimal surface area in the plugin. Every additional service we have to model in compose / k8s / Caddy is more for downstream operators to debug.
  3. Graceful migration path. We should be able to swap the backend again later without breaking Open edX-side configuration (OPENEDX_AWS_ACCESS_KEY, MINIO_HOST, bucket names).
  4. License posture. Tutor plugins are MIT-ish neighborhoods; AGPL components are tolerable when isolated to a daemon container, but Apache 2.0 is preferred long-term.

The three options

License Status (Apr 2026) GitHub stars Architecture
Garage AGPL-3.0 v2.3.0 stable ~3.6k Single static binary, embedded metadata DB
RustFS Apache 2.0 1.0.0-alpha.94, beta planned ~April 2026, GA ~July 2026 ~26k Single binary, MinIO-compatible wire protocol
SeaweedFS Apache 2.0 Mature (since 2015) 31k+ Master + volume servers + (optional) filer + S3 gateway

Why we chose Garage now

Garage is the only one of the three that is production-stable today and small enough to embed in a Tutor plugin without growing the surface area significantly. From the Garage docs and our own integration work:

  • Single binary, no external metadata store. No Postgres/etcd dependency; metadata lives in an embedded LMDB. The plugin only had to add two services to compose: the daemon and a small admin web UI (garage-webui).
  • Stable v2 line. v2.3.0 is what we pinned, with proper RPC + admin token model, layout v1 and v2 stability, and clear migration docs.
  • Tiny runtime footprint. It’s been run in production on Raspberry Pis since 2020 by Deuxfleurs themselves, which is reassuring for the smaller end of the Tutor user base.
  • S3 wire-compatibility good enough for Open edX. Bucket creation, presigned URLs, multipart upload, public website-style access — all the things edx-platform and django-storages actually call — work without patches on the Open edX side.

The license is the trade-off we’re consciously accepting. Garage is AGPL-3.0, and as a daemon container it’s at the edge of what most operators are comfortable distributing. Because it runs in its own container and Open edX talks to it over the network S3 API, the AGPL boundary stays clearly around the storage daemon, not around edx-platform. But it’s still friction we’d like to remove eventually.

Why we plan to move to RustFS later

If you read RustFS’s own marketing page and docs, the pitch is exactly what we want: Apache 2.0, Rust, and a deliberately MinIO-compatible API surface. The feat/replace-minio-with-rustfs branch is essentially a one-line rename: the same mc client, the same :9000/:9001 ports, the same mc policy set public semantics. Almost no plugin-side adapter code is needed compared to the Garage branch.

A few signals that point at RustFS as the long-term target:

  • It’s already the most-starred entrant by a wide margin (~23k stars at time of writing — significantly more than Garage’s ~3.6k or even SeaweedFS’s 25k considering RustFS only became visible in the last year).
  • RustFS shipped a drop-in binary replacement for MinIO data directories in 1.0.0-alpha.89, signalling they take migration seriously.
  • A Beta is targeted for April 2026 and GA for July 2026 (release tracker).

The reason it’s not today’s pick is just the project’s own warning: every alpha release page explicitly says “do NOT use in production environments” and the on-disk format is not yet stable across alpha releases. We’ve shipped the RustFS branch as a labeled preview so we can flip the default the moment GA lands, but pointing community users at it today would be reckless.

Why we ruled out SeaweedFS

SeaweedFS is a serious, battle-tested system, and its license is friendly. It just isn’t the right shape for this plugin:

  • Its architecture is master server + volume servers + filer + S3 gateway. Even a minimal single-node deployment introduces multiple processes and a metadata store choice (MySQL/Postgres/Redis/etcd/…). Modeling that in tutor-minio’s compose, k8s patches, and Caddyfile would roughly double the plugin’s footprint.
  • Its sweet spot is billions of small files with O(1) disk reads (README) — the kind of workload where you’d genuinely “hammer S3.” Open edX’s storage usage (course assets, profile images, video transcripts, grade exports, ORA submissions) is nowhere near that scale for the typical Tutor deployment. We’d be paying complexity tax for capacity we’d never use.
  • The S3 API is layered on top of the filer/object store rather than being the primary interface, which empirically leads to more rough edges on niche calls than a primary-S3 system like Garage or RustFS.

If your deployment is genuinely large-scale media-heavy and you want SeaweedFS’s other interfaces (FUSE, WebDAV, HDFS), it’s a great pick — but tutor-minio is the wrong place for it. It would be a separate tutor-seaweedfs plugin if anyone wants to drive that.

What’s in the repo right now

  • feat/replace-minio-with-garage — production-targeted, default migration path. Garage v2.3.0 + garage-webui.
  • feat/replace-minio-with-rustfs — preview branch, marked ALPHA — NOT FOR PRODUCTION in the changelog. Shipped now so the plumbing is exercised and we can flip over quickly when RustFS GA lands.

A note on MINIO_GATEWAY: the gateway-mode config that older versions of tutor-minio exposed (proxying S3/Azure through MinIO) is gone in both branches. MinIO itself deprecated gateway mode in 2022, which is why the legacy plugin was frozen on RELEASE.2022-03-26. Neither Garage nor RustFS proxies to other clouds — they are the storage. Operators who were relying on gateway mode should point Open edX’s AWS_S3_ENDPOINT_URL directly at AWS/Azure and disable tutor-minio for that deployment.

Open questions for the community

  1. For folks running Tutor on K8s at scale, does Garage’s geo-distribution model actually help you, or is single-node behind a PVC enough?
  2. Anyone willing to dual-deploy and run a representative Open edX workload (course imports, video transcripts, ORA file uploads) against both backends to compare?

Happy to take feedback on the migration notes in either branch.

Sources

This is great, thanks for sharing it! Is there a migration path for people currently running MinIO to preserve their existing files?

Tutor plugins are MIT-ish neighborhoods; AGPL components are tolerable when isolated to a daemon container, but Apache 2.0 is preferred long-term.

Since Tutor is AGPL and Open edX is AGPL, I don’t really understand how the AGPL license of a daemon run by a tutor plugin is that much of a concern?