MinIO란?

AWS S3와 호환되는 고성능 오브젝트 스토리지 오픈소스 프로젝트이다. S3와 사용법이 유사하며, S3와 호환된다는 장점이 있다.

환경 구축

Docker

docker run --user root -d --name minio -e "MINIO_ROOT_USER={사용할 root ID}" -e "MINIO_ROOT_PASSWORD={사용할 root PASSWORD}" -p 4380:9000 -p 4381:9001  -v minio:/data [quay.io/minio/minio](http://quay.io/minio/minio) server /data --console-address ":9001"

MinioConfig.java

@Configuration
public class MinioConfig{
	@Value("${minio.url}")
	private String url;
	
	@Value("${minio.access.name}")
	private String accessKey;
	
	@Bean
	public MinioClient minioClient() {
		return MinioClient.builder()
			.endpoint(url)
			.credentials(accessKey, secretKey)
			.build();
	}
}

application.yml 파일에서 url, accessKey 값을 가져와 저장하고, 해당 값을 이용해서 MinioClient 객체를 이용하여 연결하는 Bean을 만든다.

Application.yml

minio:  
  url: ${MINIO_URL}  
  path: ${MINIO_PATH}  
  dir:  
    image: ${MINIO_IMAGE_DIR} # 버킷 내 이미지 저장할 폴더 명  
  bucket:  
    name: ${MINIO_BUCKET} # 버킷 이름  
  access:  
    name: ${MINIO_ACCESS_KEY}  
    secret: ${MINIO_SECRET_KEY}

Service.java

@Service
@RequiredArgsConstructor
public class ImageFileService {
    private final MinioClient minioClient;
 
    @Value("${minio.bucket.name}")
    private String BUCKET_NAME;
 
    @Value("${minio.dir.image}")
    private String IMAGE_DIR;
 
    @Value("${minio.path}")
    private String PATH;
 
    public String saveImageFile(MultipartFile multipartFile)
            throws IOException, ServerException, InsufficientDataException,
            ErrorResponseException, NoSuchAlgorithmException, InvalidKeyException,
            InvalidResponseException, XmlParserException, InternalException {
 
        boolean isExist = minioClient.bucketExists(
                BucketExistsArgs.builder()
                        .bucket(BUCKET_NAME)
                        .build());
 
        if (!isExist) {
            minioClient.makeBucket(MakeBucketArgs.builder()
                    .bucket(BUCKET_NAME)
                    .build());
        }
 
        String fileName = IMAGE_DIR + "/" + UUID.randomUUID() + "-" + multipartFile.getOriginalFilename();
 
        minioClient.putObject(PutObjectArgs.builder()
			.bucket(BUCKET_NAME)
			.object(fileName)
			.stream(multipartFile.getInputStream(), multipartFile.getSize(), -1)
			.contentType(multipartFile.getContentType())
			.build());
 
        return PATH + "/" + fileName;
    }
 
    public void deleteImage(String fileName)
		throws ServerException, InsufficientDataException, ErrorResponseException,
		IOException, NoSuchAlgorithmException, InvalidKeyException,
		InvalidResponseException, XmlParserException, InternalException {
 
	        if(isHaveImage(fileName)){
				minioClient.removeObject(
				RemoveObjectArgs.builder()
					.bucket(BUCKET_NAME)
					.object(fileName)
					.build());
		    }
    }
 
    public boolean isHaveImage(String fileName){
        try {
            minioClient.statObject(StatObjectArgs.builder().bucket(BUCKET_NAME).object(fileName).build());
            return true;
        } catch (Exception e) {
            return false;
        }
    }
 
}

위 MinioConfig.java에서 만든 minioClient 객체를 활용하여 필요에 따라 함수를 사용해 Minio를 사용할 수 있습니다.