장고(Django)에서 S3 연동하기

Amazon Web Service S3

Posted by Siner on July 17, 2019

출처 : django 에서 S3에 Static, media 파일 저장하고 사용하기

소셜미디어 프로젝트를 준비하면서, Static 파일들에 대한 트래픽 부담을 줄이기 위해 S3를 도입하고자 하였다.

Django에서 S3를 연동하기 위해서는 boto라는 라이브러리를 사용해야 한다는 것은 이미 알고 있었으나, 정확한 사용 방법을 몰라서 찾아보았고, 나중에도 사용할 때 까먹지 않기 위해 포스팅으로 작성하려 한다.

1. 버킷 생성

image 버킷 이름을 작성하고 image 넘어가고 image 모든 유저가 읽을 수 있게 Block 설정을 해제해주자 image 최종 확인 후 생성한다 image 버킷이 생성되었다

2. Policy 설정

image Bucket 선택후 Permissions - Bucket Policy 에서, 아래처럼 내용을 작성한다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
{
    "Statement": [
        {
            "Sid": "PublicReadForGetBucketObjects",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "s3:GetObject",
            "Resource": "BUCKET-ARN/*"
        },
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": [
                    "USER-ARN"
                ]
            },
            "Action": "s3:*",
            "Resource": [
                "BUCKET-ARN",
                "BUCKET-ARN/*"
            ]
        }
    ]
}

BUCKET-NAME은 Bucket Policy 설정페이지에서 확인이 가능하고,
USER-ARNhttps://console.aws.amazon.com/iam/home#/users에서 유저를 선택하여 확인이 가능하다. (아래 예시) image

3. Access Key 발급

https://console.aws.amazon.com/iam/home#/users에서 키를 발급하고자 하는 유저를 선택한다.
security_credentials탭에 들어가서 Create access key버튼을 클릭하여 키를 발급받는다. image

4. Django 설정

1
2
3
4
5
6
7
8
9
''' .envs/.django
docker-compose의 env_file을 통하여 불러오도록 설정했다.
직접 settings.py에 아래의 데이터를 넣어도 되지만, 다음과 같이 분리하는 것을 추천한다.
'''

AWS_REGION=ap-northeast-2
AWS_STORAGE_BUCKET_NAME=sinerbucketforblog
AWS_ACCESS_KEY_ID=xxxxxxxxxxxxxxxxxxxxxxx
AWS_SECRET_ACCESS_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
''' config/settings.py
S3와 연관없는 내용은 생략.
'''

# AWS Setting
AWS_REGION = env('AWS_REGION')
AWS_STORAGE_BUCKET_NAME = env('AWS_STORAGE_BUCKET_NAME')
AWS_ACCESS_KEY_ID = env('AWS_ACCESS_KEY_ID')
AWS_SECRET_ACCESS_KEY = env('AWS_SECRET_ACCESS_KEY')

AWS_QUERYSTRING_AUTH = False
AWS_S3_HOST = 's3.%s.amazonaws.com' % AWS_REGION
AWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME

# Static Setting
STATIC_URL = "https://%s/" % AWS_S3_CUSTOM_DOMAIN
STATICFILES_STORAGE = 'storages.backends.s3boto.S3BotoStorage'

# Media Setting
MEDIA_URL = "https://%s/" % AWS_S3_CUSTOM_DOMAIN
DEFAULT_FILE_STORAGE = 'storages.backends.s3boto.S3BotoStorage'

# Root Setting
STATIC_ROOT = '%s/static' % STORAGE_PATH
MEDIA_ROOT = '%s/media' % STORAGE_PATH

5. boto 설치

Django에서 boto를 사용할 수 있게 pip 패키지인 boto를 설치해주자.

1
pip install boto

6. collectstatic

collectstatic 진행 후 버킷을 살펴보면 static 파일들이 생성된 것을 확인할 수 있다.

image

7. CORS

admin 페이지에 들어가보면 평소와는 살짝 다른 것 같다. image 확인해보니 폰트를 제대로 불러오지 못하고있다. image

콘솔 확인결과 CORS로 판명. S3에서 해당 처리를 해주도록 하자. image Bucket 선택후 Permissions - CORS configuration 에서, 아래처럼 내용을 작성한다

1
2
3
4
5
6
7
8
9
<!-- Sample Policy -->
<CORSConfiguration>
        <CORSRule>
                <AllowedOrigin>*</AllowedOrigin>
                <AllowedMethod>GET</AllowedMethod>
                <MaxAgeSeconds>3000</MaxAgeSeconds>
                <AllowedHeader>Authorization</AllowedHeader>
        </CORSRule>
</CORSConfiguration>

8. 결과

image 이제 제대로 된다