Add S3/MinIO (RustFS) support and compose updates
Introduce S3-compatible storage support and update local/dev configuration. - .claude: add "WebSearch" to local settings - backend/.env.example: add USE_S3 flag and detailed S3/MinIO (RustFS) example env vars + comments to explain dev vs production usage - backend/vontor_cz/settings.py: refactor to use USE_S3 boolean; set STATIC_ROOT; configure STORAGES for local filesystem vs S3 backends; add handling for S3 endpoint (MinIO/RustFS) vs real AWS S3 including path-style addressing, URL construction, and sensible AWS defaults - docker-compose.yml: add rustfs to service dependencies, include rustfs in networks, change frontend port mapping to 8001:80, and add rustfs-data volume binding These changes enable using a local S3-compatible backend (RustFS/MinIO) in development while keeping the option to swap to real AWS S3 for production.
This commit is contained in:
@@ -626,63 +626,59 @@ STATICFILES_DIRS = [
|
||||
|
||||
|
||||
|
||||
if os.getenv("USE_AWS", "") == "True":
|
||||
USE_AWS = True
|
||||
else:
|
||||
USE_AWS = False
|
||||
USE_S3 = _env_bool("USE_S3")
|
||||
print(f"USE_S3: {USE_S3}")
|
||||
|
||||
print(f"\n-------------- USE_AWS: {USE_AWS} --------------")
|
||||
STATIC_ROOT = BASE_DIR / 'collectedstaticfiles'
|
||||
|
||||
if USE_AWS is False:
|
||||
# Development: Use local file system storage for static files
|
||||
if not USE_S3:
|
||||
# Local filesystem — development only
|
||||
STORAGES = {
|
||||
"default": {
|
||||
"BACKEND": "django.core.files.storage.FileSystemStorage",
|
||||
},
|
||||
"staticfiles": {
|
||||
"BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage",
|
||||
},
|
||||
"default": {"BACKEND": "django.core.files.storage.FileSystemStorage"},
|
||||
"staticfiles": {"BACKEND": "django.contrib.staticfiles.storage.StaticFilesStorage"},
|
||||
}
|
||||
|
||||
# Media and Static URL for local dev
|
||||
MEDIA_URL = os.getenv("MEDIA_URL", "/media/")
|
||||
MEDIA_URL = os.getenv("MEDIA_URL", "/media/")
|
||||
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
|
||||
|
||||
STATIC_URL = '/static/'
|
||||
STATIC_ROOT = BASE_DIR / 'collectedstaticfiles'
|
||||
elif USE_AWS:
|
||||
# PRODUCTION
|
||||
|
||||
AWS_LOCATION = "static"
|
||||
else:
|
||||
# S3-compatible storage — MinIO (AWS_S3_ENDPOINT_URL set) or real AWS S3 (endpoint empty)
|
||||
S3_BUCKET = os.getenv('AWS_STORAGE_BUCKET_NAME', 'vontor')
|
||||
S3_ENDPOINT = os.getenv('AWS_S3_ENDPOINT_URL', '')
|
||||
S3_CUSTOM_DOMAIN = os.getenv('AWS_S3_CUSTOM_DOMAIN', '')
|
||||
S3_SSL = not S3_ENDPOINT or S3_ENDPOINT.startswith('https')
|
||||
S3_PROTO = 'https' if S3_SSL else 'http'
|
||||
|
||||
# Production: Use S3 storage
|
||||
STORAGES = {
|
||||
"default": {
|
||||
"BACKEND" : "storages.backends.s3boto3.S3StaticStorage",
|
||||
},
|
||||
|
||||
"staticfiles": {
|
||||
"BACKEND" : "storages.backends.s3boto3.S3StaticStorage",
|
||||
},
|
||||
"default": {"BACKEND": "storages.backends.s3boto3.S3Boto3Storage"},
|
||||
"staticfiles": {"BACKEND": "storages.backends.s3boto3.S3StaticStorage"},
|
||||
}
|
||||
|
||||
# Media and Static URL for AWS S3
|
||||
MEDIA_URL = f'https://{os.getenv("AWS_STORAGE_BUCKET_NAME")}.s3.amazonaws.com/media/'
|
||||
STATIC_URL = f'https://{os.getenv("AWS_STORAGE_BUCKET_NAME")}.s3.amazonaws.com/static/'
|
||||
AWS_ACCESS_KEY_ID = os.getenv('AWS_ACCESS_KEY_ID')
|
||||
AWS_SECRET_ACCESS_KEY = os.getenv('AWS_SECRET_ACCESS_KEY')
|
||||
AWS_STORAGE_BUCKET_NAME = S3_BUCKET
|
||||
AWS_S3_SIGNATURE_VERSION = 's3v4'
|
||||
AWS_S3_FILE_OVERWRITE = False
|
||||
AWS_DEFAULT_ACL = None
|
||||
AWS_QUERYSTRING_AUTH = False
|
||||
AWS_S3_USE_SSL = S3_SSL
|
||||
|
||||
CSRF_TRUSTED_ORIGINS.append(STATIC_URL)
|
||||
|
||||
# Static files should be collected to a local directory and then uploaded to S3
|
||||
STATIC_ROOT = BASE_DIR / 'collectedstaticfiles'
|
||||
|
||||
AWS_ACCESS_KEY_ID = os.getenv('AWS_ACCESS_KEY_ID')
|
||||
AWS_SECRET_ACCESS_KEY = os.getenv('AWS_SECRET_ACCESS_KEY')
|
||||
AWS_STORAGE_BUCKET_NAME = os.getenv('AWS_STORAGE_BUCKET_NAME')
|
||||
AWS_S3_REGION_NAME = os.getenv('AWS_S3_REGION_NAME', 'us-east-1') # Default to 'us-east-1' if not set
|
||||
AWS_S3_SIGNATURE_VERSION = 's3v4' # Use AWS Signature Version 4
|
||||
AWS_S3_USE_SSL = True
|
||||
AWS_S3_FILE_OVERWRITE = True
|
||||
AWS_DEFAULT_ACL = None # Set to None to avoid setting a default ACL
|
||||
if S3_ENDPOINT:
|
||||
# MinIO / S3-compatible: needs path-style addressing
|
||||
AWS_S3_ENDPOINT_URL = S3_ENDPOINT
|
||||
AWS_S3_ADDRESSING_STYLE = 'path'
|
||||
if S3_CUSTOM_DOMAIN:
|
||||
AWS_S3_CUSTOM_DOMAIN = S3_CUSTOM_DOMAIN
|
||||
AWS_S3_URL_PROTOCOL = f'{S3_PROTO}:'
|
||||
base_host = S3_CUSTOM_DOMAIN or f'{S3_ENDPOINT.split("://")[1]}/{S3_BUCKET}'
|
||||
MEDIA_URL = f'{S3_PROTO}://{base_host}/'
|
||||
STATIC_URL = f'{S3_PROTO}://{base_host}/static/'
|
||||
else:
|
||||
# AWS S3
|
||||
AWS_S3_REGION_NAME = os.getenv('AWS_S3_REGION_NAME', 'us-east-1')
|
||||
MEDIA_URL = f'https://{S3_BUCKET}.s3.amazonaws.com/media/'
|
||||
STATIC_URL = f'https://{S3_BUCKET}.s3.amazonaws.com/static/'
|
||||
CSRF_TRUSTED_ORIGINS.append(STATIC_URL)
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user