Skip to content

Create and expose buckets at startup so stacks need no init container - #1

Open
mihow wants to merge 4 commits into
mainfrom
feat/default-buckets
Open

mihow wants to merge 4 commits into
mainfrom
feat/default-buckets

Conversation

@mihow

@mihow mihow commented Sep 29, 2026

Copy link
Copy Markdown
Collaborator

Summary

Stacks that use this image currently need a second, short-lived "init" container whose only job is to create buckets and make some of them publicly readable before the application starts. This change moves that job into the image itself. Setting MINIO_DEFAULT_BUCKETS=media:public,backups on the server container creates those buckets at startup, and the image's health check only turns healthy once they exist. A compose file can then drop the init container and simply wait for the MinIO service to be healthy. Stacks that do not set the variable see no change: the server starts exactly as it did before.

The variable name and format match the old Bitnami MinIO image, which many compose files were written against before that image was withdrawn.

List of Changes

  1. Buckets can be created at startup. Setting MINIO_DEFAULT_BUCKETS to a comma-separated list of name[:policy] entries creates each bucket and applies its anonymous-access policy (none, download, upload or public). One log line is printed per bucket.
  2. "Healthy" now means "buckets ready". The image has a built-in health check that passes only when the server is ready and the requested buckets exist, so depends_on: condition: service_healthy replaces the init container.
  3. Misconfiguration stops the container. An invalid bucket name, an unknown policy, or bad credentials stops the server and exits non-zero, instead of leaving a running server with missing buckets.
  4. Existing uses keep working. Without the variable the server is started directly as the main process, --version and other non-server commands go straight to minio, and --entrypoint mc still runs the client.
  5. Every pull request runs a smoke test. The workflow builds an amd64 image into the runner and runs test/smoke.sh against it before the multi-arch build.
  6. The README documents the feature and its compose example no longer has an init container.

Detailed Description

Entrypoint. docker-entrypoint.sh is the new ENTRYPOINT; the default CMD is unchanged (server /data --console-address ":9001"). If the first argument is not server, or MINIO_DEFAULT_BUCKETS is empty, it execs /usr/bin/minio with the original arguments, so the server is PID 1 as before. Otherwise it starts the server in the background, forwards SIGTERM and SIGINT to it, polls mc ready until the server answers (bounded per attempt, because mc ready retries forever on its own, and bounded overall by MINIO_DEFAULT_BUCKETS_TIMEOUT, default 120 seconds), then runs mc mb --ignore-existing and mc anonymous set for each entry. It then waits on the server so the container's exit code is the server's. The mc alias with the root credentials lives in a temporary config directory that is removed after setup, and credentials are never logged.

Health check marker. After the last bucket is set up, the entrypoint writes /tmp/minio-default-buckets.ready. minio-healthcheck passes only if mc ready succeeds against the local server and, when MINIO_DEFAULT_BUCKETS is set, that marker exists. The entrypoint deletes the marker at every start, because /tmp survives a docker restart, so a restarted container is not reported healthy before its buckets are checked again.

Port. The scripts reach the server at http://127.0.0.1:<port>. The port is read from the server's --address argument (default 9000) and written to /tmp/minio-api-port for the health check.

Limits.

  • A single API port on plain HTTP is assumed. TLS on the API port is not supported by the bucket setup.
  • Credentials are read only from MINIO_ROOT_USER and MINIO_ROOT_PASSWORD.
  • Only MINIO_DEFAULT_BUCKETS is compatible with Bitnami; its other variables are not implemented.
  • Policies are applied again on every start, so a policy changed by hand at runtime is reset on the next restart for buckets listed in the variable.

The final build stage still only copies files (COPY --chmod=0755), so the arm64 variant continues to build on an amd64 runner without emulation.

How to Test

./build.sh
test/smoke.sh insectai/minio:dev

The smoke test checks, in order: minio --version reports the pinned release through the entrypoint and --entrypoint mc works; a container with MINIO_DEFAULT_BUCKETS=smoke-public:public, smoke-private becomes healthy, logs one line per bucket and never logs the password; both buckets exist with the right policies; an anonymous GET succeeds on the public bucket and is denied on the private one; the container is healthy again after docker restart; docker stop returns well within the timeout with exit code 0; an unknown policy stops the container with a non-zero code and a clear message; and a container without the variable becomes healthy with minio as PID 1.

For arm64:

IMAGE_TAG=insectai/minio:dev-arm64 ./build.sh --platform linux/arm64
docker run --rm --platform linux/arm64 insectai/minio:dev-arm64 --version

🤖 Generated with Claude Code

https://claude.ai/code/session_01FA1nFdyB4WmWTw4syt89Yz

mihow and others added 4 commits September 29, 2026 16:27
…they exist

The entrypoint starts the server, waits until it is ready, then creates each
listed bucket and applies its anonymous-access policy. The health check only
passes once that setup has finished, so compose can wait on service_healthy
instead of running a separate init container. Without the variable the server
is exec'd directly, as before.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FA1nFdyB4WmWTw4syt89Yz
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.

1 participant