Skip to content

BE-608: pin MinIO client image and gate bucket init on health - #9241

Open
claude[bot] wants to merge 3 commits into
mainfrom
claude/be-608-minio-bucket-init
Open

BE-608: pin MinIO client image and gate bucket init on health#9241
claude[bot] wants to merge 3 commits into
mainfrom
claude/be-608-minio-bucket-init

Conversation

@claude

@claude claude Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Requested by Ciaran Morinan · Slack thread

🌟 What is the purpose of this PR?

Fixes two bugs in the MinIO bucket initialiser in infra/compose/compose.yml that make local setup fail intermittently and unpredictably.

Before. The MinIO bucket initialiser used an untagged minio/mc image, so every developer pulled whatever client release was newest that day and an upstream CLI change could break local setup with no commit to point at. It also declared its dependency on MinIO with Compose's short-form list, which waits only for the MinIO container to start, not for MinIO to accept connections. The init script made a single unretried attempt and was set never to restart, so losing that race meant it died with connection refused and the uploads bucket was never created.

After. The client image is pinned to a specific verified release. MinIO has a healthcheck against its documented /minio/health/live endpoint, and the initialiser waits for condition: service_healthy, so it does not run until MinIO is serving. The race is fixed by ordering rather than a sleep.

How. minio/mc is pinned to minio/mc:RELEASE.2025-08-13T08-35-41Z. The minio service gains a healthcheck polling /minio/health/live every 2s (2s timeout, 15 retries), and minio-ensure-bucket-exists swaps its short-form depends_on: - minio for the long form with condition: service_healthy — matching the 23 other healthcheck-gated dependencies already in this file.

🔗 Related links

🚫 Blocked by

  • Nothing

🔍 What does this change?

  • Pins the bucket initialiser's client image from untagged (:latest) to minio/mc:RELEASE.2025-08-13T08-35-41Z.
  • Adds a healthcheck to the minio service against http://localhost:9000/minio/health/live, written as a fallback chain (curl … || mc ready local).
  • Changes minio-ensure-bucket-exists from short-form depends_on to the long form with condition: service_healthy.

Pre-Merge Checklist 🚀

🚢 Has this modified a publishable library?

This PR:

  • does not modify any publishable blocks or libraries, or modifications do not need publishing

📜 Does this require a change to the docs?

The changes in this PR:

  • are internal and do not require a docs change

🕸️ Does this require a change to the Turbo Graph?

The changes in this PR:

  • do not affect the execution graph

⚠️ Known issues

The healthcheck command is untested at runtime. Docker could not be run in this environment, so it is written as a fallback chain (curl … || mc ready local) because curl's presence in the MinIO server image could not be confirmed — quay.io is blocked by the network proxy. One docker compose up on the dev profile would close that out.

🐾 Next steps

Two related gaps deliberately left out of scope:

  • quay.io/minio/minio is still untagged — the other half of the image-pinning gap.
  • The api service has no dependency on minio-ensure-bucket-exists, so it can still start before the uploads bucket exists.

🛡 What tests cover this?

  • No automated tests cover the Compose file. Validation done here: the YAML parses, and both services deserialize to the correct Compose schema (the healthcheck as a CMD-SHELL test, the dependency as a long-form condition). The pinned tag was confirmed to exist against the registry API with an HTTP 200 manifest response.

❓ How to test this?

  1. Check out the branch.
  2. Bring up the dev profile with Compose from a clean state (no pre-existing MinIO volume).
  3. Confirm minio-ensure-bucket-exists waits for minio to report healthy, then exits 0, and that the uploads bucket exists afterwards.

Pin the MinIO client image to minio/mc:RELEASE.2025-08-13T08-35-41Z. It
was previously untagged, so every developer pulled whatever client
release was newest that day and an upstream CLI change could break local
setup with no commit to point at.

Add a healthcheck to the minio service against /minio/health/live and
switch the bucket initialiser from the short-form depends_on list to
condition: service_healthy. The short form waits only for the container
to start, not for MinIO to accept connections, so the initialiser could
race it, fail with connection refused, and never create the uploads
bucket.
@vercel

vercel Bot commented Aug 19, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
petrinaut Ready Ready Preview Aug 19, 2026 11:12am
3 Skipped Deployments
Project Deployment Actions Updated (UTC)
hash Ignored Ignored Preview Aug 19, 2026 11:12am
hashdotdesign-tokens Ignored Ignored Preview Aug 19, 2026 11:12am
petrinaut-docs Ignored Ignored Preview Aug 19, 2026 11:12am

@cursor

cursor Bot commented Aug 19, 2026

Copy link
Copy Markdown

PR Summary

Low Risk
Dev/local Compose-only changes with no application runtime or production deploy path affected.

Overview
Local MinIO setup in infra/compose/compose.yml is tightened so bucket creation stops racing a not-yet-ready S3 API and image pulls stay reproducible.

The MinIO server moves from an unpinned quay.io/minio/minio image to RELEASE.2025-09-07T16-13-09Z, and gains a healthcheck on /minio/health/live (with curl or mc ready local as fallback), polled every 2s with up to 15 retries.

The minio-ensure-bucket-exists job pins minio/mc to RELEASE.2025-08-13T08-35-41Z with an immutable digest instead of an untagged/latest pull, and its depends_on switches from “container started” to condition: service_healthy on minio, matching other health-gated services in the same file.

Reviewed by Cursor Bugbot for commit 8a6ebe8. Bugbot is set up for automated code reviews on this repo. Configure here.

The client image was pinned by tag alone. A tag is mutable, so it does
not actually guarantee every developer resolves the same image.

Add the `sha256:` manifest digest alongside the existing tag, keeping
the tag for readability. The digest resolves to the multi-arch manifest
list (linux/amd64, linux/arm64, linux/ppc64le).

`RELEASE.2025-08-13T08-35-41Z` is confirmed still correct: enumerating
all 473 tags on Docker Hub `minio/mc` shows it is the newest of the 471
`RELEASE.*` tags and the target of `latest`. There is no semver series
to prefer instead — the only non-release tags are `latest` and `edge`,
so upstream's `RELEASE.<timestamp>Z` is its version scheme.

The tag is a year old because publishing stopped, not because it was
picked carelessly: `minio/mc`, `minio/minio` and `minio/operator` on
Docker Hub all last received a push in Sept 2025. quay.io could not be
reached from this environment to check for newer tags there, so the
registry choice still wants a human eye; a comment records that.
@claude

claude Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor Author

Pushed 04b1c2d in response to the question about the pin — the image reference has changed since the review was requested.

The pin is now minio/mc:RELEASE.2025-08-13T08-35-41Z@sha256:a7fe349ef4bd8521fb8497f55c6042871b2ae640607cf99d9bede5e9bdf11727, keeping the tag for readability and adding the digest because only the digest is immutable. That digest is the multi-arch manifest list (linux/amd64, arm64, ppc64le), read from the Docker-Content-Digest header on a v2 manifest request.

On the tag being a timestamp rather than a version number: that is upstream's scheme, not a choice made here. Enumerating all 473 tags on Docker Hub minio/mc (5 pages of 100 via the Hub API) shows 471 RELEASE.<timestamp>Z tags and exactly two others, latest and edge — there is no semver series to use instead. RELEASE.2025-08-13T08-35-41Z is the newest of those and is what latest currently resolves to, so it is the right tag.

On why it is a year old: publishing stopped rather than the tag being stale by oversight. minio/mc, minio/minio and minio/operator on Docker Hub all last received a push in September 2025, which points to MinIO having moved image publishing off Docker Hub. I could not confirm what quay.io/minio/mc offers — quay.io is refused by this environment's egress proxy (403 on CONNECT) — so I have deliberately not pinned to a quay tag I could not verify exists. Worth a human check: whether mc should move to quay.io alongside the server image, which this file already pulls from there. A comment on the image line records that. Relatedly, quay.io/minio/minio on line 370 is still untagged, for the same unverifiability reason.


Generated by Claude Code

The `minio` service pulled `quay.io/minio/minio` untagged, so every
developer got whatever server release was newest that day — the other
half of the pinning gap this PR set out to close.

Pin it to `RELEASE.2025-09-07T16-13-09Z`, the newest release and the one
`latest` points at (verified on Docker Hub: the tag resolves, and the
linux/amd64 child of its manifest list is a1a8bd4, matching upstream's
published digest for that release). Pinned by tag alone rather than by
digest: quay.io is unreachable from this environment's egress proxy, so
its digest cannot be verified, and a Docker Hub digest is not valid for
the quay copy of the same tag.

The client stays on `RELEASE.2025-08-13T08-35-41Z`. `minio/minio` and
`minio/mc` are separate repositories with independent release-timestamp
series, and `minio/mc:RELEASE.2025-09-07T16-13-09Z` does not exist —
404 from both the registry manifest API and the Hub tag API. mc's newest
of its 473 tags is the one already pinned here, which `latest` also
points at. The two images cannot share a version string.

Also trims the client's comment, which had grown to six lines.
@claude

claude Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor Author

Pinned the server to quay.io/minio/minio:RELEASE.2025-09-07T16-13-09Z — by tag alone, since quay.io is blocked by this environment's egress proxy (403 on CONNECT) so I can't verify its digest, and the Docker Hub digest isn't valid for the quay copy of the same tag.

The client can't share that version, though: minio/minio and minio/mc are separate repositories with independent release-timestamp series, and minio/mc:RELEASE.2025-09-07T16-13-09Z returns 404 from both the registry manifest API and the Hub tag API. mc's newest of its 473 tags is RELEASE.2025-08-13T08-35-41Z, already pinned here and also what its latest points at — so I left it. (Your Docker Hub link checks out for the server: a1a8bd4 is the linux/amd64 child of that tag's manifest list.)


Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/infra Relates to version control, CI, CD or IaC (area)

Development

Successfully merging this pull request may close these issues.

2 participants