장고와 같은 대부분의 웹프로젝트에는 정적 파일과 미디어 파일이 있어요. 웹 처리 과정에서 이런 파일은 응당하는 용도로만 작용해요.
하지만 용량이 커서 부하가 큽니다. 즉 비용이 증가한다는 말이에요.
이런 점을 고려해서 운용환경에서는 웹서버와 다른 스토리지 서버를 별도로 두어 정적 파일 및 미디어 파일을 서비스하는 것이 일반적입니다.
즉, 스토리지 서버를 별도로 두면 웹 서버 처리 능력이 높아지고 서버 확장도 쉬워집니다.
양동이라느 의미이고 가상의 디스크라고 생각하면 되요.
즉, 우리는 양동이를 만들어서 정적파일과 미디어 파일을 저장 할 것이에요.
AWS 서비스에서는 보안을 강화하기 위해 하위 개념의 사용자를 생성할 수 있고, 각 사용자별로 권한을 따로 줄 수 있어요.
처음 AWS에서 만든 계정은 root 계정입니다. 즉, 보스라고 보면되요.
사용자
클릭사용자 이름
입력 후 엑세스 유형
에서 프로그래밍 방식 엑세스
체크 후 다음 버튼 클릭
프로그래밍 방식 엑세스
: 지금 생성하는 사용자는 boto3 패키지를 활용하여 프로그래밍 방식으로 S3 자원에 액세스 합니다. 이 방식에는 사용자의 액세스 키와 비밀 액세스 키가 필요한데, 사용자 생성 마지막 단계에서 확인 할 수 있어요.
기존정책직접연결
버튼 클릭!AmazonS3FullAccess
정책을 체크한 후 우측 아래 다음 버튼을 클릭!.csv다운로드
버튼을 눌러 access key와 secret key를 추후에도 확인 할 수 있어요.장고 프로젝트에서 AWS S3와 연동하려면 해당 API를 사용해야합니다.
2가지 패키지를 설치할게요.
pip install boto3
pip install django-storages
S3 API를 쉽게 사용하도록 도와주는 파이썬 SDK입니다.
boto3는 S3 서비스 이외에도 EC2, DynamoDB등 여러가지 AWS 서비스들을 제어하는 기능도 제공합니다.
장고의 저장소 엔진 기능을 제공합니다. 즉, django-storages 패키지에서 boto3dml SDK를 활용해서 S3 저장소를 제어해요.
이 패키지를 이용하면 AWS S3이외에 Google Cloud Storage, Dropbox 등의 원격 저장소를 활용할 수도 있습니다.
프로젝트 설정 파일을 모아둔 디렉토리의 settings.py파일과 urls.py을 수정하고 storage.py(다른 곳에 둬도 되요) 새로 생성합니다.
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
...
...
...
#'storages',
]
# 파일의 끝에 아래 내용을 추가합니다.
STATICFILES_STORAGE = '프로젝트디렉토리명.storage.S3StaticStorage'
DEFAULT_FILE_STORAGE = '프로젝트디렉토리명.storage.S3MediaStorage'
# AWS_ACCESS_KEY_ID = 'IAM 사용자 생성후 받게된 ACCESS KEY ID'
# AWS_SECRET_ACCESS_KEY = 'IAM 사용자 생성후 받게된 SECRET KEY ID'
# AWS_S3_REGION_NAME = 'ap-northeast-2' # 한국 아닌 지역은 다른 명칭으로 바꿔주세요.
# AWS_STORAGE_BUCKET_NAME = '버킷 이름'
# AWS_S3_CUSTOM_DOMAIN = f'{AWS_STORAGE_BUCKET_NAME}.s3.{AWS_S3_REGION_NAME}.amazonaws.com'
# AWS_DEFAULT_ACL = 'public-read'
]
STATICFILES_STORAGE: 정적 파일에 대한 저장소 클래스를 지정해요. STATICFILES_STORAGE 항목의 디폴트 값은 StaticFilesStorage클래스이며 이 클래스는 로컬에 있는
정적파일에 대한 저장소 역할을 해요. 반면 새로 지정한 S3StaticStorage클래스는 원격에 있는 S3 버킷을 저장소로 사용해요.
DEFAULT_FILE_STORAGE: 미디어 파일에 대한 저장소 클래스를 지정해요. DEFAULT_FILE_STORAGE 항목의 디폴트 값은 FileSystemStorage클래스이며 이 클래스는 로컬에 있는 정적파일에 대한 저장소 역할을 해요. 반면 새로 지정한 S3MediaStorage클래스는 원격에 있는 S3 버킷을 저장소로 사용해요.
AWS_DEFAULT_ACL = 'public-read'는 버킷에 대한 액세스 권한을 지정하는 것인데요. public-read는 버킷과 객체(정적파일, 미디어파일)에 대해 소유자느 모든 권한을 가지며 그외 사용자는 읽기만 가능한 권한입니다.
여기서는 정적 파일 및 미디어 파일 저장소 클래스를 정의해요.
아래 두 클래스 모두 S3Boto3Storage를 상속 받아 정의해요. 즉 장고에서 필요한 저장소 엔진 기능은 S3Boto3Storage 클래스에 이미 정의되어 있어요.
location 항목에는 S3 버킷 하위의 폴더명을 정의해요.
from storages.backends.s3boto3 import S3Boto3Storage
# 정적 파일용
class S3StaticsStorage(S3Boto3Storage):
location = 'static'
# 미디어 파일용
class S3MediaStorage(S3BotoStorage):
location = 'media'
urlpatterns += static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
부분은 미디어 파일을 로컬 저장소에 저장하는 경우 사용해요.
이제는 S3에 서비스 하므로 삭제하거나 주석 처리할게요.
from django.conf import settings
from django.conf.urls.static import static
...
urlpatterns += static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
정적 파일을 한곳에 모아주는 명령어를 사용할게요.
요 명령으로 정적 파일들을 S3버킷에 업로드해요.
python manage.py collectstatic
버킷 아래 static, media 디렉토리와 그 아래 파일들이 있으면 정상이에요.
인스턴스는 가상머신, 즉 가상으로 만든 서버 H/W 박사를 의미해요.
이제 AWS MySQL <--> Django를 연동해 볼게요.
그러기 위해선 드라이버 설치가 필요해요.
가상 환경을 실행한 이후 아래 명령어를 입력할게요.
pip install mysqlclient
참고! mysqlclient 설치 실패시
- 원인: Visual C++ 빌드 과정에서 에러 발생.
- 해결책: *.whl 패키지를 아래 사이트에서 다운하고 설치함.
- https:www.lfd.uci.edu/~gohlke/pythonlibs/#mysql-python 으로 접속
- mysqlclient-1.4.4-cp38-win_amd64.whl패키지를 선택해 다운로드 한 경우,
- pip install mysqlclient-1.4.4-cp38-win_amd64.whl
다른 방법으로는 mysqlclient 대신 pymysql 패키지를 이용하는 것이에요. 순수 파이썬 패키지이므로 빌드 에러가 발생하지 않아요.
프로젝트 설정 디렉토리안의 settings.py 파일로 가서 DATABASE 변수를 변동 할게요.
DATABSE = {
'default':{
'ENGINE':'django.db.backends.mysql',
'NAME': '데이터베이스 이름'
'USER': '인스턴스 생성시 입력한 마스터 사용자', #
'PASSWORD': '인스턴스 생서시 입력한 비번',
'HOST': '엔드포인트' #
'PORT': 3306, # 변동하지 않았다면 기본 3306입니다.
'OPTIONS':
'init_command': 'SET sql_mode='STRICT_TRANS_TABLES'",
}
}
STRICT_TRANS_TABLES 항목은 레코드 생성, 변경 시 컬럼 타입이나 데이터 길이 등을 정확하게 체크하여 데이터 일부가 잘리는 것을 방지하는 기능을 해요.(잘못 입력시 오료률 발생시킴)
아래 명령어로 디비에 환경 설정 사항등을 반영해줄게요. 기존 DB인 sqlite3의 테이블들은 초기화 되므로, SQLite3 DB에 있던 예전 데이터는 삭제되요.
python manage.py migrate
python manage.py runserver # 서버 구동 후 정상적으로 확인!