How To Store Django Static and Media Files in AWS S3
Posted by Vivek Shukla on Sep 6, 2023 under Django
In this guide we will use django-storages package to manage our static and media files. Let’s walkthrough the whole process on how to store django static and media files in aws s3.
S3 is a cloud based object storage service provided by AWS (Amazon Web Services), it stands for Simple Storage Service (S3).
Using AWS S3 to serve Static and Media files in Django makes sense since Django is not good at serving those and S3 provides a lot more feature around these.
Table of Contents
S3 Bucket
Create a bucket
Let’s create a S3 Bucket where our files will be stored. Few things to keep in mind:
ACL must be enabled, so that we can control object permission from our Django
Uncheck all “Block Public Access settings for this bucket” settings and check the acknowledge box
CORS
After bucket is created successfully, now we need to update the CORS settings of the bucket so that if content is being served to different host then your browser might block it.
Open the bucket
Go to the Permissions tab
At the end of the page there will be CORS settings
Put the JSON given below, make sure to put the host which will use the S3 files, you can put multiples.
[
{
"AllowedHeaders": ["*"],
"AllowedMethods": ["HEAD", "GET"],
"AllowedOrigins": ["yourdomain.com"],
"ExposeHeaders": []
}
]
IAM User
An IAM user allow us to access AWS resources programmatically. We need IAM credentials to upload the files to S3.
Create IAM User
Go to IAM page in your AWS Console.
Go to Users then Add users.
Fill out the name that you want to give this user.
Go ahead and create the user, you can skip the permission.
Setting up Permission
Open IAM user which you intend on using.
Make sure you are on Permissions (default) tab.
From “Add permissions” dropdown select “Create inline policy”.
Select JSON policy editor instead of Visual and paste below JSON. Make sure to update the bucket name.
Give the policy appropriate name and save the changes.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": ["arn:aws:s3:::your-bucket-name", "arn:aws:s3:::your-bucket-name/*"]
}
]
}
Get the access key
To use the IAM user in our django project we will need to generate access key.
Open user page, go to Security credentials tab
Scroll down to Access keys section and click on Create access key button
Select “Local code” from the use case menu
Setting Up Django
Installing necessary packages
We will be using django-storages package to manage our connection with AWS S3 and to upload our files. We will also need boto3 package to connect to AWS, which django-storages uses.
pip install boto3 django-storages
Storage Backend
django-storages provides S3Boto3Storage
class for media storage and S3StaticStorage
for static files.
We will subclass S3Boto3Storage
to create our custom storage class so that we can customize certain things.
In your_project/custom_storage.py
from django.conf import settings
from storages.backends.s3boto3 import S3Boto3Storage
class StaticStorage(S3Boto3Storage):
location = settings.STATICFILES_LOCATION
default_acl = "public-read"
querystring_auth = False
class MediaStorage(S3Boto3Storage):
location = settings.MEDIAFILES_LOCATION
default_acl = "public-read"
file_overwrite = False
Update settings.py
We also need to update our settings.py file with media and static files settings:
STATICFILES_DIRS = [
BASE_DIR / "static_assets",
]
AWS_S3_ACCESS_KEY_ID = "your_aws_key"
AWS_S3_SECRET_ACCESS_KEY = "your_aws_secret"
AWS_S3_REGION_NAME = "ap-south-1" # change to your region
AWS_STORAGE_BUCKET_NAME = "your_bucket_name"
AWS_DEFAULT_ACL = None
AWS_S3_CUSTOM_DOMAIN = f"{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com"
# static files
STATICFILES_LOCATION = "static"
STATIC_URL = f"https://{AWS_S3_CUSTOM_DOMAIN}/{STATICFILES_LOCATION}/"
# media files
MEDIAFILES_LOCATION = "media"
MEDIA_URL = f"https://{AWS_S3_CUSTOM_DOMAIN}/{MEDIAFILES_LOCATION}/"
# storage backends
STORAGES = {
"default": {"BACKEND": "your_project.custom_storage.MediaStorage"}, # for media
"staticfiles": {"BACKEND": "your_project.custom_storage.StaticStorage"},
}
AWS_S3_OBJECT_PARAMETERS = {
"CacheControl": "max-age=2592000",
}
We have done all the setup for our static and media files to be uploaded to our S3 bucket. You can test it out in your django project. You can also checkout the tutorial on how to create file upload api using django rest framework.