
AWS S3와 호환되는 고성능 오브젝트 스토리지 오픈소스
S3와 사용법이 유사하고 S3와 호환가능하다.
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"
서버 주소:4381로 접속






//minio
implementation 'io.minio:minio:8.5.9'
package org.sixback.omess.common.config;
import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MinioConfig {
@Value("${minio.url}")
private String url;
@Value("${minio.access.name}")
private String accessKey;
@Value("${minio.access.secret}")
private String secretKey;
@Bean
public MinioClient minioClient() {
return MinioClient.builder()
.endpoint(url)
.credentials(accessKey, secretKey)
.build();
}
}
minio:
url: ${MINIO_URL} //minio 주소
path: ${MINIO_PATH}
dir:
image: ${MINIO_IMAGE_DIR} // 버킷 내 이미지 저장할 폴더 명
bucket:
name: ${MINIO_BUCKET} // 버킷 이름
access:
name: ${MINIO_ACCESS_KEY} //3에서 발급한 access key
secret: ${MINIO_SECRET_KEY} //3에서 발급한 secretKey key
package org.sixback.omess.domain.image.controller;
import io.minio.errors.*;
import lombok.RequiredArgsConstructor;
import org.sixback.omess.domain.image.service.ImageFileService;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
@RestController
@RequestMapping("/api/v1/images")
@RequiredArgsConstructor
public class ImageController {
private final ImageFileService imageFileService;
@PostMapping
public ResponseEntity<String> uploadImage(@RequestBody MultipartFile file) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
return ResponseEntity.ok().body(imageFileService.saveImageFile(file));
}
@DeleteMapping
public ResponseEntity<Void> deleteImage(@RequestBody String fileName) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
imageFileService.deleteImage(fileName);
return ResponseEntity.ok().build();
}
}
package org.sixback.omess.domain.image.service;
import io.minio.*;
import io.minio.errors.*;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;
@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;
}
}
}



