In this post, we’ll explore how to integrate MinIO with Spring Boot to perform bucket and object operations to any Amazon S3-compatible object storage service.
· Prerequisites
· Overview
∘ What is Minio?
∘ Key Benefits of Using Minio
· Setup Minio: MinIO Object Storage for Container
∘ Access MinIO
∘ Create a Bucket
· Spring Boot API
∘ Configure MinIO in Spring Boot
∘ Upload Object
∘ Download the file
∘ FileController
· Test the REST APIs
· Conclusion
· References
Prerequisites
This is the list of all the prerequisites:
- Spring Boot 3+
- Maven 3.6.3
- Java 21
- Docker / Docker-compose installed (optional if you’ve already downloaded and installed MinIO from https://min.io)
- Postman
Overview
What is Minio?
MinIO is a high-performance object storage released under dual licenses, GNU Affero General Public License v3.0 and MinIO Commercial License. It is API compatible with Amazon S3 cloud storage service. MinIO is built to deploy anywhere — public or private cloud, bare-metal infrastructure, orchestrated environments, and edge infrastructure.
Key Benefits of Using Minio
The benefits of Minio are listed below:
- S3 API Compatibility — Minio supports the Amazon S3 API, making it easy to integrate with existing S3-compatible applications.
- Data Redundancy — Using erasure coding, Minio ensures that data is replicated and distributed across multiple drives, protecting against data loss.
- High Availability — Minio can run in a distributed mode, ensuring continuous access even if some nodes or disks fail.
- Horizontal and Vertical Scaling — Minio scales out by adding more servers or scales up by increasing storage capacity on existing servers.
- Supports Multiple Pluggable Storage Backends — It works with local disks, Kubernetes PVC, NAS, and public cloud storage like Azure and GCP.
- Data Security — It offers encryption on both the server and client sides, ensuring secure data transfer and storage.
Setup Minio: MinIO Object Storage for Container
This story uses docker containers to run MinIO instances. Here is the full content of Docker-compose:
version: '3.8'
services:
minio:
image: minio/minio:latest
container_name: minio
ports:
- "9000:9000" # MinIO API port
- "9001:9001" # MinIO console port
environment:
MINIO_ROOT_USER: minioadmin # Default root user
MINIO_ROOT_PASSWORD: minioadmin # Default root password
volumes:
- minio_data:/data # Persistent storage for MinIO data
command: server /data --console-address ":9001"
volumes:
minio_data:
Let’s start the MinIO service by running the below command:
$ docker compose up -d

Access MinIO
Access the MinIO Console by going to a browser and going to http://localhost:9001
Log in with the default credentials:
- Username:
minioadmin - Password:
minioadmin

Create a Bucket
- Click on Buckets in the left sidebar.
- Click Create Bucket and provide a name (e.g.,
demo-bucket).

Spring Boot API
Let’s create a simple Spring Boot project from start.spring.io, with the following dependencies: Spring Web and Lombok.
Configure MinIO in Spring Boot
Add MinIO Dependency
To implement the integration with MinIO, we need to add MinIO Java SDK to the pom.xml
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.5.17</version>
</dependency>
MinIO Java SDK is a Simple Storage Service (aka S3) client that performs bucket and object operations for any Amazon S3-compatible object storage service.
Add MinIO Configuration Properties
- Create a configuration class to store MinIO properties (e.g., endpoint, access key, secret key).
- Add these properties to
application.yml:
minio:
endpoint: http://localhost:9000
access-key: minioadmin
secret-key: minioadmin
bucket: demo-bucket
bucket– bucket name.access-key– access key ID for a MinIOsecret-key– secret access keyendpoint:– URL to S3 service.
Configuration Class
Create a configuration class that sets up a MinioClient bean.
@RequiredArgsConstructor
@Configuration
public class MinioConfig {
private final MinioProperties minioProperties;
@Bean
public MinioClient minioClient() {
return MinioClient.builder()
.endpoint(minioProperties.getEndpoint())
.credentials(minioProperties.getAccessKey(), minioProperties.getSecretKey())
.build();
}
}
Upload Object
We are going to implement the object upload service in the MinIO bucket.
@Override
public void uploadFile(MultipartFile multipartFile) {
try {
var putObjectRequest = PutObjectArgs.builder()
.bucket(minioProperties.getBucket())
.object(multipartFile.getOriginalFilename())
.stream(multipartFile.getInputStream(), multipartFile.getSize(), -1)
.contentType(multipartFile.getContentType())
.build();
minioClient.putObject(putObjectRequest);
} catch (Exception ex ) {
log.error("error [{}] occurred while uploading file.", ex.getMessage());
throw new FileStorageException("Could not upload file");
}
}
putObject method is used to upload data from a stream to an object.
Download the file
The MinIO Java SDK provides the getObject() method to retrieve objects from the bucket. It returns aInputStream that must be closed after use to release network resources.
public InputStreamResource downloadFile(String fileName) {
try {
var inputStream = minioClient.getObject(GetObjectArgs.builder()
.bucket(minioProperties.getBucket())
.object(fileName)
.build());
return new InputStreamResource(inputStream);
} catch (Exception ex) {
log.error("error [{}] occurred while download [{}] ", ex.getMessage(), fileName);
throw new FileStorageException("Error: Could not download file");
}
}
FileController
Let’s see all the methods of our controller class.
@Slf4j
@RestController
@RequestMapping("/file")
@Validated
public class FileController {
private final MinioFileStorageService minioFileStorageService;
public FileController(MinioFileStorageService minioFileStorageService) {
this.minioFileStorageService = minioFileStorageService;
}
@PostMapping("/upload")
public ResponseEntity<BaseResponse> uploadFile(@RequestParam("file")
@FileRequired
@FileMaxSize
@ValidFileType MultipartFile file) {
minioFileStorageService.uploadFile(file);
return new ResponseEntity<>(new BaseResponse(new FileResponse(file.getOriginalFilename(), file.getContentType(), file.getSize()), "File uploaded with success!"), HttpStatus.CREATED);
}
@DeleteMapping
public ResponseEntity<BaseResponse> deleteFile(@RequestParam("fileName") String fileName) {
minioFileStorageService.deleteFile(fileName);
return new ResponseEntity<>(new BaseResponse(null, "file [" + fileName + "] removing request submitted successfully."), HttpStatus.OK);
}
@GetMapping("/download")
public ResponseEntity<InputStreamResource> downloadFile(@RequestParam("fileName") String fileName) {
InputStreamResource resource = minioFileStorageService.downloadFile(fileName);
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"")
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(resource);
}
}
Test the REST APIs
- Upload Object

- Retrieve objects by fileName
- Delete object
Conclusion
In this post, we’ve explored MinIO integration using Spring Boot as a Backend.
The complete source code is available on GitHub.
Support me through GitHub Sponsors.
Thank you for reading!! See you in the next post.


