워크샵 이미지와 영상을 저장할 때 로컬 저장소가 아닌 aws s3에 저장하기로 했다.
s3(Simple Storage Service)는 데이터를 객체 형태로 저장하는 원격 파일 저장소다. s3의 저장 용량은 무한대이므로 저장하는 데이터의 양이 증가하더라도 DB 서버를 따로 증설하지 않고 안정적으로 저장할 수 있다는 장점이 있다.
s3는 데이터를 버킷에 객체 형태로 저장하게 되고, 해당 데이터에 접근하려면 자동으로 생성된 객체 url을 불러와야 한다.
따라서 DB에는 파일명만 저장하고 이미지를 불러올 때는 저장되는 url 형태로 가공해줘야만 불러올 수 있는 것이다.
const workshops = await queryBuilder.getRawMany();
return workshops.map((workshop) => ({
...workshop,
purposeTag_name: workshop.purposeTag_name.split(','),
thumb: `${this.configService.get('AWS_CLOUD_FRONT_DOMAIN_IMAGE')}
images/workshops/${workshop.workshop_id}/800/
${workshop.workshop_thumb}`, // bucket 경로에 맞게 가공
우리는 s3와 함께 cloudFront 서비스를 함께 사용했기 때문에 .env 파일에 AWS_CLOUD_FRONT_DOMAIN_IMAGE 변수에 cloudFront url을 저장하여 불러온 다음, 해당 버킷 경로에 맞게 가공해주면 된다.
(CloudFront를 통해 s3로 접근하게 됨)
위와 같이 map 함수로 가공해줬는데도 이미지가 렌더링이 되지 않는 문제가 발생했다. 우선 브라우저 콘솔로 확인했을 때 객체 url은 정상적으로 불러오는 것을 확인했다.
혹시 권한이 없어서 문제가 바생하는 것은 아닐까 싶어, aws에 접속해서 버킷에 들어간 다음 해당 이미지의 url를 버킷에서 직접 클릭해봤다. 페이지에 'access denied'
라는 문구가 나타나서 찾아봤더니 정책 설정을 잘못한 탓이었다.
이미지와 같이 모든 퍼블릭 액세스 차단을 체크하지 않은 상태로 변경 사항을 저장해야 한다. 내 경우 두 번째 항목에 체크가 되어 있어 객체 url에 접근하지 못한 것 같다. 체크를 해제하니 이미지가 정상적으로 렌더링됐다.
우리는 s3와 함께 aws CloudFront를 연동해 이미지를 저장했다. CloudFront는 cdn(Contents Delivery Network) 서비스로서, 전 세계의 엣지 로케이션(edge location, aws가 cdn을 제공하기 위해 만든 서비스인 cloudFront의 캐시 서버)을 통해 콘텐츠를 빠른 속도로 제공한다. 엣지 로케이션에서는 콘텐츠를 캐싱하기 때문에 미리 캐싱된 데이터가 있는 경우 더 빠르게 콘텐츠를 전송할 수 있다.
현재 우리 프로젝트의 경우, 한국에서만 서비스되기 때문에 CDN의 효과를 직접적으로 얻을 수는 없겠으나 추후 글로벌 서비스를 고려한다면 유용한 기능인 것 같다.
또한 CloudFront는 https 통신을 지원하기 때문에 보안성도 향상된다.
s3 버킷의 데이터를 CloudFront로 접근해서 가져오도록 하려면 두 서비스를 연동해줘야 한다.
우선 CloudFront 배포 생성 시 원본 도메인을 설정하는 부분에서 연동할 s3 버킷을 지정해준다.
그런 다음 s3에서 퍼블릭 액세스를 막는다.
이제 s3 버킷에서 객체 url을 클릭했을 때 access denied 문구가 뜨는 것을 확인할 수 있다. CloudFront 도메인을 통해서만 해당 url에 접근 가능하다.