예전에 했던 트러블슈팅 기록용~..~
나는 현재 프로젝트에서 사용되는 static 파일들을 AWS S3로 전송하고 있다.
사실 배포하지 않거나 EC2 인스턴스의 용량이 충분하다면, 해당 로컬 환경에서 바로 data가 저장되는 형태로 하면 되지만, 그게 아니면 파일을 따로 관리할 필요가 있다.
django settings.py에서 해당 설정은 다음과 같았다.
AWS_ACCESS_KEY_ID = env("AWS_ACCESS_KEY_ID")
AWS_SECRET_ACCESS_KEY = env('AWS_SECRET_ACCESS_KEY')
AWS_STORAGE_BUCKET_NAME = env('AWS_STORAGE_BUCKET_NAME')
AWS_S3_CUSTOM_DOMAIN = AWS_STORAGE_BUCKET_NAME + ".s3.ap-northeast-2.amazonaws.com"
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
STATICFILES_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
BASE_DIR = Path(__file__).resolve().parent.parent
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
딱히 특별하게 설정할 코드가 없던 설정법이었다.
이렇게 설정해줬더니 잘 연결되고 파일도 잘 저장되었는데... 문제는 실제로 서버에 얹히고 사진을 불러오니 url이 잘못되었다.
https://{bucket_name}.s3.{region}.amazonaws.com/static/image/user/user1_profile.jpg
내 설정으로는 위와 같이 나와야 정상이고 s3 객체를 직접 들여다봤을 때에도 해당 url이 나오는데,
https://{bucket_name}.s3.{region}.amazonaws.com/user/user1_profile.jpg
이렇게 중간 경로인 static/image/
이 사라진 문제점이었다.
저렇게 설정했는데도 나와 같이 안 된 케이스가 극히 드물었고... 머리를 쥐어뜯던 중에 한 포럼을 발견하였다. -> 링크
포럼 글 중에서 주목해야할 것은 STATIC_ROOT
와 STATIC_URL
의 차이점인데, KenWhitesell님께서 정리해주셨지만 크게 와닿지 않아 따로 검색을 해봤다.
그러다가 스택오버플로우 글을 보고 이해가 됐다! -> 링크
django의 settings.py에 사용되는 변수 두 개, STATIC_ROOT와 STATIC_URL은 비슷하면서도 다르다.
공통점 : 두 개는 static 파일의 path를 custom하는 역할
STATIC_ROOT : django에서 collectstatic 할 때의 path
STATIC_URL : static file을 서버에 serve할 때의 path
나의 경우엔 file이 제대로 저장되지만 serve할 때 path가 다르게 나타나는 문제였으므로 STATIC_URL을 명시해줘야 했다.
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto3.S3Boto3Storage'
이 이상하게 작동되지 않은 때가 많아서 S3Boto3Storage를 상속받아 custom storage class를 만들었다.AWS_ACCESS_KEY_ID = env('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = env('AWS_SECRET_ACCESS_KEY')
AWS_STORAGE_BUCKET_NAME = env('AWS_STORAGE_BUCKET_NAME')
AWS_S3_CUSTOM_DOMAIN = AWS_STORAGE_BUCKET_NAME + ".s3.ap-northeast-2.amazonaws.com"
# 여기까지는 동일한 코드
# 여기서부터는 수정/추가된 코드
class StaticStorage(S3Boto3Storage):
location = "static"
default_acl = None
class MediaStorage(S3Boto3Storage):
location = "media"
default_acl = None
file_overwrite = True
STORAGES = {
'default': {'BACKEND': f'{project_name}.settings.StaticStorage'},
'staticfiles': {'BACKEND': f'{project_name}.settings.MediaStorage'}
}
STATIC_URL = "https://%s/static/" % AWS_S3_CUSTOM_DOMAIN
MEDIA_URL = "https://%s/media/" % AWS_S3_CUSTOM_DOMAIN