I have set up MinIO as my Django app object storage and integrate the functionality of this module on my the same server. I followed the instruction in django-minio-backend
, but I got the below error.
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='subdomain.domain.org', port=9000): Max retries exceeded with url: /django-backend-dev-public (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1006)')))
A few contextual issues for the setup environment:
The server runs Ubuntu
22.04 LTS operating system. the MinIO
version is 2024-08-03T04-33-23Z. The Django
version is 5.0.6
The MinIO setup worked perfectly when I had set it up to use unsecured connections (http), and Django running was running on the server unsecured. The Django web app could be able to upload files and images to MinIO server without any issue.
The error started when I updated the MinIO setup to work using secured connections only. On the WebUI, the server loads using https perfectly (i.e. I can log onto the console using https://subdomain.domain.org:9000)
The secure setup is done through linking the MinIO to the SSL certificate folder on the server (/opt/minio/certs) that contains both the public.crt
and private.key
The relevant lines for MinIO setup for my Django web-app in my settings.py are as follows:
ALLOWED_HOSTS = [
'localhost',
'127.0.0.1',
'subdomain.domain.org'
]
CSRF_TRUSTED_ORIGINS = [
'https://subdomain.domain.org',
'https://127.0.0.1',
'https://localhost'
]
CSRF_ALLOWED_ORIGINS = ["https://subdomain.domain.org", "https://localhost"]
CORS_ORIGINS_WHITELIST = ["https://subdomain.domain.org", "https://localhost"]
INTERNAL_IPS = ['127.0.0.1', 'localhost', 'subdomain.domain.org']
MINIO_CONSISTENCY_CHECK_ON_START = True
MINIO_ENDPOINT = 'subdomain.domain.org:9000'
MINIO_EXTERNAL_ENDPOINT = 'subdomain.domain.org:9000'
MINIO_EXTERNAL_ENDPOINT_USE_HTTPS = True
MINIO_REGION = 'eu-west-1' # Default is set to None, current is Ireland
MINIO_ACCESS_KEY = 'XXXXXX'
MINIO_SECRET_KEY = 'YYYYY'
MINIO_USE_HTTPS = True
MINIO_URL_EXPIRY_HOURS = timedelta(
days=1) # Default is 7 days (longest) if not defined
MINIO_PRIVATE_BUCKETS = ['django-backend-dev-private', ]
MINIO_PUBLIC_BUCKETS = ['django-backend-dev-public', ]
MINIO_POLICY_HOOKS: List[Tuple[str, dict]] = []
MINIO_MEDIA_FILES_BUCKET = 'bridge-media-files-bucket'
MINIO_PRIVATE_BUCKETS.append(MINIO_MEDIA_FILES_BUCKET)
MINIO_STATIC_FILES_BUCKET = 'bridge-static-files-bucket'
MINIO_PRIVATE_BUCKETS.append(MINIO_STATIC_FILES_BUCKET)
MINIO_BUCKET_CHECK_ON_SAVE = True
# SSL
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SECURE_SSL_REDIRECT = True
SECURE_HSTS_SECONDS = 31536000 # 1 year
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
Might anyone have an idea why the secure configuration is throwing the error urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='subdomain.domain.org', port=9000): Max retries exceeded with url: /django-backend-dev-public (Caused by SSLError(SSLCertVerificationError(1, '[SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate (_ssl.c:1006)')))
My SSL certificate was through GoDaddy. Django requires each certificate in the CA chain to be passed separately in an array, not just the typical final certificate. From your GoDaddy crt bundle, the crt to use for configuring HTTPS for both both Django and MinIO should look something like this:
-----BEGIN CERTIFICATE-----
MIIE3jCCA...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIE3jFDFA...
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIEADCCA...
-----END CERTIFICATE-----