fix(minio): bake bootstrap.sh into image instead of bind-mounting
Some checks failed
CI / Unit & Component Tests (push) Has been cancelled
CI / OCR Service Tests (push) Has been cancelled
CI / Backend Unit Tests (push) Has been cancelled
CI / fail2ban Regex (push) Has been cancelled
CI / Compose Bucket Idempotency (push) Has been cancelled
CI / Unit & Component Tests (pull_request) Failing after 2m50s
CI / OCR Service Tests (pull_request) Successful in 17s
CI / Backend Unit Tests (pull_request) Successful in 4m9s
CI / fail2ban Regex (pull_request) Failing after 12s
CI / Compose Bucket Idempotency (pull_request) Successful in 57s

Closes #506.

Under Docker-out-of-Docker (the production Gitea Actions runner), the
host daemon resolves the relative bind-mount path against the host
filesystem — not the runner container's /workspace. The script is not
there, so Docker creates an empty directory at /bootstrap.sh and the
entrypoint fails with `/bootstrap.sh: Is a directory`.

Bake the script into a tiny derived image (infra/minio/Dockerfile) so
there is no runtime path resolution. Works in DooD, regular Docker,
and CI.

Unblocks the staging / production deploy pipelines from #497 / #499
and turns the Compose Bucket Idempotency CI job green.

Verified locally:
- `docker compose ... config --quiet` parses
- `docker compose ... build create-buckets` builds the image
- bootstrap.sh exists as a +x file at /bootstrap.sh inside the image

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit was merged in pull request #507.
This commit is contained in:
Marcel
2026-05-11 15:32:36 +02:00
parent c3c1efe5f1
commit f8f0951bd5
2 changed files with 22 additions and 4 deletions

View File

@@ -80,7 +80,12 @@ services:
# logic is readable, reviewable, and unit-testable as a script rather # logic is readable, reviewable, and unit-testable as a script rather
# than YAML-escaped shell. # than YAML-escaped shell.
create-buckets: create-buckets:
image: minio/mc:RELEASE.2025-08-13T08-35-41Z # Custom image bakes bootstrap.sh in at build time. A bind-mount fails on
# the Docker-out-of-Docker production runner because the host daemon
# resolves the relative path against the host filesystem, not the
# runner container's CWD. See #506 + infra/minio/Dockerfile.
build:
context: ./infra/minio
depends_on: depends_on:
minio: minio:
condition: service_healthy condition: service_healthy
@@ -89,9 +94,6 @@ services:
environment: environment:
MINIO_PASSWORD: ${MINIO_PASSWORD} MINIO_PASSWORD: ${MINIO_PASSWORD}
MINIO_APP_PASSWORD: ${MINIO_APP_PASSWORD} MINIO_APP_PASSWORD: ${MINIO_APP_PASSWORD}
volumes:
- ./infra/minio/bootstrap.sh:/bootstrap.sh:ro
entrypoint: ["/bin/sh", "/bootstrap.sh"]
# Dev-only mail catcher; gated behind the staging profile so production # Dev-only mail catcher; gated behind the staging profile so production
# never starts it. Staging workflow runs with `--profile staging`. # never starts it. Staging workflow runs with `--profile staging`.

16
infra/minio/Dockerfile Normal file
View File

@@ -0,0 +1,16 @@
# Derived MinIO Client image with the idempotent bootstrap script baked in.
#
# Why a custom image instead of a bind-mount?
# The production Gitea Actions runner is Docker-out-of-Docker. A
# `./infra/minio/bootstrap.sh:/bootstrap.sh:ro` mount resolves the path
# against the HOST filesystem (the host daemon owns the bind), not the
# runner container's `/workspace/...`. The path doesn't exist on the host
# and Docker auto-creates an empty directory at the mount target — the
# entrypoint then fails with `/bootstrap.sh: Is a directory`. Baking the
# script in removes runtime path resolution entirely. See #506.
FROM minio/mc:RELEASE.2025-08-13T08-35-41Z
COPY bootstrap.sh /bootstrap.sh
RUN chmod +x /bootstrap.sh
ENTRYPOINT ["/bin/sh", "/bootstrap.sh"]