Django에서 S3를 미디어 파일 저장소로 설정하는 방법

Django에서 S3를 미디어 파일 저장소로 설정하는 방법

안녕하세요! 오늘은 Django 프로젝트에서 AWS S3를 미디어 파일 저장소로 설정하는 방법에 대해 알아보겠습니다. 이 설정을 통해 정적 파일과 미디어 파일을 효율적으로 관리할 수 있습니다.

왜 S3를 사용할까요?

AWS S3를 사용하는 주요 이점은 다음과 같습니다:

  1. 확장성: 트래픽이 증가해도 안정적으로 서비스 가능
  2. 비용 효율성: 사용한 만큼만 지불
  3. 고가용성: 99.99%의 가용성 보장
  4. 보안: AWS의 강력한 보안 시스템 활용
  5. CDN 연동: CloudFront와 쉽게 연동 가능

프로젝트 설정

먼저 필요한 패키지들을 설치합니다:

pip install django-storages boto3

AWS 설정

  1. AWS 계정 생성 (없는 경우)
  2. IAM 사용자 생성 및 S3 접근 권한 부여
  3. Access Key와 Secret Key 발급

Django 설정

settings.py에 다음과 같이 설정을 추가합니다:

# AWS 설정
AWS_ACCESS_KEY_ID = 'your-access-key-id'
AWS_SECRET_ACCESS_KEY = 'your-secret-access-key'
AWS_STORAGE_BUCKET_NAME = 'your-bucket-name'
AWS_S3_REGION_NAME = 'ap-northeast-2'  # 서울 리전
AWS_S3_CUSTOM_DOMAIN = f'{AWS_STORAGE_BUCKET_NAME}.s3.{AWS_S3_REGION_NAME}.amazonaws.com'
AWS_S3_OBJECT_PARAMETERS = {
    'CacheControl': 'max-age=86400',
}

# S3를 기본 스토리지로 설정
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3StaticStorage'

# 미디어 파일 URL 설정
MEDIA_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/media/'
STATIC_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/static/'

S3 버킷 설정

1. 버킷 생성

  1. AWS S3 콘솔에 접속
  2. "버킷 만들기" 클릭
  3. 버킷 이름 입력 (전역적으로 유일해야 함)
  4. 리전 선택 (ap-northeast-2)
  5. 버킷 설정:
    • 버전 관리: 활성화
    • 서버 액세스 로깅: 활성화
    • 객체 수준 로깅: 활성화

2. CORS 설정

버킷의 권한 탭에서 CORS 설정을 추가합니다:

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "GET",
            "PUT",
            "POST",
            "DELETE",
            "HEAD"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": []
    }
]

3. 버킷 정책 설정

버킷의 권한 탭에서 버킷 정책을 추가합니다:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "PublicReadGetObject",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::your-bucket-name/*"
        }
    ]
}

커스텀 스토리지 클래스

특별한 요구사항이 있는 경우 커스텀 스토리지 클래스를 만들 수 있습니다:

# storage_backends.py
from storages.backends.s3boto3 import S3Boto3Storage

class MediaStorage(S3Boto3Storage):
    location = 'media'
    file_overwrite = False

class StaticStorage(S3Boto3Storage):
    location = 'static'
    file_overwrite = True

그리고 settings.py를 수정합니다:

DEFAULT_FILE_STORAGE = 'your_app.storage_backends.MediaStorage'
STATICFILES_STORAGE = 'your_app.storage_backends.StaticStorage'

파일 업로드 예제

1. 모델 설정

# models.py
from django.db import models

class Document(models.Model):
    title = models.CharField(max_length=100)
    file = models.FileField(upload_to='documents/')
    uploaded_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title

class Image(models.Model):
    title = models.CharField(max_length=100)
    image = models.ImageField(upload_to='images/')
    uploaded_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title

2. 폼 설정

# forms.py
from django import forms
from .models import Document, Image

class DocumentForm(forms.ModelForm):
    class Meta:
        model = Document
        fields = ('title', 'file',)

class ImageForm(forms.ModelForm):
    class Meta:
        model = Image
        fields = ('title', 'image',)

3. 뷰 설정

# views.py
from django.shortcuts import render, redirect
from .forms import DocumentForm, ImageForm
from django.contrib import messages

def upload_document(request):
    if request.method == 'POST':
        form = DocumentForm(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            messages.success(request, '문서가 성공적으로 업로드되었습니다.')
            return redirect('document_list')
    else:
        form = DocumentForm()
    return render(request, 'upload_document.html', {'form': form})

def upload_image(request):
    if request.method == 'POST':
        form = ImageForm(request.POST, request.FILES)
        if form.is_valid():
            form.save()
            messages.success(request, '이미지가 성공적으로 업로드되었습니다.')
            return redirect('image_list')
    else:
        form = ImageForm()
    return render(request, 'upload_image.html', {'form': form})

파일 다운로드 예제

# views.py
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from .models import Document

def download_document(request, document_id):
    document = get_object_or_404(Document, id=document_id)
    response = HttpResponse(document.file, content_type='application/force-download')
    response['Content-Disposition'] = f'attachment; filename="{document.file.name}"'
    return response

성능 최적화

1. CloudFront 연동

# settings.py
AWS_S3_CUSTOM_DOMAIN = 'your-cloudfront-domain.cloudfront.net'

2. 캐시 설정

# settings.py
AWS_S3_OBJECT_PARAMETERS = {
    'CacheControl': 'max-age=86400',
    'Expires': 'Thu, 31 Dec 2099 20:00:00 GMT',
}

보안 설정

1. IAM 정책

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject",
                "s3:DeleteObject"
            ],
            "Resource": "arn:aws:s3:::your-bucket-name/*"
        }
    ]
}

2. 환경 변수 사용

# settings.py
import os

AWS_ACCESS_KEY_ID = os.environ.get('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = os.environ.get('AWS_SECRET_ACCESS_KEY')

모니터링 및 로깅

1. CloudWatch 설정

# settings.py
AWS_S3_USE_SSL = True
AWS_S3_VERIFY = True

2. 로깅 설정

# settings.py
LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        's3': {
            'level': 'DEBUG',
            'class': 'logging.handlers.S3Handler',
            'bucket': AWS_STORAGE_BUCKET_NAME,
            'key': 'logs/django.log',
        },
    },
    'loggers': {
        'django': {
            'handlers': ['s3'],
            'level': 'DEBUG',
            'propagate': True,
        },
    },
}

주의사항

  1. 비용 관리: S3 사용량을 모니터링하고 비용을 관리하세요.
  2. 보안: Access Key와 Secret Key를 안전하게 관리하세요.
  3. 버전 관리: 중요한 파일은 버전 관리를 활성화하세요.
  4. 백업: 정기적으로 S3 버킷의 백업을 확인하세요.

결론

AWS S3를 Django의 미디어 파일 저장소로 사용하면 확장성 있고 안정적인 파일 저장 시스템을 구축할 수 있습니다. 이 글에서 소개한 설정과 예제들을 참고하여 자신의 프로젝트에 맞는 S3 스토리지를 구현해보세요. 추가적인 질문이나 궁금한 점이 있으시면 댓글로 남겨주세요!

댓글