Sunday, September 7, 2014

Django + Amazon S3

Let me start by saying that there are a lot of good tutorials on the internet, and my motivation for writing this one is simply because its a "different" way for setting up Django with Amazon S3 storage.

As i said i am taking a different approach and although i am not certain if it is the best approach or not it does seem to work for me. If you find that this is not right please let me know in the comments and ill fix it.

Scenario

So the main idea here is to simply create a S3 Bucket that will hold both the static files and the media files, where you can set you static files to be public and your media to be private.


Amazon S3 Steps:

1 - CREATE THE BUCKET

2 - EDIT CORS CONFIGURATION TO BE:



If you do not to this you might end up having JavaScript errors like for example:

XMLHttpRequest cannot load http://myApiUrl/login. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access


3- CREATE STATIC FOLDER AND SET IT TO PUBLIC:
You can use the s3 amazon console and right click on top of the static folder and choose the option `make public`

4 - CREATE MEDIA FOLDER
After crating this folder do not attempt to make it public otherwise it will beat the purpose of this tutorial

5 - YOU CAN START UPLOADING CONTENT BUT PLEASE NOTE THAT:
"It seems that this is a common issue when uploading files to a new bucket.
Something to do with the DNS propagation means it takes a little while before your bucket can successfully accept files. More info here.
After waiting a few hours running the same command completes successfully."
(http://tinyurl.com/q7cpjju)

This means that if you attempt to do a `python manage.py collectstatic` and get a broken pipe

it might be just because the DNS propagation is not finished.


Django Configurations:

Install django-storages and boto, read django-storages documentation and then you can just replace this settings.





You may read in other places that you need to set S3 bucket policies but i found that i really did not need to do that, by setting specifically the folders i want to be public.

2 comments:

  1. in case you need bucket policies here is an example:

    # Bucket policies

    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Sid": "AddPerm",
    "Effect": "Allow",
    "Principal": "*",
    "Action": [
    "s3:GetObject",
    "s3:PutObject"
    ],
    "Resource": "arn:aws:s3:::bucketname/*"
    }
    ]
    }

    ReplyDelete
  2. if you want to use you local static files instead of amazon s3, just comment STATIC_ROOT = '/static/' and STATIC_URL = S3_URL + STATIC_ROOT, and do python manage.py collectstatic

    ReplyDelete