Running the Service Container
Acquire a specific MinIO release image from Docker Hub:
docker pull minio/minio:RELEASE.2025-04-22T22-12-26Z
Launch a container with the API and web console ports mapped. Adjust the host bind-mount paths as appropriate for your environment:
docker run -d \
--name minio \
-p 9000:9000 \
-p 9001:9001 \
-v /opt/minio/data:/data \
-v /opt/minio/config:/root/.minio \
-e "MINIO_ROOT_USER=admin" \
-e "MINIO_ROOT_PASSWORD=admin123456" \
minio/minio:RELEASE.2025-04-22T22-12-26Z \
server /data --console-address ":9001"
The flags control the folowing:
-pexposes the S3-compatible API on port 9000 and the browser-based managemetn UI on port 9001.-vpersist service data and configuration on the host filesystem.- The environment pair
MINIO_ROOT_USER/MINIO_ROOT_PASSWORDdefines the initial administrator credentials. - The final command argument
server /datapoints the server to the data volume, while--console-addressbinds the web dashboard.
Navigate to http://localhost:9001 and log in with the administrator credentials to confirm the service is operational.
Bucket and Object Organization
In MinIO the top-level container is a bucket. There is no true directory hierarchy; instead, forward slashes within object keys produce a virtual folder layout visible in the console and SDKs. Consider a bucket named datasets containing these keys:
datasets/mydataset1/train/image1.jpg
datasets/mydataset1/train/image2.jpg
datasets/mydataset2/data.csv
datasets/mydataset2/labels.txt
When listed through the UI, these appear as a nested tree structure such as:
datasets/
├── mydataset1/
│ └── train/
│ ├── image1.jpg
│ └── image2.jpg
└── mydataset2/
├── data.csv
└── labels.txt
Workflow for uploading content:
- Create the bucket
datasets. - Define a key prefix like
mydataset1. - Upload a file using the console or an SDK.
Configuring Public Access
To make objects directly accessible without a signed URL, change the bucket's access policy. In the console, edit the bucket policy from Private to Public. Once applied, objects are reachable using the pattern http://{host}:9000/{bucket}/{key}.
Example public URL:
http://localhost:9000/datasets/mydataset1/example.png
Programmatic Upload with the Java SDK
Before writing client code, generate an access key pair from the MinIO console (Access Keys section). Add the following dependency to your project:
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.5.10</version>
</dependency>
A upload routine written in Java can use a file input stream. The example below initializes the client, describes the target location, and uploads a local image into the public bucket:
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import java.io.FileInputStream;
import java.io.InputStream;
public class FileUploader {
public static void main(String[] args) {
String endpoint = "http://localhost:9000";
String accessKey = "yHxFBiulXKsuhbg9nHqO";
String secretKey = "qmsQU4JuWuwlr3ZgY4eMFbQ9LaTzzEHMV6T722kC";
String bucket = "datasets";
String remoteKey = "mydataset1/images/uploaded.webp";
String localFilePath = "/home/user/Pictures/uploaded.webp";
MinioClient client = MinioClient.builder()
.endpoint(endpoint)
.credentials(accessKey, secretKey)
.build();
try (InputStream input = new FileInputStream(localFilePath)) {
PutObjectArgs uploadArgs = PutObjectArgs.builder()
.bucket(bucket)
.object(remoteKey)
.stream(input, input.available(), -1)
.contentType("image/webp")
.build();
client.putObject(uploadArgs);
String directUrl = String.format("%s/%s/%s", endpoint, bucket, remoteKey);
System.out.println("Upload completed. Direct link: " + directUrl);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Executing the program places the file into the bucket and prints the publicly accessible URL.