웹/배포

[Final 14] 서버 용량 걱정 끝! S3로 Static & Media 파일 관리하기

jumemory 2025. 9. 10. 09:01

 

[Final 14] 서버 용량 걱정 끝! S3로 Static & Media 파일 관리하기

Django 서비스에는 두 종류의 파일이 있습니다. 개발자가 미리 준비한 Static(CSS, JS, 로고) 파일과 사용자가 업로드하는 Media(프로필 사진, 게시글 이미지) 파일입니다. 이 파일들을 EC2가 아닌 AWS S3라는 무한한 저장소에 맡겨 서버 부하를 줄이고 데이터 안전성을 확보해 봅시다.


1. 왜 로컬 서버가 아니라 S3인가?

  • 무한한 확장성: 서버 하드디스크 용량을 신경 쓸 필요가 없습니다. 쓴 만큼만 비용을 지불하면 됩니다.
  • 데이터 보존: 서버(EC2)를 삭제하거나 새로 띄워도 S3에 저장된 파일은 그대로 유지됩니다.
  • 부하 분산: 웹 브라우저가 이미지나 CSS를 서버가 아닌 S3에서 직접 가져오므로, Django 서버의 CPU/메모리 자원을 아낄 수 있습니다.
  • 고가용성: 아마존이 데이터를 여러 곳에 복제하여 보관하므로 유실 위험이 거의 없습니다.

2. AWS S3 버킷(Bucket) 생성 및 설정

  1. S3 콘솔 접속: [버킷 만들기] 클릭.
  2. 버킷 이름: 전 세계에서 중복되지 않는 고유한 이름 설정 (예: my-django-storage-2026).
  3. 객체 소유권: ACL 활성화됨 선택 (Django 라이브러리 호환성을 위해 필요할 수 있습니다).
  4. 퍼블릭 액세스 차단 설정: 테스트를 위해 '모든 퍼블릭 액세스 차단' 해제 (실무에서는 특정 정책을 사용하지만, 입문 단계에서는 읽기 권한을 열어주어야 브라우저에서 보입니다).

3. IAM 사용자 생성 및 권한 부여

Django가 내 S3에 접근할 수 있는 '열쇠'가 필요합니다.

  1. IAM 콘솔: [사용자 추가] 클릭.
  2. 이름: django-s3-user.
  3. 권한 설정: AmazonS3FullAccess 정책 연결 (보안상 특정 버킷만 허용하는 것이 좋으나 우선 전체 권한으로 진행).
  4. 액세스 키 발급: [보안 자격 증명] 탭에서 Access KeySecret Key를 발급받아 .env에 저장합니다.

4. Django 프로젝트 설정 (django-storages)

Django가 S3와 대화할 수 있게 해주는 라이브러리를 설치하고 설정합니다.

📦 패키지 설치

Bash
 
pip install django-storages boto3

⚙️ settings.py 및 .env 설정

Python
 
# .env 파일에 추가
AWS_ACCESS_KEY_ID=발급받은키
AWS_SECRET_ACCESS_KEY=발급받은비밀키
AWS_STORAGE_BUCKET_NAME=버킷이름
AWS_S3_REGION_NAME=ap-northeast-2

# settings.py 수정
INSTALLED_APPS = [
    ...
    'storages',
]

# S3 설정
AWS_S3_ACCESS_KEY_ID = env('AWS_ACCESS_KEY_ID')
AWS_S3_SECRET_ACCESS_KEY = env('AWS_SECRET_ACCESS_KEY')
AWS_STORAGE_BUCKET_NAME = env('AWS_STORAGE_BUCKET_NAME')
AWS_S3_REGION_NAME = env('AWS_S3_REGION_NAME')

# 정적 파일 및 미디어 파일 저장 경로를 S3로 지정
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3StaticStorage'

# S3 URL 설정
AWS_S3_CUSTOM_DOMAIN = f'{AWS_STORAGE_BUCKET_NAME}.s3.amazonaws.com'
STATIC_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/static/'
MEDIA_URL = f'https://{AWS_S3_CUSTOM_DOMAIN}/media/'

5. 정적 파일 업로드 (collectstatic)

설정을 마쳤다면 로컬에 있는 Static 파일들을 S3로 모두 쏘아 올립니다.

Bash
 
python manage.py collectstatic

이 명령어를 실행하면 정적 파일들이 S3 버킷의 static/ 폴더 안으로 업로드됩니다. 이제 브라우저에서 소스 보기를 하면 이미지 경로가 S3 주소로 바뀐 것을 확인할 수 있습니다.


6. [선생님의 심화 보충] 보안을 위한 서명된 URL (Signed URLs)

만약 아무나 내 S3 파일을 보는 게 싫다면(예: 유료 강의 영상), AWS_S3_QUERYSTRING_AUTH = True 설정을 사용하세요.

  • 파일 URL 뒤에 일시적인 토큰이 붙어, 일정 시간이 지나면 링크가 만료됩니다. 보안이 중요한 서비스를 운영할 때 필수적인 기능입니다.

✍️ 블로그 작성을 위한 마지막 조언

독자들에게 **"이제 서버가 가벼워졌습니다!"**라고 외쳐주세요. 특히 사용자가 이미지를 올렸는데 서버를 재배포했다는 이유로 이미지가 엑박(Broken Image)이 뜨던 고질적인 문제가 해결되었다는 점을 강조하면 큰 공감을 얻을 수 있습니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

powershell 관리자 권한 

netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=8001 connectaddress=내wsl ip connectport=8001

- 포트 등록 확인 

netsh interface portproxy show all

- 삭제

netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=8001

방화벽 인바운드 새규칙

-포트

 

wsl에서 모델 서빙 가동

python manage.py runserver 0.0.0.0:8001

 

-ser1에서 wsl로 통신되는지 확인-

curl -i -X POST "http://윈도우ip:8001/predict/" \

     -H "Content-Type: application/json" \

     -d '{"content":"배가 고파요"}'

 

gunicorn --bind 0:8001 senti.wsgi:application --workers 2






requirements.txt

 

Django

djangorestframework

transformers

gunicorn

torch==2.7.1



Dockerfile 

 

FROM python:3.11.13-slim

 

WORKDIR /usr/src/app

 

RUN apt update

RUN apt install gcc -y

 

COPY . /usr/src/app

 

RUN pip install --upgrade pip

RUN pip install -r requirements.txt

 

CMD ["gunicorn", "--bind", "0:8001", "senti.wsgi:application"]




docker build -t model_serving:0.1 . 



 docker run -itd --name serving -p 8001:8001 model_serving:0.1





export DJANGO_SETTINGS_MODULE=mysite.settings.local

 

python manage.py makemigrations board 

 

# Create your models here.

class Question(models.Model):

    author = models.ForeignKey(User, on_delete=models.CASCADE)

    subject = models.CharField(max_length=200)

    content = models.TextField()

    create_date = models.DateTimeField()

    modify_date = models.DateTimeField(null=True, blank=True)

    sentiment = models.CharField(max_length=200)

 

    def __str__(self):

        return self.subject

 

 

wsl에서 도커 데몬 실행시키고 진행해야함 도커를 먼저 켜야함

 

 

 

✅ 1. WSL에서 root 계정으로 들어가기

Windows PowerShell(관리자 권한)에서 실행:

 
wsl -u root
  • -u root 옵션으로 WSL을 root 사용자로 직접 실행합니다.
  • root 계정은 패스워드 입력이 필요 없어요.

✅ 2. root 계정에서 사용자 비밀번호 재설정

root로 들어간 뒤(위 1단계):

 
passwd 사용자이름

예:

 
passwd play

👉 새 비밀번호를 입력하면 해당 사용자 계정 비밀번호가 초기화됩니다.


✅ 3. 기본 사용자 바꾸기 (옵션)

만약 root로만 들어가고 싶으면 (임시조치):

PowerShell에서:

 
wsl --set-default-user root

이러면 WSL 실행 시 기본적으로 root 계정으로 들어갑니다.
그 다음 원래 사용자 비번 고친 후 다시 기본 사용자로 되돌릴 수 있어요:

 
wsl --set-default-user play

🚨 주의할 점

  • root 계정은 제한 없이 시스템을 건드릴 수 있으니 비밀번호 고친 후에는 다시 일반 사용자로 돌아가서 쓰는 게 안전합니다.
  • WSL의 root 계정은 기본적으로 비밀번호가 설정돼 있지 않아서 바로 접속 가능해요.