MinIO Testcontainers
The `testcontainers-minio` library is a component of `testcontainers-python`, an active library designed for functional and integration testing with throwaway Docker containers. It simplifies the setup and teardown of MinIO object storage instances for tests. While `testcontainers-python` is currently at version 4.x.x, the `testcontainers-minio` module is at an early release candidate, `0.0.1rc1`. The parent project `testcontainers-python` maintains a frequent release cadence, continuously adding new features and bug fixes across its various modules.
Common errors
-
minio.error.S3Error: S3 operation failed; No such bucket: test-bucket
cause Attempting to put or get an object from a MinIO bucket that has not yet been created.fixEnsure `client.make_bucket(bucket_name)` is called and completes successfully before attempting object operations on that bucket. -
docker.errors.ImageNotFound: 404 Client Error for http+docker://localhost/v1.xx/images/create?fromImage=minio/minio&tag=RELEASE.2022-12-02T19-19-22Z: Not Found ("pull access denied for minio/minio, repository does not exist or may require 'docker login': denied: requested access to the resource is denied")cause Docker daemon cannot pull the specified MinIO image. This often indicates a network issue, an incorrect image name/tag, or insufficient Docker permissions/authentication.fixVerify the image name and tag are correct (e.g., `minio/minio:RELEASE.2022-12-02T19-19-22Z`). Check Docker connectivity and ensure you are logged into Docker Hub if using private repositories. Run `docker pull minio/minio:RELEASE.2022-12-02T19-19-22Z` manually to diagnose. -
TypeError: Minio() got an unexpected keyword argument 'secure'
cause This typically means an older version of the `minio` client library is installed that does not accept the `secure` keyword argument, or there's a mismatch between the expected arguments and the installed client version.fixUpgrade the `minio` client library to a recent version (`pip install --upgrade minio`). Alternatively, remove the `secure` argument if your MinIO instance is HTTP-only and the client's default behavior is to infer security.
Warnings
- gotcha Community modules like `testcontainers-minio` do not strictly follow SemVer. Breaking changes might occur in minor versions without a major version bump, unlike `testcontainers-core`. Always review the changelog for `testcontainers-python` when upgrading to new minor versions.
- gotcha The `minio` client object is thread-safe but not process-safe. Do not share a single `Minio` client instance across multiple processes (e.g., using `multiprocessing.Pool`), as this can lead to unexpected behavior or errors. Instead, create a new `Minio` client instance in each separate process.
- breaking As of `testcontainers-python` v4.14.0, the `minio` client initialization in `MinioContainer` methods (like `get_client()`) may require keyword arguments. Older code expecting positional arguments might break.
- deprecated In `testcontainers-python` v4.14.0, deprecated decorators for wait strategies (e.g., `wait_for_logs`) were replaced with new `WaitStrategy` classes. If you were using custom or older wait patterns, they might need updating.
Install
-
pip install testcontainers[minio] -
pip install testcontainers-minio -
pip install minio
Imports
- MinioContainer
from testcontainers.minio import MinioContainer
- Minio
from minio import Minio
Quickstart
import io
from testcontainers.minio import MinioContainer
from minio import Minio
# Instantiate MinioContainer (it automatically starts on entering 'with')
with MinioContainer() as minio_container:
# Get MinIO client configuration from the container
minio_config = minio_container.get_config()
endpoint = minio_config['endpoint']
access_key = minio_config['access_key']
secret_key = minio_config['secret_key']
# Create a MinIO client instance to interact with the container
client = Minio(
endpoint,
access_key=access_key,
secret_key=secret_key,
secure=False # Testcontainers MinIO usually runs on http by default
)
bucket_name = "test-bucket"
object_name = "hello.txt"
file_content = b"Hello from Testcontainers MinIO!"
# Create a bucket if it doesn't exist
if not client.bucket_exists(bucket_name):
client.make_bucket(bucket_name)
print(f"Bucket '{bucket_name}' created.")
# Upload an object
client.put_object(
bucket_name,
object_name,
io.BytesIO(file_content),
length=len(file_content),
content_type="text/plain"
)
print(f"Object '{object_name}' uploaded to '{bucket_name}'.")
# Retrieve the object
response = client.get_object(bucket_name, object_name)
retrieved_data = response.read()
response.close()
response.release_conn()
print(f"Retrieved data: {retrieved_data.decode('utf-8')}")
assert retrieved_data == file_content
print("MinIO Testcontainers setup successful!")