May 21, 2025, 2:57 p.m.  |   Charles U  |   33    |              

How to Store Django Static and Media Files on AWS S3: A Step-by-Step Guide

Introduction

Managing static files like CSS and JavaScript, as well as media uploads such as user photos, can quickly become a headache as your Django app grows. Storing these files locally might seem convenient at first, but it often leads to scalability and performance bottlenecks. This is where AWS S3 (Simple Storage Service) comes to the rescue.

AWS S3 is a reliable, highly scalable, and cost-effective object storage service from Amazon Web Services. It's designed to store and retrieve any amount of data, anytime, from anywhere on the web. By offloading your Django app's static and media files to S3, you not only free up server resources but also benefit from S3's global infrastructure, ensuring fast and secure file delivery to users worldwide.

In this guide, we'll walk through integrating AWS S3 with Django step by step, helping you transform file management into a seamless, scalable experience.

In this guide, we'll:

  1. Set up an AWS S3 bucket.
  2. Configure Django to use S3 for static and media files.
  3. Demonstrate the setup with a simple Django project.

Prerequisites

Before you start, ensure you have:

  • Django Project: A simple Django app. We'll create one if needed.
  • Python Installed: Ensure Python 3.8+ is installed.
  • AWS Account: Sign up at AWS if you don't already have an account.
  • Access to AWS Management Console.


Step 1: Set Up Your AWS S3 Bucket

1.1 Create a Bucket

  1. Log in to the AWS Management Console.
  2. Navigate to S3 and click Create bucket.
  3. Configure the following:
    - Bucket Name:
    Use a globally unique name, e.g., mydjangotestbucket.
    - Region:
    Choose your preferred AWS region, e.g., us-east-1.
  4. Uncheck the Block Public Access settings.
  5. Leave other default settings as is.
  6. Click Create bucket.
S3 Service
Create Bucket
S3 Bucket Name
Uncheck Public Access
Create Bucket Successful

1.2 Configure Permissions

  1. Click on your bucket name and go to the Permissions tab.
  2. Add a bucket policy to allow the S3 bucket to serve files:
    1. Copy the Bucket ARN
    2. Use the AWS Policy Generator to create a policy:
      1. Policy Type: S3 Bucket Policy.
      2. Effect: Allow
      3. Principal: * (allow all)
      4. Action: s3:GetObject
      5. Resource: Your bucket's ARN
    3. Generate and copy the policy, then paste it into the Bucket Policy section.
  3. Save the changes
General Purpose Buckets
Bucket Permissions
Setting Bucket Policy
Generate Bucket Policy
Policy JSON Document

1.3 Set Up Access Keys

  1. Click your account name on the top-right of the AWS management Console.
  2. Go to Security Credentials > Access keys.
  3. Create new access keys and download/ save them securely.
Security credentials
Access keys


Step 2: Set Up Your Django Project

Use the sample project to focus on the integration with AWS S3.

Procedure

# Clone the repository
git clone https://github.com/charlesu49/django_s3_demo.git
cd django_s3_demo
# Create and activate a virtual environment

python -m venv venv
source venv/bin/activate 
# On Windows: venv\Scripts\activate
# Install dependencies
pip install -r requirements.txt
# Configure your .env file with:

AWS_ACCESS_KEY_ID=your_access_key_id
AWS_SECRET_ACCESS_KEY=your_secret_access_key
AWS_STORAGE_BUCKET_NAME=your_bucket_name
# Apply migrations and start the server:

python manage.py migrate


Step 3: Install and Configure django-storages

django-storages and boto3 are included in the requirements files

3.2 Update Django Settings

Update your setting.py:

Add 'storages' to your installed apps then add the following AWS configurations.

import os
from dotenv import load_dotenv


load_dotenv("./.env", override=True)


AWS_ACCESS_KEY_ID = os.getenv('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = os.getenv('AWS_SECRET_ACCESS_KEY')


AWS_STORAGE_BUCKET_NAME = 'mydjangotestbucket'
AWS_S3_REGION_NAME = 'us-east-1'
AWS_S3_CUSTOM_DOMAIN = f'{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com'


# S3 Security Settings
AWS_DEFAULT_ACL = None  # Default to bucket settings
AWS_S3_FILE_OVERWRITE = False  # Don't overwrite files with the same name
AWS_S3_VERIFY = True  # Verify SSL certificates
AWS_S3_OBJECT_PARAMETERS = {
    'CacheControl': 'max-age=86400',  # 24 hours cache
}


# Separate storage for static and media files
STORAGES = {


    # Media file (image) management  
    "default": {
        "BACKEND": "storages.backends.s3boto3.S3StaticStorage",
    },
   
    # CSS and JS file management
    "staticfiles": {
        "BACKEND": "storages.backends.s3boto3.S3StaticStorage",
    },
}


# URLs for static and media files
STATIC_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/static/'
MEDIA_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/media/'
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')


Step 4: Test the Setup

  1. Upload static files: python manage.py collectstatic
  2. Create a superuser: python manage.py createsuperuser
  3. Start the development server: python manage.py runserver
  4. Test:
    1. Log in to the admin panel http://localhost:8000/admin/
    2. Upload a file and verify it is served from S3.
    3. Check the S3 console to confirm the file exists.
Admin Panel
Test
File Serving from S3
S3 Console Confirmation


Conclusion

By following this guide, you’ve integrated AWS S3 with Django to manage static and media files efficiently. This setup ensures your app scales smoothly and serves files reliably.