Skip to content

Run MinIO in CI and local stacks from an image we build and publish ourselves - #1446

Closed
mihow wants to merge 7 commits into
mainfrom
feat/owned-minio-image
Closed

mihow wants to merge 7 commits into
mainfrom
feat/owned-minio-image

Conversation

@mihow

@mihow mihow commented Sep 29, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

The local development stack and the CI test job need a MinIO server and the mc client to stand in for S3. Since MinIO archived its open-source projects, the images we pulled have disappeared or been locked three times, and each time every open pull request went red at once. This change points both compose files at an image we build and publish ourselves, so a decision by another organisation can no longer stop our tests.

The image is built by the new public repository RolnickLab/minio-image from pinned source tags of the community-maintained forks of the MinIO server and client, and published to insectai/minio on Docker Hub. The insectai organisation is a Docker-Sponsored Open Source namespace, so anonymous pulls from CI runners are not rate limited. The binaries keep their original names, so compose/local/minio/init.sh and the health checks run unchanged.

This builds on #1435 (same three files). Until #1435 merges, the diff here also shows its commits; the change specific to this PR is the last commit. Backend Tests only run for pull requests into main, which is why it targets main directly.

Closes #1445

List of Changes

  1. CI and local stacks pull our own MinIO image. docker-compose.ci.yml and docker-compose.yml use insectai/minio:RELEASE.2026-09-16T00-00-00Z, pinned by digest, for both the minio server and the minio-init bucket-setup container. The image bundles the server, mc, and a shell.
  2. The local MinIO service no longer needs user: root. The image runs as root by default, like the historical official image, so existing development volumes keep working without the override that the Chainguard image required.
  3. Comments explain where the image comes from and how to bump it. Each release's digest pin line is printed in the image repository's workflow run summary; the bump procedure is in its README.

Detailed Description

Why not the earlier plan from #1445 (download official binaries from dl.min.io): that site now returns 410 Gone for every MinIO binary, and the upstream minio/minio and minio/mc repositories are archived. The image is therefore built from source at pinned tags of pgsty/silo (server) and pgsty/mc (client), which are the actively maintained forks with published security fixes. The build verifies the checked-out commit against a pinned SHA so a moved tag fails the build rather than changing the image silently.

Verified locally before opening this PR:

  • docker compose -f docker-compose.ci.yml up minio minio-init with the published digest: the server becomes healthy, init.sh creates both buckets and sets them public, and an anonymous GET of an object in the test bucket succeeds.
  • minio --version and mc --version report the pinned release on both linux/amd64 and linux/arm64.
  • An anonymous docker pull of the digest from a logged-out Docker config succeeds, and the registry returns no rate-limit headers for this repository.
  • The existing 10-character CI root credentials are accepted by the forked server.

The full test suite runs in this PR's CI.

🤖 Generated with Claude Code

https://claude.ai/code/session_01FA1nFdyB4WmWTw4syt89Yz

Summary by CodeRabbit

  • Bug Fixes
    • Application environments now coordinate service startup more reliably, waiting for required services and storage setup to reach the appropriate state before Django starts.
    • MinIO setup now stops if a command fails, helping prevent incomplete bucket initialization. Both required buckets and their public-read access remain configured.

kra and others added 6 commits September 24, 2026 15:00
…l on errors

Current mc releases no longer have `mc config host add`, so the setup script
now uses `mc alias set`. The script also stops on the first error; before, a
failed setup exited 0 and left the storage tests erroring later with no clue.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7Xf6VPbwWtTumhjjF15g8
The test container waited only for the bucket setup container to start, so a
failed setup still let the tests run and fail later with no clear cause. The
test container now waits for bucket setup to finish successfully, and compose
aborts the run with the setup container's exit status otherwise.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7Xf6VPbwWtTumhjjF15g8
In the local development stack, Django waited only for the bucket setup
container to start, and the setup container did not wait for the MinIO
server to be healthy. Django could therefore start against missing buckets,
and setup could race the server on a cold start. The setup container now
waits for the server's healthcheck, and Django (plus the services that
inherit its settings) waits for setup to complete successfully, matching
the CI stack.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7Xf6VPbwWtTumhjjF15g8
…October 2026

Minimus has announced that it will turn off its registry (reg.mini.dev) on
22 October 2026, so the image this branch switched to would stop being
pullable in a few weeks. Both compose files now use Chainguard's MinIO image
instead, which is publicly pullable and pinned by digest so it cannot change
under us. The digest is a multi-arch index, so it works on amd64 and arm64.

The Chainguard image bundles the server, mc and a shell, so the same image
serves the server and the bucket setup container. Its entrypoint is the
minio binary itself, so the server command drops the leading "minio", and
the setup script is run through /bin/sh explicitly. The image runs as a
non-root user by default, which cannot write to local development volumes
created by the previous image, so the development server runs as root.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7Xf6VPbwWtTumhjjF15g8
…est pin

Chainguard publishes only a "latest" tag publicly, so the digest is the only
stable reference. The comment above each MinIO service records why the image
was chosen and the two commands needed to move the pin forward.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01C7Xf6VPbwWtTumhjjF15g8
@netlify

netlify Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for antenna-preview canceled.

Name Link
🔨 Latest commit 8fe1a2e
🔍 Latest deploy log https://app.netlify.com/projects/antenna-preview/deploys/6abc2deeb3d3c3000881a1ce

@coderabbitai

coderabbitai Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: c887c502-3a0d-4d31-ab7b-357239f4ccb6

📥 Commits

Reviewing files that changed from the base of the PR and between e4c53bf and 2330295.

📒 Files selected for processing (3)
  • compose/local/minio/init.sh
  • docker-compose.ci.yml
  • docker-compose.yml

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The local and CI Compose configurations now use a shared pinned MinIO image and explicit service dependency conditions. The MinIO initialization script uses mc alias set, stops on command failure, and retains bucket creation and public-read policies.

Changes

MinIO service setup

Layer / File(s) Summary
MinIO runtime and bucket initialization
compose/local/minio/init.sh, docker-compose.ci.yml, docker-compose.yml
The MinIO server and initializer use the same pinned insectai/minio image. The initializer runs the script through /bin/sh. The script configures the local alias, creates both buckets, applies public-read policies, and stops when a command fails.
Service startup conditions
docker-compose.ci.yml, docker-compose.yml
Django uses explicit service_started conditions for its dependencies and requires minio-init to complete successfully. The local initializer waits for MinIO health and proxy startup.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to 23302

The stacks now wait for successful bucket initialization, while existing buckets remain supported. No actionable merge-blocking issue was identified; normal CI checks should complete before merging.

Security Architecture Review

Security architecture risk: 🔵 Low · up to 23302

The change improves startup failure containment without adding observed network or credential exposure. Risk is low rather than minimal because the replacement image’s build provenance, runtime defaults, and persistent-data rollback compatibility are not established here.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — A compromised replacement image would execute within the existing local and CI MinIO service authority: supplied environment variables, attached data volumes, and the initializer’s mounted script. Both server and initializer now trust the same image content. These definitions do not establish production deployment, cross-tenant access, or host-level authority.

Trust Boundaries and Controls

  • observed — The executable supply-chain trust boundary changes to an owned image publication path. Matching digest pins prevent mutable-tag selection drift between the server and initializer, but do not themselves verify source provenance or build integrity.

Resilience and Maintainability Implications

  • inferred — Fail-fast initialization and successful-completion gating reduce the chance that Django operates against failed provisioning. They do not revoke partial bucket policies, stop already-running consumers, or revalidate ongoing storage health. Those limits bound the guarantee rather than establish a new security regression.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Linked Issues check ✅ Passed #1445 is active and directly linked. The PR configures both local and CI Compose stacks to use the same digest-pinned insectai/minio image. The reported image includes the MinIO server, mc, and a …
Out of Scope Changes check ✅ Passed The reviewed changes are limited to MinIO initialization and Compose configuration. Fail-fast initialization, explicit health and completion dependencies, and the shared pinned image directly support …
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 1…
Title check ✅ Passed The title clearly and concisely describes the primary change: using a project-owned MinIO image in CI and local stacks.
Description check ✅ Passed The description covers the summary, changes, rationale, related issue, testing, risks, and deployment impact. The template checklist and explicit deployment-notes section are not included, but the des…
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@mihow
mihow changed the base branch from fix/minio-replacement-again to main September 29, 2026 21:23
@mihow mihow closed this Sep 29, 2026
@mihow mihow reopened this Sep 29, 2026
…a third-party registry

Both the local stack and the CI stack pull insectai/minio, built from pinned
pgsty/silo and pgsty/mc sources by RolnickLab/minio-image and published to the
sponsored insectai Docker Hub organisation, which is exempt from pull rate
limits. The image runs as root like the historical official one, so the
user: root override on the dev service is no longer needed.

Closes #1445

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FA1nFdyB4WmWTw4syt89Yz
Copilot AI balanced review requested due to automatic review settings September 29, 2026 21:30
@mihow
mihow force-pushed the feat/owned-minio-image branch from 2330295 to 8fe1a2e Compare September 29, 2026 21:30
@netlify

netlify Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

✅ Deploy Preview for antenna-ssec canceled.

Name Link
🔨 Latest commit 8fe1a2e
🔍 Latest deploy log https://app.netlify.com/projects/antenna-ssec/deploys/6abc2defc4c7d80008f36aa6

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

The pinned digest matches the published multi-platform image, and the compose and initialization changes are consistent and complete.

Review effort: Balanced
Findings: None

What changed in this PR

Switches local and CI MinIO services to the project-controlled, digest-pinned image while improving startup reliability.

Changes:

  • Uses the same server/client image across both stacks.
  • Waits for successful bucket initialization before Django starts.
  • Makes bucket setup fail fast and uses the current mc commands.
File Description
docker-compose.yml Updates local MinIO image and startup dependencies.
docker-compose.ci.yml Updates CI MinIO image and startup dependencies.
compose/​local/​minio/​init.sh Modernizes and hardens bucket initialization.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@mihow

mihow commented Sep 29, 2026 •

Copy link
Copy Markdown
Collaborator Author

Claude says: Superseded: this commit was cherry-picked onto #1435 as e442bb3c so the change lands in one PR. Closing.

@mihow mihow closed this Sep 29, 2026
@mihow
mihow deleted the feat/owned-minio-image branch September 29, 2026 21:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Own the MinIO test image instead of depending on a third-party registry

3 participants