Skip to content

Replace MinIO with Garage v2.3.0 as S3 backend#74

Open
Syed-Ali-Abbas-568 wants to merge 2 commits into
overhangio:mainfrom
Syed-Ali-Abbas-568:syed-ali/feat/replace-minio-with-garage
Open

Replace MinIO with Garage v2.3.0 as S3 backend#74
Syed-Ali-Abbas-568 wants to merge 2 commits into
overhangio:mainfrom
Syed-Ali-Abbas-568:syed-ali/feat/replace-minio-with-garage

Conversation

@Syed-Ali-Abbas-568

Copy link
Copy Markdown
Collaborator

Replace MinIO with Garage v2.3.0 as S3 backend

Summary

Swaps the deprecated MinIO daemon (and its mc init image) for [Garage v2.3.0](https://garagehq.deuxfleurs.fr/) as the S3-compatible storage backend, with [khairul169/garage-webui](https://github.com/khairul169/garage-webui) as the admin console.

Open edX-side configuration is preserved end-to-end: all variables keep the MINIO_ prefix and Garage binds on port 9000 internally, so existing MINIO_HOST:9000 endpoints resolve transparently. No changes are required in edx-platform or downstream plugins.

Changes

Plugin (tutorminio/plugin.py)

  • New image defaults: MINIO_DOCKER_IMAGE (Garage), MINIO_WEBUI_DOCKER_IMAGE (garage-webui), MINIO_JOB_DOCKER_IMAGE (custom alpine + garage CLI).
  • New unique config MINIO_RPC_SECRET plus a to_hex Jinja filter that SHA-256s the random secret into the 32-byte hex string Garage requires (Tutor's random_string is alphanumeric and not valid hex).
  • Registers garage-job via IMAGES_BUILD / IMAGES_BUILD_REQUIRED so it auto-builds on tutor dev launch / tutor local launch. Needed because the upstream Garage image is scratch-based and the init script needs a shell, awk, and wget.
  • Bumps OPENEDX_AWS_ACCESS_KEY from openedxopenedxs3 (Garage rejects key IDs shorter than 8 chars). This is the only user-visible default that changed.

Init flow (templates/minio/tasks/minio/init.sh)

  • Reads the node ID from the metadata volume on docker-compose, falls back to the admin API on k8s where ReadWriteOnce PVCs prevent the job pod from mounting it.
  • Configures cluster layout (1 GiB capacity, dc1 zone), imports the Open edX S3 key, creates all buckets, grants the key full access, and enables public website access on the buckets Open edX serves directly.
  • All operations are idempotent — re-running is a no-op.

Docker Compose / Kubernetes patches

  • New garage, garage-webui, and garage-job services with garage.toml mounted at /etc/garage.toml.
  • k8s: new ConfigMap for garage.toml, Deployment for garage-webui, and storage split into separate meta + data PVCs.
  • Caddyfile proxies MINIO_HOSTgarage:9000 and MINIO_CONSOLE_HOSTgarage-webui:3909.

Testing

Verified end-to-end with tutor dev launch:

  • Cluster initialized, all 5 buckets created, S3 key imported.
  • LMS wrote badge images into the openedx bucket during its own init — confirms Open edX → Garage works with no Open edX-side changes.
  • S3 round-trip via aws-cli against http://garage:9000 succeeded.
  • HTTP checks: LMS 200, CMS 302 (login redirect, expected), Garage WebUI 200, S3 root 403 (anonymous listing denied, expected).
  • ruff check and ruff format --check both pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Syed-Ali-Abbas-568 and others added 2 commits April 28, 2026 02:00
Swap the deprecated MinIO daemon (and `mc` init job image) for the
Garage v2.3.0 S3-compatible storage backend, plus the khairul169
garage-webui admin console. Open edX-side configuration is preserved:
all variable names keep the `MINIO_` prefix, and the daemon binds on
port 9000 internally so existing `MINIO_HOST:9000` endpoints continue
to resolve transparently.

Plugin / templates:
- plugin.py: add Garage image defaults (`MINIO_DOCKER_IMAGE`,
  `MINIO_WEBUI_DOCKER_IMAGE`, `MINIO_JOB_DOCKER_IMAGE`), unique
  `MINIO_RPC_SECRET`, and a `to_hex` Jinja filter that SHA-256s the
  random secret to a 32-byte hex string (Garage's required format).
- IMAGES_BUILD + IMAGES_BUILD_REQUIRED hooks register the
  `garage-job` image (alpine + garage CLI) so it auto-builds during
  `tutor dev launch` / `tutor local launch`. Required because the
  upstream Garage image is `scratch`-based and the init script needs
  a shell, awk, and wget.
- Override `OPENEDX_AWS_ACCESS_KEY` to `openedxs3` (9 chars) since
  Garage rejects key IDs shorter than 8 characters.

Init flow (templates/minio/tasks/minio/init.sh):
- Read node ID from the metadata volume in docker-compose, or fall
  back to the admin API in k8s where the ReadWriteOnce PVC blocks
  the job pod from mounting it.
- Configure cluster layout (1 GiB capacity, dc1 zone), import the
  Open edX S3 key, create + grant access to all buckets, and enable
  public website access on bucket(s) Open edX serves directly.
- All operations idempotent so subsequent inits are no-ops.

Docker compose / k8s patches:
- Garage daemon, garage-webui, and garage-job services with the
  garage.toml config mounted at /etc/garage.toml.
- k8s adds a ConfigMap for garage.toml, a Deployment for
  garage-webui, and splits storage into separate meta + data PVCs.
- Caddyfile proxies MINIO_HOST → garage:9000 and
  MINIO_CONSOLE_HOST → garage-webui:3909.

Verified end-to-end with `tutor dev launch`: cluster initialized,
buckets created, LMS uploaded badge images during init, S3 read/write
round-trips succeed via aws-cli, and LMS/CMS/WebUI all return healthy
HTTP responses.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Pending Triage

Development

Successfully merging this pull request may close these issues.

2 participants