Integrating AWS S3 for Media Storage in Django

Local storage for media files doesn't scale. If you're running multiple EC2 instances or containers, user uploads need to exist in a centralized, highly available location. Amazon S3 is the perfect solution.
Step 1: AWS Setup
- Create an S3 Bucket (e.g.,
my-django-media-bucket). - Set Object Ownership to "ACLs enabled".
- Uncheck "Block all public access" (ensure you secure this later via IAM policies).
- Create an IAM User with AmazonS3FullAccess programmatic access and save the Access Key ID and Secret Access Key.
Step 2: Install Dependencies
pip install boto3 django-storages
Add storages to your INSTALLED_APPS in settings.py:
INSTALLED_APPS = [
# ...
'storages',
]
Step 3: Configure Settings
Add the following to your settings.py:
AWS_ACCESS_KEY_ID = 'your-access-key-id'
AWS_SECRET_ACCESS_KEY = 'your-secret-access-key'
AWS_STORAGE_BUCKET_NAME = 'my-django-media-bucket'
AWS_S3_REGION_NAME = 'us-east-1'
AWS_S3_CUSTOM_DOMAIN = f'{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com'
AWS_S3_FILE_OVERWRITE = False
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
MEDIA_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/media/'
Note: Always use environment variables for your AWS keys (e.g., os.environ.get('AWS_ACCESS_KEY_ID')). Do not hardcode them!
Step 4: Testing Uploads
In your models, use a standard ImageField or FileField.
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
avatar = models.ImageField(upload_to='avatars/')
When a user uploads a file through the Django admin or a form, django-storages intercepts the file saving process and streams the payload directly to your S3 bucket.
Step 5: Serving Static Files (Optional)
You can also serve CSS and JS from S3.
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
STATIC_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/static/'
Then run:
python manage.py collectstatic
✅ Done
Your Django application is now storing media files flawlessly on AWS S3, enabling infinite scalability for user uploads.