TL;DR Here's the example code on github: github.com/naomiaro/django-minio-storage
This post assumes that you've added a host entry for minio to /etc/hosts
127.0.0.1 minio
Recently while working on an application for the BC Public Service, I've tried configuring django-storages to be backed by a private Minio bucket rather than Amazon S3. Minio is API compatible with Amazon S3 cloud storage service, so we can use this point to our advantage when setting up django-storages backed by a minio bucket.
The settings passed to Django look as follows for django-storages:
# django-storages settings
DEFAULT_FILE_STORAGE = "storages.backends.s3boto3.S3Boto3Storage"
MINIO_ACCESS_KEY = os.getenv("MINIO_ROOT_USER")
MINIO_SECRET_KEY = os.getenv("MINIO_ROOT_PASSWORD")
MINIO_BUCKET_NAME = os.getenv("MINIO_BUCKET_NAME")
MINIO_ENDPOINT = os.getenv("MINIO_ENDPOINT")
AWS_ACCESS_KEY_ID = MINIO_ACCESS_KEY
AWS_SECRET_ACCESS_KEY = MINIO_SECRET_KEY
AWS_STORAGE_BUCKET_NAME = MINIO_BUCKET_NAME
AWS_S3_ENDPOINT_URL = MINIO_ENDPOINT
AWS_DEFAULT_ACL = None
AWS_QUERYSTRING_AUTH = True
AWS_S3_FILE_OVERWRITE = False
Credentials from minio.env
are passed via Docker so that they are available as environment variables.
**Note that these credentials are just default local development settings, don't store any secrets in github.
Let's take a closer look at the projects' development docker-compose.yml
file.
minio:
image: minio/minio
hostname: "minio"
volumes:
- ./minio:/minio_files
env_file:
- minio.env
command: 'minio server /minio_files --console-address ":9001"'
ports:
- 9000:9000
- 9001:9001
The minio
service starts the Minio server for local dev. The volume will mount any uploaded files back into the local minio folder so the contents can be seen if needed.
createbuckets:
image: minio/mc
depends_on:
- minio
env_file:
- minio.env
entrypoint: >
/bin/sh -c "
/usr/bin/mc config host add myminio http://minio:9000 minioadmin minioadmin;
/usr/bin/mc mb --quiet myminio/photos;
/usr/bin/mc policy set none myminio/photos;
"
The createbuckets
service uses the Minio client to setup configuration and create a private bucket (policy set to none). If you want to view the bucket via the Minio console, it's available at http://minio:9000
with user/pass minioadmin/minioadmin
The demo Django project code on github includes a Django app photos
which defines a single model Record
. The record contains a photo uploaded to our private bucket by using a model ImageField.
photo = models.ImageField(upload_to="docs")
The method photo_tag
creates an image tag which can be rendered on our admin panel page directly.
def photo_tag(self):
return mark_safe(
'<img src="%s" width="600" />'
% (media_storage.url(name=self.photo.file.name))
)
Because the bucket is private and we have setting AWS_QUERYSTRING_AUTH = True
, Minio will generate a signed url for secure access to load and display our image. Links are valid for one hour by default. Look into adjusting setting AWS_QUERYSTRING_EXPIRE
if one hour is not suitable.
http://minio:9000/photos/docs/IMG_20190628_203544.jpg?AWSAccessKeyId=minioadmin&Signature=l08S%2BWA7qzguBFl6FfUtcGSn%2Ftc%3D&Expires=1651646316
The admin panel nicely displays the photo inline below thanks to jazzmin and our photo_tag
method on our Record
model.