Using AWS S3 for Static and Media Files

If you want to use AWS S3 for storing your static and media files then you can follow these steps to get things setup and going.

Setup an AWS User and S3 Bucket

  1. Login to your AWS Console and create an IAM user for your Django project, making sure to only give the user programmatic access. Make sure you save the public access key and the secret key, because you’ll need those for your Django settings.
  2. Create an S3 Bucket. If you want to eventually point a CNAME DNS record to this bucket then make sure your bucket name is a fully qualified domain name.
  3. Give the user you created access to the bucket. Create a policy like the following and add it to your user. You could name it Something like, MyDjangoProjectNameS3Access.
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::django-base-site"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:PutBucketCORS",
                "s3:DeleteObject",
                "s3:PutObjectAcl"
            ],
            "Resource": "arn:aws:s3:::django-base-site/*"
        }
    ]
}
  1. Add the following CORS configuration to your bucket.
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>HEAD</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
</CORSConfiguration>

Update your Django Project Settings

  1. Add the following to your Pipfile. Update the version numbers for whatever is current.
django-storages = "<1.7,>=1.6.5"
"boto3" = "<1.6,>=1.5.8"
  1. Install the requirements.
$ pipenv install
  1. Add storages to your INSTALLED_APPS.
INSTALLED_APPS = [
    ...
    'storages',
]
  1. Add the following to your .env settings.
DEFAULT_FILE_STORAGE=apps.base.storage.MediaS3Storage
STATICFILES_STORAGE=apps.base.storage.StaticS3Storage
AWS_ACCESS_KEY_ID=<your key goes here>
AWS_SECRET_ACCESS_KEY=<your secret key goes here>
AWS_STORAGE_BUCKET_NAME=<your bucket name goes here>

Usage

If you set the DEFAULT_FILE_STORAGE to apps.base.storage.MediaS3Storage in the .env file, your django project will use Django Storages to save your static and media files to S3. If you want you can use your local filesystem during development, then just make sure you don’t set the DEFAULT_FILE_STORAGE setting locally and only set it on your production instances.

After every static file change, you’ll have to run manage.py collectstatic to upload your static files to S3. This usually is done programmatically using a tool like Fabric.