MinIO (S3)#
MinIO offers open source S3 compatible object storage, thier solution is very advanced and can scale the way AWS native S3 can across many nodes, alternatively it works just as well on a single system with the added benefit of coming with a easy-to-use user interface that can also be used to manage access controls.
See tests/minio for complete template.
Adding minio to your app’s docker-compose.yaml#
services:
# ...
yourapp-minio:
image: quay.io/minio/minio
pull_policy: missing
restart: unless-stopped
command: server /data --console-address ":9001"
environment:
- MINIO_ROOT_USER=minio
# this should be in your .env file and set to a long random string
- MINIO_ROOT_PASSWORD
ports:
- target: 9000
published: 9000
x-kubernetes:
annotations:
maayanlab.cloud/ingress: https://s3.yourapp.k8s.dev.maayanlab.cloud
- target: 9001
published: 9001
x-kubernetes:
annotations:
maayanlab.cloud/ingress: https://console.s3.yourapp.k8s.dev.maayanlab.cloud
volumes:
- yourapp-minio-data:/data
volumes:
yourapp-minio-data:
x-kubernetes:
size: 1Gi
class: local-path
Transfering your local database to the production database#
# copy file from docker minio onto your system
docker compose cp yourapp-minio:/data data
# copy file from your system up to the cloud (the -T option is necessary for this particular image)
kube-compose cp -T data yourapp-minio:/data
# copy file from cluster minio onto your system
kube-compose cp -T yourapp-minio:/data data
# copy file from your system up to the cloud (the -T option is necessary for this particular image)
docker compose cp data yourapp-minio:/data
Accessing the database in your app#
The database will be accessible at the hostname corresponding to your service name, but it’s best practice to set up an environment variable to specify the location. For example, in python:
.env
:# so you can test accessing the database locally S3_URL=http://minio:YOURMINIO_PASSWORD@localhost:9000/yourbucket PUBLIC_S3_URL=http://localhost:9000/yourbucket
docker-compose.yaml
:services: yourapp-app: environment: # so your app container goes to the right location, **NOT localhost** - S3_URL=http://minio:${MINIO_ROOT_PASSWORD}$@yourapp-minio:9000/yourbucket - PUBLIC_S3_URL=https://s3.yourapp.k8s.dev.maayanlab.cloud
app.py
:import os import io import json import dotenv from minio import Minio from urllib.parse import urlparse dotenv.load_dotenv() # connect to db S3_URL_parsed = urlparse(os.environ['S3_URL']) s3 = Minio( f"{S3_URL_parsed.hostname}:{S3_URL_parsed.port}", access_key=f"{S3_URL_parsed.username}", secret_key=f"{S3_URL_parsed.password}", secure=S3_URL_parsed.scheme == 'https', ) # create the bucket if it doesn't exist bucket, _, _ = S3_URL_parsed.path[1:].partition('/') if not s3.bucket_exists(bucket): s3.make_bucket(bucket) # enable anonymous downloading of files in this bucket s3.set_bucket_policy(bucket, json.dumps({ 'Version': '2012-10-17', 'Statement': [ {'Effect': 'Allow', 'Principial': {'AWS': '*'}, 'Action': 's3:GetBucketLocation', 'Resource': f"arn:aws:s3:::{bucket}"}, {'Effect': 'Allow', 'Principial': {'AWS': '*'}, 'Action': 's3:GetObject', 'Resource': f"arn:aws:s3:::{bucket}/*"}, ], })) # create a file content = b'Hello World!' s3.put_object(bucket, 'test.txt', io.BytesIO(content), len(content), content_type='plain/text') print(f"File available at <{os.environ['PUBLIC_S3_URL']}/test.txt>") # ... use s3 in your app deal with files ...