Setting up the project
My aim when setting this up was to run the application locally using
python manage.py runserver, but to use Heroku for production.
I experimented with the Two Scoops of Django convention of using separate settings files. This makes it easier to have versions of the application running locally and in production (or in “staging”).
To achieve this, I set up the Django application in the normal way, but created
settings folder in the “project folder” (which sits alongside the app
directory you should have set up as part of starting a new Django project), the
contents of which are as follows:
-rw-r--r-- 1 lemon lemon 3221 Aug 17 10:58 base.py -rw-r--r-- 1 lemon lemon 65 Aug 10 09:27 heroku_local.py -rw-r--r-- 1 lemon lemon 0 Aug 3 16:03 __init__.py -rw-r--r-- 1 lemon lemon 394 Aug 3 16:18 local.py -rw-r--r-- 1 lemon lemon 1116 Aug 17 13:52 staging.py
The path is
The hiearchy created through importing these modules is as follows:
base.py -> staging.py -> heroku_local.py -> local.py
This contains most of the baseline settings already generated automatically by
django-admin startproject. These settings are imported by the other “sub”
from .staging import * ALLOWED_HOSTS = ['localhost', '0.0.0.0']
These are the settings used when running
heroku local (more on which
later). Here were are saying that everything that we need to run Heroku is
staging settings module, but here we just want to override the
Hosting Django static files in an AWS bucket
It took a lot of fannying around, but I finally go there. Here are the steps to doing it - hopefully this will enable a reproducable situation.
Create a new user on AWS here. Give it a decent simple username and ensure Programmatic Access is checked. Download the CSV containing the AWS Access ID and AWS Access Secret Key here before you navigate away.
Take a note of the ARN by clicking on the newly created username at the above page. Copy and paste this and hang onto it because you’ll need this to set up your bucket policy.
Create a new bucket here. Give it a name and sensible region. Copy the settings from a previous one that works in Django if you can.
Set permissions by clicking on the bucket in the bucket list and going to Permissions tab, then Bucket Policy. I did a lot of fucking about here when I set this up for the first time but I found this the easiest way to start with a useable JSON file. Click the Policy generator button.
Using the policy generator. Select “S3 Bucket Policy” as Type. Select Allow, paste your ARN from the user console into the Principle box, check All Services, and then put the ARN for the bucket in the ARN box, using arn:aws:s3::
. Then click add Statement. This is the main thing that gives your app programmatic access to the bucket. I don’t think we need to worry about adding other statements here necessarily, but there are loads of other permissions we can set. Click Generate.
Copy the resulting JSON file. You need to paste this into Bucket Policy text area and click Save. This should now mean that any application quoting this user’s id and secret key can programatically acess the files in the bucket. That’s the idea here.