MinIO Object Storage Integration with RuoYi Framework

Dependencies and Configuration

Add MinIO SDK dependency in pom.xml:

<dependency>
  <groupId>io.minio</groupId>
  <artifactId>minio</artifactId>
  <version>8.5.7</version>
</dependency>

Configure application.yml:

minio:
  endpoint: http://server-ip:9000
  access-id: minio-user
  secret-key: secure-pass
  container: ruoyi-files

Client Configuration

@Configuration
public class ObjectStorageConfig {
  @Value("${minio.access-id}")
  private String accessId;
  
  @Value("${minio.secret-key}")
  private String secretKey;
  
  @Value("${minio.endpoint}")
  private String endpoint;
  
  @Bean
  public MinioClient storageClient() {
    return MinioClient.builder()
        .credentials(accessId, secretKey)
        .endpoint(endpoint)
        .build();
  }
}

Storage Service Implementation

@Service
public class ObjectStorageService {
  @Autowired
  private MinioClient client;
  
  @Value("${minio.container}")
  private String containerName;
  
  public String saveObject(MultipartFile file) throws Exception {
    String objectName = generateFilename(file.getOriginalFilename());
    try (InputStream stream = file.getInputStream()) {
      createContainerIfMissing();
      client.putObject(PutObjectArgs.builder()
          .bucket(containerName)
          .object(objectName)
          .stream(stream, file.getSize(), -1)
          .contentType(file.getContentType())
          .build());
      return "/" + containerName + "/" + objectName;
    }
  }
  
  private void createContainerIfMissing() throws Exception {
    if (!client.bucketExists(BucketExistsArgs.builder().bucket(containerName).build())) {
      client.makeBucket(MakeBucketArgs.builder().bucket(containerName).build());
      client.setBucketPolicy(SetBucketPolicyArgs.builder()
          .bucket(containerName)
          .config(getContainerPolicy())
          .build());
    }
  }
  
  private String getContainerPolicy() {
    return String.format("{\"Version\":\"2012-10-17\",\"Statement\":["
        + "{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":"
        + "[\"s3:GetBucketLocation\",\"s3:ListBucket\"],\"Resource\":"
        + "[\"arn:aws:s3:::%s\"]}]}", containerName);
  }
}

API Controller

@RestController
@RequestMapping("/storage")
public class StorageController {
  @Autowired
  private ObjectStorageService storageService;
  
  @PostMapping("/upload")
  public ResponseEntity<Map<String, String>> upload(@RequestParam("file") MultipartFile file) {
    try {
      String path = storageService.saveObject(file);
      return ResponseEntity.ok(Map.of(
        "path", path,
        "originalName", file.getOriginalFilename()
      ));
    } catch (Exception ex) {
      return ResponseEntity.status(500).body(Map.of("error", ex.getMessage()));
    }
  }
}

MinIO Server Deployment

Run MinIO server using Docker:

docker run -d --name minio-server \
  -p 9000:9000 -p 9001:9001 \
  -e "MINIO_ROOT_USER=admin" \
  -e "MINIO_ROOT_PASSWORD=admin123" \
  -v /mnt/minio-data:/data \
  minio/minio server /data --console-address ":9001"

Container Configuration

  1. Acess console at http://server-ip:9001
  2. Create new container matching application.yml configuration
  3. Set containerr acces policy to public
  4. Create dedicated user with read-write permissions

Verification and Troubleshooting

  1. Test file upload via API client
  2. Verify object appears in MinIO console
  3. Check network connectivity between application server and MinIO
  4. Validate container permissions and user credentials
  5. Ensure firewall allows traffic on ports 9000/9001

Tags: MinIO RuoYi Spring Boot Object Storage java

Posted on Thu, 30 Jul 2026 16:21:36 +0000 by 11Tami