개발

AWS S3 캐싱 정책 일괄변경 작업 + Laravel 옵션

나는 AWS S3를 통해서 게시글 본문 이미지를 호스팅 하고 있다.
이 S3를 최대한 잘 사용해보기 위해서 그위에 Cloud Front를 얹어서 CDN 처럼 지역 배포하는 기능을 구현해놨는데, 이게 캐싱설정이 제대로 먹지 않는다는걸 알게되었다.

무슨말이냐면 아무리 CloudFront에 캐시정책이 제대로 설정되어있다하더라고 S3에 설정된것을 우선적으로 적용한다는 말이다.

그말은 즉슨 S3 파일헤더에도 관련된 캐싱값이 있어야 한다고한다.
뭔 이런 개떡같은 구조가 다있냐 하겠지만 실제로 그런걸 어떻하나...

S3 메타데이터 변경 작업

일단 기존에 올라가있는 몇천개의 파일의 캐싱주기를 다 설정해줘야한다.

하나씩 설정하는 방법은 S3로 들어가 버킷 -> 객체 -> 속성 탭에서 메타 데이터 영역을 찾아서 수정하면된다.

본문 이미지

근데 나만해도 몇천개의 파일을 이미 넣어놨는데 이렇게 하나씩 바꾸는건 비정상적인 행위라고할 수 있다.

그나마 aws 콘솔로 이 작업을 쉽게 할 수 있는 방법이 있다.

JPG 파일

aws s3 cp s3://erulabo/ s3://erulabo/ \
  --recursive \
  --exclude "*" --include "*.jpg" --include "*.jpeg" \
  --metadata-directive REPLACE \
  --cache-control "public, max-age=31536000, immutable" \
  --content-type "image/jpeg"Copy

aws cli를 터미널에 깔고 위 명령어를 통해서 파일 확장자별로 캐싱설정값을 넣을 수 있다.
왜 이렇게 파일별로해야하냐면 S3 파일엔 content-type이 붙어있는데 이 값을 파일확장명에 맞게 부여해야하기때문이다.

반복적으로 png, webp, mp4등도 아래와 같은 명령어로 변경할 수 있다.

PNG 파일

aws s3 cp s3://erulabo/ s3://erulabo/ \
  --recursive \
  --exclude "*" --include "*.png" \
  --metadata-directive REPLACE \
  --cache-control "public, max-age=31536000, immutable" \
  --content-type "image/png"Copy

WEBP 파일

aws s3 cp s3://erulabo/ s3://erulabo/ \
  --recursive \
  --exclude "*" --include "*.webp" \
  --metadata-directive REPLACE \
  --cache-control "public, max-age=31536000, immutable" \
  --content-type "image/webp"Copy

MP4 파일

aws s3 cp s3://erulabo/ s3://erulabo/ \
  --recursive \
  --exclude "*" --include "*.mp4" \
  --metadata-directive REPLACE \
  --cache-control "public, max-age=31536000, immutable" \
  --content-type "video/mp4"Copy

이런식으로 확장자에 맞는 content-type를 부여해서 메타데이터를 수정해주면 된다.


라라벨에서 S3 업로드시 캐시 정책 추가하는법

나는 라라벨 환경에서 작업을 하는데 라라벨의 경우 별도의 Storage 패키지를 통해 S3와 연동작업을 할 수 있다.
이때 config/filesystem.php 파일을 좀 만져주는것으로 위의 캐시값을 자동 추가할 수 있다.

's3' => [
    'driver' => 's3',
    'key' => env('AWS_ACCESS_KEY_ID'),
    'secret' => env('AWS_SECRET_ACCESS_KEY'),
    'region' => env('AWS_DEFAULT_REGION'),
    'bucket' => env('AWS_BUCKET'),
    'url' => env('AWS_URL'),
    'endpoint' => env('AWS_ENDPOINT'),
    'cloudfront_url' => env('AWS_CLOUDFRONT_URL'),
    'options' => [
        'CacheControl' => 'public, max-age=31536000, immutable',
    ],
],Copy

맨 아래 options 배열을 통해 메타디에터를 쉽게 추가할 수 있다.
진작에 알았다면 이렇게 데이터 쌓이고 작업할일은 없었을꺼같은데...

본문 이미지

이렇게 캐싱정보를 추가한 후 제대로 추가되었는지 확인하고싶으면 터미널에서 아래 명령어로 쉽게 네트워크 파일의 헤더 데이터를 까볼 수 있다.

  ~ curl -I https://cdn.erulabo.com/editor/s0t8zl6xqzezDtAkjIUZm3cQKsBPgRB82sqWM2mX_optimized.webp    
HTTP/2 200 
content-type: image/webp
content-length: 25634
date: Mon, 21 Apr 2025 07:02:50 GMT
last-modified: Mon, 21 Apr 2025 07:00:25 GMT
etag: "810bc8b143dcb7b104ac2960ae4e0465"
x-amz-server-side-encryption: AES256
cache-control: public, max-age=31536000, immutable
accept-ranges: bytes
server: AmazonS3
x-cache: Miss from cloudfront
via: 1.1 0c9ac74e4533d4cd2c0dd7de136ec086.cloudfront.net (CloudFront)
x-amz-cf-pop: ICN57-P2
x-amz-cf-id: 1okZagSQEd3lmSDVWVl50ycK25TY1KpBbf1sjv_M7ucuVzP3kufvoA==Copy

cache-control 항목이 보인다면 제대로 된것이다.
끝!

#문제해결 #AWS
0 개의 댓글
×