Note1. S3 Architecture
이미지파일 업로드 로직
사용자가 EC2(인스터스/서버)에 이미지 업로드를 API로 요청한다.
S3에 이미지를 업로드한다.
이미지가 저장된 URL을 리턴한다.
DB에 이미지가 저장된 URL을 저장한다.
처음에 이미지파일 업로드 아키텍쳐를 구성할때 이미지 자체를 DB에 저장하는것이 아닌가 많이들 오해하는데
물론 DB에 이미지파일 자체를 저장할 수도 있으나 대체로 DB에는 이미지 파일 주소만을 저장하고 실제 이미지 파일은 S3에 저장한다.
이미지파일 다운로드 로직
사용자가 EC2(인스턴스/서버)에 이미지 조회를 API로 요청한다.
서버는 DB로 조회 SQL문을 날린다.
DB는 서버에 저장되어 있던 이미지 URL을 응답한다.
서버는 사용자에게 이미지 URL을 응답한다.
사용자는 S3로부터 URL을 통해 이미지를 다운받는다.
Note2. S3 Practice
Note2.1 Bucket 생성
AWS S3 서비스로 들어가 Bucket을 생성해준다.
✨S3 Bucket & Object✨
Bucket - S3내부의 하나의 저장소 단위
Object - S3 Bucket에 업로드된 파일


Note2.2 정책 설정
✨정책(Policy)✨
AWS 내부에서 권한(Permission)을 정의하는 JSON 문서이다.
AWS에서는 버킷 설정 사진처럼 액세스 차단을 비활성화 하더라도 기본적으로 권한이 없는 상태가 default이며 특정한 리소스에 접근하고자 하면 권한을 별도로 설정해 주어야 한다.


리소스에 접근 가능하도록 하는 GetObject 권한을 추가해준다.

리소스 ARN의 {BucketName} 부분에 생성한 Bucket 이름을 ObjectName에는 *를 작성한다.
마지막으로 생성된 Json의 Principal은 접근 가능한 대상 목록을 작성해야 하는데, 사이트 이미지라면 모든 사람에게 노출되어야 하니 *를 적어준다.

Note2.3 파일 업로드 권한 설정
백엔드 서버가 S3에 접근해 파일을 업로드할 수 있는 권한을 설정해 주어야 한다.
IAM 서비스를 사용해 S3 파일 업로드 권한을 설정하자.




액세스키는 이후에 서버 환경설정 파일에 세팅해 주어야 하기에 따로 다운하거나 복사해두자

Note3. AWS S3 SpringBoot Setting
LightSale Instance 내부에 Mysql, SpringBoot 인스턴스를 Docker로 가상화하여 올려둔 상태이며
별도의 RDS같은 외부 데이터베이스 서비스는 사용하지 않는다.
pom.xml dependency 추가
<!-- AWS SDK S3 -->
<!-- AWS SDK for Java 2.x (Spring Boot 3.x 호환) -->
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3</artifactId>
<version>2.20.0</version>
</dependency>
.env
# AWS S3 설정
AWS_S3_BUCKET=
AWS_REGION=
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
Docker AWS S3 Setting
environment:
...
# AWS S3 설정
- AWS_S3_BUCKET=${AWS_S3_BUCKET}
- AWS_REGION=${AWS_REGION}
- AWS_ACCESS_KEY_ID=${AWS_ACCESS_KEY_ID}
- AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY}
...
application.yml
# AWS 설정
aws:
s3:
bucket: ${AWS_S3_BUCKET}
region: ${AWS_REGION}
access-key: ${AWS_ACCESS_KEY_ID}
secret-key: ${AWS_SECRET_ACCESS_KEY}
# 파일 저장 경로
profile-image-path: profiles/ # 프로필 이미지 저장
board-image-path: boards/ # 게시판 이미지
board-file-path: boards/files # 게시판 첨부파일
# 파일 크기 제한
max-file-size: 10485760 # 10mb
# 허용 이미지 타입
allowed-image-types: jpg,jpeg,png,gif,webp
# 허용된 파일 타입
allowed-file-types: pdf,doc,docx,xls,xlsx,zip
application.yml multipart setting
SpringBoot의 기본 파일 설정은 1MB이기에 Nginx와 최대 파일 업로드 제한 크기를 맞춰주는 것이 좋다.
Nginx.conf 환경설정 파일에서 파일 업로드 제한을 10Mb로 제한하였기에 똑같이 10Mb로 설정했다.
* 다만 multipart는 전역 설정만 가능하기에 파일 타입에 따라 용량 제한을 커스텀하고 싶다면 애플리케이션 코드 레벨에서 검증을 진행해야 한다. *
# 파일 업로드 설정 (Multipart)
servlet:
multipart:
max-file-size: 10MB # 파일당 최대 크기 (nginx의 client_max_body_size와 일치)
max-request-size: 10MB # 요청 전체 최대 크기
enabled: true