This is a two part post which will guide you to host your own django app in a production environment using Amazon Web Services (AWS) for storing static files and Heroku for hosting the project.

This part will cover the storing of static files in AWS S3 Bucket.
AWS Setup
1. Create an AWS Account here.
2. Create a new S3 Bucket
- Navigate to S3 from here.
- Click
Create Bucket. - Create a unique bucket name.
- Select region according to your Primary user’s location. For reference, see: AWS Regions and Endpoints.
- Keep other settings as the default ones and create the bucket.
3. Create credentials for AWS User
- Navigate to IAM Users.
- Select
Create New Users - Enter the username.
- Ensure
Programmatic Accessis selected and hitNext. - Select
Download credentialsand keep thecredentials.csvfile safe as it will be required later.
4. Add policies to your IAM user
Default policies
- Navigate to IAM Home.
- Select user and click on
Permissionstab. - Click on
Attach Existing Policies Directlyand add any policies as per your requirement.
Custom Policies
- Navigate to IAM Home.
- Select user and click on
Permissionstab. - Click on
Attach Existing Policies Directlyand selectCreate Policy. - Go to the
JSONtab and paste the policy given below. Change all<your_bucket_name>to the name of your bucket in S3 (set above). Do not change version date.{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:ListAllMyBuckets" ], "Resource": "arn:aws:s3:::*" }, { "Effect": "Allow", "Action": [ "s3:ListBucket", "s3:GetBucketLocation", "s3:ListBucketMultipartUploads", "s3:ListBucketVersions" ], "Resource": "arn:aws:s3:::<your_bucket_name>" }, { "Effect": "Allow", "Action": [ "s3:*Object*", "s3:ListMultipartUploadParts", "s3:AbortMultipartUpload" ], "Resource": "arn:aws:s3:::<your_bucket_name>/*" } ] } - The Actions that we choose to set are based on what we want this user to be able to do. The line
"s3:*Object*", will handle a lot of our permissions for handling objects for the specified bucket within the Recourse Value.
Django Setup
1. Install requirements
boto and boto3 are python bindings for AWS. django-storages are used by django to send static files to AWS.
$ pip install boto boto3 django-storages
2. Update settings and migrate
- Add the app
storagesto theINSTALLED_APPSinsettings.pyINSTALLED_APPS = [ ... 'storages', ... ] - Run migrations
$ python manage.py migrate
3. Set up the AWS module
- Create
awsmodule in same directory assettings.py$ pwd /path/to/<your-project>/<main-app>/ $ ls __init__.py settings.py wsgi.py urls.py $ mkdir aws && cd aws $ touch __init__.py $ touch utils.py $ touch conf.py - In
utils.pyadd the followingfrom storages.backends.s3boto3 import S3Boto3Storage StaticRootS3BotoStorage = lambda: S3Boto3Storage(location='static') MediaRootS3BotoStorage = lambda: S3Boto3Storage(location='media') - Fetch the
Access Key IdandSecret Access Keyfromcredentials.csvdownloaded earlier. Then inconf.pyadd the followingimport datetime AWS_ACCESS_KEY_ID = "<your_access_key_id>" AWS_SECRET_ACCESS_KEY = "<your_secret_access_key>" AWS_FILE_EXPIRE = 200 AWS_PRELOAD_METADATA = True AWS_QUERYSTRING_AUTH = True DEFAULT_FILE_STORAGE = '<your-project>.aws.utils.MediaRootS3BotoStorage' STATICFILES_STORAGE = '<your-project>.aws.utils.StaticRootS3BotoStorage' AWS_STORAGE_BUCKET_NAME = '<your_bucket_name>' S3DIRECT_REGION = 'us-west-2' S3_URL = '//%s.s3.amazonaws.com/' % AWS_STORAGE_BUCKET_NAME MEDIA_URL = '//%s.s3.amazonaws.com/media/' % AWS_STORAGE_BUCKET_NAME MEDIA_ROOT = MEDIA_URL STATIC_URL = S3_URL + 'static/' ADMIN_MEDIA_PREFIX = STATIC_URL + 'admin/' two_months = datetime.timedelta(days=61) date_two_months_later = datetime.date.today() + two_months expires = date_two_months_later.strftime("%A, %d %B %Y 20:00:00 GMT") AWS_HEADERS = { 'Expires': expires, 'Cache-Control': 'max-age=%d' % (int(two_months.total_seconds()), ), }
4. Update settings.py
from <your-project>.aws.conf import *
5. Push the static files to S3 Bucket
$ python manage.py collectstatic
Note
- Any existing media files (before the AWS setup) cannot be uploaded to the bucket automatically, they have to be manually uploaded either from AWS website, Django admin or through aws-cli. For cli, see: AWS CLI Setup
Once AWS has been setup, all media files will be directly uploaded to AWS bucket. - For testing, to disable the AWS upload and use local static files, comment out
from <your-project>.aws.conf import *
from settings.py