How to Deploy RustFS with Docker and Integrate It into a SpringBoot Application
This guide walks you through installing the RustFS distributed object storage via Docker, using its visual console, and configuring a SpringBoot project to upload and delete files through the RustFS S3‑compatible API, complete with code snippets and practical screenshots.
Overview
RustFS is a high‑performance distributed object storage system written in Rust, compatible with the AWS S3 API and released under the Apache 2.0 license.
Docker Deployment
Run RustFS quickly with Docker.
Pull the official image: docker pull rustfs/rustfs Start the container, setting access credentials and mounting a host directory for data:
docker run -p 9000:9000 --name rustfs \
-e RUSTFS_ACCESS_KEY=rustfsadmin \
-e RUSTFS_SECRET_KEY=rustfsadmin \
-v /mydata/rustfs/data:/data \
-v /etc/localtime:/etc/localtime \
-d rustfs/rustfsOpen the management console at http://<em>host</em>:9000 using the default credentials rustfsadmin:rustfsadmin.
Spring Boot Integration
Example shows how to upload and delete files on RustFS from a Spring Boot application.
Dependencies
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3</artifactId>
<version>${aws-s3-sdk.version}</version>
</dependency>Configuration
rustfs:
endpoint: http://192.168.3.101:9000
bucketName: simple
accessKey: rustfsadmin
secretKey: rustfsadmin @Configuration
public class RustFSConfig {
@Value("${rustfs.endpoint}") private String ENDPOINT;
@Value("${rustfs.accessKey}") private String ACCESS_KEY;
@Value("${rustfs.secretKey}") private String SECRET_KEY;
@Bean
public S3Client s3Client() {
return S3Client.builder()
.endpointOverride(URI.create(ENDPOINT))
.region(Region.US_EAST_1) // region is ignored by RustFS
.credentialsProvider(StaticCredentialsProvider.create(
AwsBasicCredentials.create(ACCESS_KEY, SECRET_KEY)))
.forcePathStyle(true) // required for RustFS
.build();
}
}Controller
@RestController
@RequestMapping("/rustfs")
public class RustFSController {
@Autowired private S3Client s3Client;
@Value("${rustfs.bucketName}") private String BUCKET_NAME;
@Value("${rustfs.endpoint}") private String ENDPOINT;
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public CommonResult upload(@RequestPart("file") MultipartFile file) {
if (!bucketExists(BUCKET_NAME)) {
s3Client.createBucket(CreateBucketRequest.builder().bucket(BUCKET_NAME).build());
String policy = JSONUtil.toJsonStr(createBucketPolicyConfigDto(BUCKET_NAME));
s3Client.putBucketPolicy(PutBucketPolicyRequest.builder()
.bucket(BUCKET_NAME).policy(policy).build());
}
try {
s3Client.putObject(PutObjectRequest.builder()
.bucket(BUCKET_NAME)
.key(file.getOriginalFilename())
.contentType(file.getContentType())
.build(),
RequestBody.fromInputStream(file.getInputStream(), file.getSize()));
RustFSUploadResult result = new RustFSUploadResult();
result.setName(file.getOriginalFilename());
result.setUrl(ENDPOINT + "/" + BUCKET_NAME + "/" + file.getOriginalFilename());
return CommonResult.success(result);
} catch (IOException e) {
e.printStackTrace();
return CommonResult.failed();
}
}
@PostMapping("/delete")
public CommonResult delete(@RequestParam("objectName") String objectName) {
s3Client.deleteObject(DeleteObjectRequest.builder()
.bucket(BUCKET_NAME).key(objectName).build());
return CommonResult.success(null);
}
private boolean bucketExists(String bucketName) {
try {
s3Client.headBucket(r -> r.bucket(bucketName));
return true;
} catch (NoSuchBucketException e) {
return false;
}
}
private BucketPolicyConfigDto createBucketPolicyConfigDto(String bucketName) {
BucketPolicyConfigDto.Statement stmt = BucketPolicyConfigDto.Statement.builder()
.Effect("Allow")
.Principal(BucketPolicyConfigDto.Principal.builder()
.AWS(new String[]{"*"}).build())
.Action(new String[]{"s3:GetObject"})
.Resource(new String[]{"arn:aws:s3:::" + bucketName + "/*"})
.build();
return BucketPolicyConfigDto.builder()
.Version("2012-10-17")
.Statement(CollUtil.toList(stmt))
.build();
}
}Bucket Policy Example
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"AWS": ["*"]},
"Action": ["s3:GetObject"],
"Resource": ["arn:aws:s3:::simple/*"]
}]
}Testing
Swagger UI (e.g., http://localhost:8088/swagger-ui.html ) can be used to invoke the /upload and /delete endpoints.
References
RustFS repository: https://github.com/rustfs/rustfs Spring Boot example source:
https://github.com/macrozheng/spring-examples/tree/master/spring-rustfsmacrozheng
Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
