RustFS 실습 - 1 ( Docker / Entity 정의 )

TopOfTheHead·2026년 7월 25일

RustFS
。Rust 언어로 개발된 S3 API와 호환되는 오픈소스 Object Storage
▶ S3과 호환성이 좋으므로, AWS SDK를 사용하는 어플리케이션과 거의 동일한 방식으로 연동이 가능.

。S3과 같은 Object Storage를 사용자 Host에서 직접 구축해서 활용하는 방식
▶ 객체 사용비용을 감소 가능

。9000 포트를 사용하며, 전용 Web Console을 제공.

。Rust로 개발되었으므로, 성능 및 메모리 안정성 추구

。어플리케이션 서버는 파일 메타데이터는 RDBMS에, 파일은 RustFS에 저장하는 방식으로 구성.

  • Rust FS를 사용하는 이유?
    。AWS SDK를 그대로 사용하면서 AWS S3와 같은 객체 저장소를 직접 온프레미스 환경에서 구축하므로, AWS 비용을 절감하면서, 데이터를 직접 관리 가능.

Docker Compose 파일 / .env 파일 정의

services:
  rustfs:
    image: rustfs/rustfs:1.0.0-alpha.72
    container_name: springboot-sns-rustfs
    env_file:
      - .env
    ports:
      - "9000:9000"
      - "9001:9001"
    volumes:
      - rustfs-data:/data
      - rustfs-logs:/logs
    healthcheck:
      test: ["CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:9000/health"]
      interval: 10s
      timeout: 3s
      retries: 3
volumes:
  rustfs-data:
    driver: local
  rustfs-logs:
    driver: local

。10 초 마다 9000 포트로 헬스체크 용 트래픽을 전송하여 백그라운드 체크를 수행하도록 헬스체크를 설정
▶ 타임아웃 : 3초로 트래픽 처리 실패 시 재시도를 최대 3번 수행하도록 설정

RUSTFS_ADDRESS=0.0.0.0:9000
RUSTFS_CONSOLE_ADDRESS=0.0.0.0:9001
RUSTFS_CONSOLE_ENABLE=true
RUSTFS_ACCESS_KEY=rustfsadmin
RUSTFS_SECRET_KEY=1234567
  • RUSTFS_ADDRESS :
    。RustFS의 URL을 설정
    ▶ 로컬호스트:9000 포트 지정

  • RUSTFS_CONSOLE_ADDRESS :
    。RustFS 전용 웹콘솔의 URL을 설정
    ▶ 로컬호스트:9001 포트로 지정

  • RUSTFS_ACCESS_KEY / RUSTFS_SECRET_KEY
    。웹콘솔 진입 시 자격증명을 설정

9001 포트로 진입하여 RUSTFS 웹콘솔 진입

。Account / Key에 .env파일에서 정의한 ACCESS_KEY / SECRET_KEY를 입력

  • PostgreSQL : docker compose / .env 정의
    。테이블을 저장할 RDBMS를 정의
services:
  postgres:
    image: postgres:18.1-alpine3.22
    container_name: springboot-sns-postgres
    env_file:
      - .env
    ports:
      - "5432:5432"
    volumes:
      - postgres-data:/var/lib/postgresql/data
    healthcheck:
      test: [ "CMD-SHELL", "pg_isready -U snsuser -d snsdb" ]
      interval: 10s
      timeout: 3s
      retries: 3
volumes:
  postgres-data:
    driver: local

。10 초 마다 9000 포트로 헬스체크 용 트래픽을 전송하여 백그라운드 체크를 수행하도록 헬스체크를 설정
▶ 타임아웃 : 3초로 트래픽 처리 실패 시 재시도를 최대 3번 수행하도록 설정

# MYSQL
POSTGRES_DB=snsdb
POSTGRES_USER=snsuser
POSTGRES_PASSWORD=snspassword
  • 의존성 설정 수행

Entity 정의

  • Enum : MediaType 정의
    。파일 업로드 시 해당 파일 확장자에 해당하는 확장자를 반환하는 Enum
    ▶ 현재는 jpg와 video만 받을 수 있음.

    。IMAGE의 파일이 업로드 요청 시 fileExtension()에 의해 .jpg 문자열 반환
public enum MediaType {
    IMAGE,
    VIDEO;
    public String fileExtension(){
        return switch (this){
            case IMAGE -> ".jpg";
            case VIDEO -> ".mp4";
        };
    }
    public String contentType(){
        return switch (this){
            case IMAGE -> "image/jpeg";
            case VIDEO -> "video/mp4";
        };
    }
}
  • Enum : MediaStatus 정의
    。해당 파일 상태를 지시
public enum MediaStatus {
    INIT, UPLOADED, COMPLETED, FAILED
}
  • Entity 정의
@Entity
@Table(name = "media")
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Media extends BaseEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    //
    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    private MediaType mediaType; // 저장할 수 있는 미디어파일 타입
    //
    @Column(nullable = false, length = 2000)
    private String path; // RustFS 상 미디어파일 저장 경로
    //
    @Enumerated(EnumType.STRING)
    @Column(nullable = false)
    private MediaStatus status; // 미디어파일 상태
    //
    @Column
    private Long userId; // 업로드 한 유저ID
    //
    @Column(length = 500)
    private String uploadId; // 멀티파트 업로드
    //
    @Column
    private Long fileSize; // 업로드 파일 크기
    //
    @JdbcTypeCode(SqlTypes.JSON)
    @Column(columnDefinition = "jsonb")
    private Map<String, Object> attributes; // JSON
    // 단일 업로드 시 생성하는 Media 객체
    public Media(
            MediaType mediaType,
            String path,
            Long userId,
            Long fileSize
    ){
        this.mediaType = mediaType;
        this.path = path;
        this.status = MediaStatus.INIT;
        this.userId = userId;
        this.fileSize = fileSize;
    }
    // 멀티파트 업로드 시 생성하는 Media 객체
    public Media(
            MediaType mediaType,
            String path,
            Long userId,
            Long fileSize,
            String uploadId
    ){
        this.mediaType = mediaType;
        this.path = path;
        this.status = MediaStatus.INIT;
        this.userId = userId;
        this.fileSize = fileSize;
        this.uploadId = uploadId;
    }
    public void updateStatus(MediaStatus status) {
        this.status = status;
    }
    public void updateAttributes(Map<String, Object> attributes) {
        this.attributes = attributes;
    }
}

MediaType
。ENUM으로서 일반적으로 이미지 / 동영상으로 구분.

Path :
。Object Storage( = RustFS, S3, ... )에서 파일이 저장되는 경로

Status :
。업로드 미디어 파일의 상태
▶ ENUM으로서 INIT / UPLOADED / COMPLETED / FAILED의 4가지 상태를 소유

uploadId :
。멀티파트 업로드를 위한 Object Storage 상 업로드 ID
▶ 동영상 등 대용량 파일을 여러번 걸쳐서 나눠 업로드 시 사용

attribute
。업로드될 미디어 파일의 메타데이터로서 JSON Format으로 저장
▶ 파일번호, 해상도 또는 재생시간 등을 저장

profile
공부기록 블로그

0개의 댓글