Déployer une application Django qui utilise AWS S3 pour gérer ses fichiers médias et fichiers statiques semble, au premier abord, une formalité.
Pourtant, quand on se lance vraiment, les surprises arrivent vite :
erreurs Access Denied,
problèmes avec les ACL,
Bucket Policies trop restrictives,
tableau de bord Django sans style CSS,
erreurs silencieuses à l'upload,
incompréhension de la gestion de l'accès public sur S3.
En tant que développeur, je voulais rendre mon projet plus scalable, plus propre, en hébergeant tous mes médias et fichiers statiques sur AWS S3, plutôt que de tout laisser sur le serveur local.
Je partage ici tout mon cheminement, mes erreurs, et surtout comment je les ai corrigées, pour obtenir une intégration fiable, rapide, et sécurisée.
1. Création du Bucket S3
Première étape, créer un bucket S3.
Je me connecte à AWS Management Console > S3 > Créer un bucket.
Piège n°1 : les paramètres de blocage d'accès public
Par défaut, AWS recommande de bloquer tous les accès publics. Ce que j'ai fait.
Problème ?
Si tout est bloqué, Django, mon frontend et même moi n'avons plus accès aux fichiers !
Solution :
Je laisse coché "Bloquer toutes les ACL (anciennes et nouvelles)" ✅.
Mais je décoche "Bloquer l'accès public via Bucket Policies" ❌.
Ainsi, je gère tout l'accès public à travers une Bucket Policy.
2. Configuration de la Bucket Policy
Deuxième étape, permettre l'accès en lecture publique.
Je mets cette Bucket Policy sur mon bucket :
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowPublicReadAccessToObjects",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::mon-bucket-name/*"
}
]
}
3. Création de l'utilisateur IAM et des clés d'accès
Je crée un utilisateur IAM dans AWS Console :
Accès programmatique uniquement.
Permission AmazonS3FullAccess (temporairement pour tout mettre en place).
Je récupère :
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
À mettre ensuite dans Django.
4. Configuration Django pour utiliser S3
Dans ton settings :
AWS_ACCESS_KEY_ID = '...'
AWS_SECRET_ACCESS_KEY = '...'
AWS_STORAGE_BUCKET_NAME = 'mon-bucket-name'
AWS_S3_REGION_NAME = 'eu-north-1'
AWS_S3_CUSTOM_DOMAIN = f'{AWS_STORAGE_BUCKET_NAME}.s3.{AWS_S3_REGION_NAME}.amazonaws.com'
STATICFILES_STORAGE = 'storage.StaticStorage'
DEFAULT_FILE_STORAGE = 'storage.MediaStorage'
STATIC_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/static/'
MEDIA_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/media/'
Dans ton fichier storage :
from storages.backends.s3boto3 import S3Boto3Storage
class StaticStorage(S3Boto3Storage):
location = 'static'
default_acl = 'public-read'
class MediaStorage(S3Boto3Storage):
location = 'media'
default_acl = 'public-read'
Tu crée ton fichier upload_media pour ne pas ecraser tes fichiers existant
import boto3
import os
from django.conf import settings
from django.core.management.base import BaseCommand
def upload_media_to_s3():
s3_client = boto3.client(
's3',
aws_access_key_id=settings.AWS_ACCESS_KEY_ID,
aws_secret_access_key=settings.AWS_SECRET_ACCESS_KEY,
region_name=settings.AWS_S3_REGION_NAME
)
media_root = settings.MEDIA_ROOT
for root, dirs, files in os.walk(media_root):
for file in files:
local_path = os.path.join(root, file)
relative_path = os.path.relpath(local_path, media_root)
s3_path = os.path.join('media', relative_path)
s3_client.upload_file(
local_path,
settings.AWS_STORAGE_BUCKET_NAME,
s3_path
)
print(f"Uploaded {local_path} to {s3_path}")
if __name__ == "__main__":
import django
django.setup()
upload_media_to_s3()
5. Problèmes rencontrés et solutions
Problème 1 : AccessDenied en accédant aux fichiers
Corrigé en mettant une Bucket Policy propre.
Problème 2 : AccessControlListNotSupported
Mon bucket était configuré avec "Bucket owner enforced".
J'ai supprimé l'option --acl public-read dans AWS CLI.
Problème 3 : tableau de bord Django sans CSS
J'ai oublié d'envoyer mes fichiers staticfiles/ sur S3.
Solution :
python manage.py collectstatic
aws s3 cp staticfiles/ s3://mon-bucket-name/static/ --recursive
6. Script automatique pour uploader les fichiers statiques
J'ai créé un petit script Bash upload_static.sh :
#!/bin/bash
python manage.py collectstatic --noinput
aws s3 cp staticfiles/ s3://mon-bucket-name/static/ --recursive
Exécution :
./upload_static.sh
Simple et efficace !
Conclusion
Intégrer Django avec AWS S3 demande de comprendre quelques subtilités :
Comment S3 gère l'accès public,
Comment fonctionnent les ACL et Bucket Policies,
Comment organiser ses fichiers statiques et médias,
Comment anticiper les erreurs AccessDenied et AccessControlListNotSupported.
Grâce à ce parcours et à ces solutions, j'ai pu rendre mon application plus rapide, plus robuste et prête à scaler.
Si toi aussi tu construis ton projet Django sur AWS, j'espère que ce guide t'évitera de nombreuses heures de galère ! 🚀
Bon déploiement à toi 👋 !