minio: install mc in the runtime image, declare its region #62

Merged
jschoubben merged 11 commits from fix/minio-provisioner-missing-mc-cli into main 2026-09-25 15:25:19 +00:00
Owner

mesh-minio's s3-bucket provisioner shells out to mc to create buckets and service accounts on the live server, but mc was never in this module's own runtime image, only in minio's own. It had been silently retrying spawn mc ENOENT forever, so every s3-bucket grant reached the control-plane layer (store.json, sealed secret) without the credential ever actually existing on minio. Copies mc/mcli from minio's own already-pinned server image rather than introducing a new base.

Also declares region: eu-west in serves.s3-bucket (was stale at us-east-1) and on both the server and sidecar containers — the live deployment had eu-west set out-of-band, not in any manifest at all, and the real minio server had no region configured whatsoever, apparently lost across an earlier container recreation since nothing declared it to survive one.

Already built, pushed, and verified live on novox — real credential confirmed created (mesh_novox_ncloud), a real WebDAV write/read round-tripped through nextcloud afterward.

`mesh-minio`'s `s3-bucket` provisioner shells out to `mc` to create buckets and service accounts on the live server, but `mc` was never in this module's own runtime image, only in minio's own. It had been silently retrying `spawn mc ENOENT` forever, so every `s3-bucket` grant reached the control-plane layer (store.json, sealed secret) without the credential ever actually existing on minio. Copies `mc`/`mcli` from minio's own already-pinned server image rather than introducing a new base. Also declares `region: eu-west` in `serves.s3-bucket` (was stale at `us-east-1`) and on both the server and sidecar containers — the live deployment had `eu-west` set out-of-band, not in any manifest at all, and the real minio server had no region configured whatsoever, apparently lost across an earlier container recreation since nothing declared it to survive one. Already built, pushed, and verified live on novox — real credential confirmed created (`mesh_novox_ncloud`), a real WebDAV write/read round-tripped through nextcloud afterward.
jschoubben added 11 commits 2026-09-25 15:25:13 +00:00
The pinned digest resolved to a PHP 8.5.10 image; Nextcloud 30 refuses to
run above PHP 8.4. Repinned to the current digest for the nextcloud:30 tag
(matches HAL's own NEXTCLOUD_VERSION), which carries PHP 8.3.28 -- the
same version the data being migrated was actually running under.
The sidecar's own client needs MESH_NEXTCLOUD_ADMIN_PASSWORD to list
shares over the OCS API, but the runtime container's env/volumes never
carried it -- only the server container did. Delivered the same way every
other sealed value in this manifest already is: a generated env-file with
the ${secret:admin} substitution, not a raw value in the container's env.
The mesh's own check caught it: an env-file-loaded secret still reaches
the process environment, readable via docker inspect and /proc (hq
04-ISSUES/041) -- the same class of exposure the file-based delivery
exists to avoid. Added MESH_NEXTCLOUD_ADMIN_PASSWORD_FILE support to the
client, matching the pattern the minio client already uses, and mounted
the sealed admin secret directly rather than writing it into an env-file.
- MESH_NEXTCLOUD_URL hardcoded :80 instead of the mesh-assigned ${port:80}
- sidecar's occ() shells to docker exec but the docker CLI binary was never
  present in the runtime image, only the mounted socket
build refused to reach docker:cli implicitly (novox/hq ADR 0097); pin it by
digest and thread it through as DOCKER_CLI, redeclared in the final stage
since args declared before the first FROM don't carry past it
the legacy (non-BuildKit) docker build this host runs doesn't expand ARGs
inside COPY --from — only FROM. Give it its own named stage instead
the migrated data has no literal 'admin' account — HAL's real admin login
is a personal account (jochens), not a generic one. Resetting that would
touch a real user's own credential, so the module gets its own dedicated
admin-group service account instead, same pattern as the minio per-module
service accounts. mesh-admin was created once by hand on novox to match
this manifest for the already-migrated data; a genuinely fresh install
seeds it automatically via NEXTCLOUD_ADMIN_USER/NEXTCLOUD_ADMIN_PASSWORD.
minio runs with MINIO_REGION=eu-west; nextcloud's S3 config never set a
region, so every object write (avatars, file writes) failed signature
validation with AuthorizationHeaderMalformed, surfacing as Internal Server
Error on real page loads
the s3-bucket binding already carries serves.region (same mechanism as
at/port); ${bound:s3-bucket:region} tracks whatever minio is actually
configured with instead of a copy that can drift
mesh-minio's s3-bucket provisioner shells out to mc to create buckets and
service accounts on the live server, but mc was never in this module's own
runtime image, only in minio's own. It's been silently retrying 'spawn mc
ENOENT' forever, so every s3-bucket grant reached the control-plane layer
(store.json, sealed secret) without the credential ever actually existing
on minio — nextcloud's live instance just hit this as InvalidAccessKeyId
on a real user session.

Copies mc from minio's own image (docker.io/pgsty/minio, already pinned
and pulled as this module's server container) rather than introducing a
new base — mc there is a working, already-verified binary. /usr/bin/mc is
a symlink to mcli; both are copied so it resolves.
serves.s3-bucket.region still said us-east-1 (PR #58 already fixed this,
unmerged) while the live mesh-minio sidecar had MESH_MINIO_REGION=eu-west
set out-of-band, not in the manifest at all — and the actual minio server
had no region configured whatsoever (mc admin config get region: empty),
apparently lost across a container recreation since nothing declared it.
Every s3-bucket consumer binding ${bound:s3-bucket:region} was reading
the stale us-east-1 declaration regardless of what was actually live.

Declares MINIO_REGION on the server container and MESH_MINIO_REGION on
the sidecar, matching the static serves declaration, so this is mesh-
managed and durable rather than a manual mc admin config or docker env
override that the next recreation silently drops.
jschoubben merged commit 19e0a8469d into main 2026-09-25 15:25:19 +00:00
jschoubben deleted branch fix/minio-provisioner-missing-mc-cli 2026-09-25 15:25:19 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: novox/mesh-catalog#62