MinIO

High-performance object storage server. Amazon S3-compatible API, cloud-native design, Kubernetes support. Solution for private cloud environments.

File ServerObject StorageS3 CompatibleSelf-HostedHigh PerformanceAI Ready

Server

MinIO

Overview

MinIO is a high-performance open-source object storage that provides a fully S3-compatible API. Released under the GNU AGPLv3 license, it is optimized for cloud-native workloads, particularly AI and machine learning applications. With production throughput exceeding 2.2 TiB/s and over 6 million deployment instances, MinIO is recognized as the world's fastest object storage. It can be deployed anywhere from single-node to petabyte-scale distributed environments across public clouds, private clouds, bare metal, edge infrastructure, and Kubernetes environments.

Details

MinIO 2025 edition, with RELEASE.2025-06-13T11-33-47Z as the latest stable version, has significantly enhanced its "AIStor" capabilities specialized for AI and machine learning workloads. Enterprise features include comprehensive functionality such as IAM (Identity and Access Management), ILM (Information Lifecycle Management), replication, versioning, observability, encryption, key management, firewall, event/Lambda integration, and management console as standard offerings. The latest deployment topologies support three patterns: SNSD (Single-Node Single-Drive), SNMD (Single-Node Multi-Drive), and MNMD (Multi-Node Multi-Drive), enabling flexible configurations based on use cases. Starting from the May 2025 version, the console UI has been specialized for object browser functionality, with administrative operations integrated into the mc command-line tool.

Key Features

  • Full S3 Compatibility: 100% compatibility with AWS S3 API and enterprise-level reliability
  • World's Highest Performance: Throughput exceeding 2.2 TiB/s and industry-standard benchmarks
  • AI/ML Specialized: Optimized for cloud-native AI workloads
  • Multi-Environment Support: Full support for Kubernetes, Docker, bare metal, and cloud
  • High Availability: Fault tolerance for up to 50% node/drive failures
  • Comprehensive Security: Object-level encryption and extended S3 security features

Pros and Cons

Pros

  • Utilize existing tools and libraries directly through S3 compatibility
  • Avoid vendor lock-in with open-source freedom and flexible operations
  • World-class performance optimized for AI and machine learning workloads
  • Scalable deployment from single nodes to distributed clusters based on requirements
  • Reduced operational costs through comprehensive enterprise features
  • Excellent operability in container environments with Kubernetes-native design

Cons

  • Distributed cluster management requires specialized knowledge like Erlang Cookies
  • Proper hardware design and network configuration are crucial for high performance
  • Complex understanding of replication settings and distributed consensus algorithms
  • Infrastructure costs due to minimum 4-node requirements for serious distributed configurations
  • High learning curve to fully utilize enterprise features
  • Application modifications required when migrating from traditional file servers

Reference Pages

Code Examples

Basic Docker Setup

# Create data directory
mkdir -p ~/minio/data

# Start MinIO container (standalone configuration)
docker run -d \
  --name minio-server \
  -p 9000:9000 \
  -p 9001:9001 \
  -v ~/minio/data:/data \
  -e "MINIO_ROOT_USER=minioadmin" \
  -e "MINIO_ROOT_PASSWORD=minioadmin123" \
  quay.io/minio/minio server /data --console-address ":9001"

# Check container status
docker ps | grep minio
docker logs minio-server

# Browser access
# Object API: http://localhost:9000
# Console UI: http://localhost:9001

# Docker Compose configuration example
cat > docker-compose.yml << 'EOF'
version: '3.8'
services:
  minio:
    image: quay.io/minio/minio:latest
    container_name: minio
    environment:
      MINIO_ROOT_USER: minioadmin
      MINIO_ROOT_PASSWORD: minioadmin123
    ports:
      - "9000:9000"
      - "9001:9001"
    volumes:
      - minio_data:/data
    command: server /data --console-address ":9001"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
      interval: 30s
      timeout: 20s
      retries: 3

volumes:
  minio_data:
EOF

docker-compose up -d

Native Installation on Linux Environment

# Download MinIO latest version (Linux AMD64)
wget https://dl.min.io/server/minio/release/linux-amd64/minio
chmod +x minio
sudo mv minio /usr/local/bin/

# Create service user
sudo useradd -r -s /sbin/nologin minio-user

# Create data directory
sudo mkdir -p /mnt/minio/data
sudo chown minio-user:minio-user /mnt/minio/data

# Create configuration directory
sudo mkdir -p /etc/minio
sudo chown minio-user:minio-user /etc/minio

# Create environment configuration file
sudo tee /etc/default/minio << 'EOF'
# Volume to be used for MinIO server.
MINIO_VOLUMES="/mnt/minio/data"
# Use if you want to run MinIO on a custom port.
MINIO_OPTS="--console-address :9001"
# Root credentials
MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=minioadmin123
EOF

# Create systemd service configuration
sudo tee /etc/systemd/system/minio.service << 'EOF'
[Unit]
Description=MinIO
Documentation=https://docs.min.io
Wants=network-online.target
After=network-online.target
AssertFileIsExecutable=/usr/local/bin/minio

[Service]
WorkingDirectory=/usr/local/

User=minio-user
Group=minio-user
ProtectProc=invisible

EnvironmentFile=/etc/default/minio
ExecStartPre=/bin/bash -c "if [ -z \"${MINIO_VOLUMES}\" ]; then echo \"Variable MINIO_VOLUMES not set in /etc/default/minio\"; exit 1; fi"
ExecStart=/usr/local/bin/minio server $MINIO_OPTS $MINIO_VOLUMES

# Let systemd restart this service always
Restart=always

# Specifies the maximum file descriptor number that can be opened by this process
LimitNOFILE=65536

# Specifies the maximum number of threads this process can create
TasksMax=infinity

# Disable timeout logic and wait until process is stopped
TimeoutStopSec=infinity
SendSIGKILL=no

[Install]
WantedBy=multi-user.target
EOF

# Enable and start service
sudo systemctl daemon-reload
sudo systemctl enable minio
sudo systemctl start minio
sudo systemctl status minio

MinIO Client (mc) Setup and Basic Operations

# Install MinIO Client (mc)
wget https://dl.min.io/client/mc/release/linux-amd64/mc
chmod +x mc
sudo mv mc /usr/local/bin/

# Configure MinIO server
mc alias set myminio http://localhost:9000 minioadmin minioadmin123

# Verify alias configuration
mc alias list

# Bucket operations
mc mb myminio/test-bucket                    # Create bucket
mc ls myminio                                # List buckets
mc rb myminio/test-bucket                    # Remove empty bucket
mc rb myminio/test-bucket --force            # Force removal (including contents)

# Object operations
echo "Hello MinIO" > test.txt
mc cp test.txt myminio/test-bucket/          # Upload file
mc ls myminio/test-bucket                    # List objects
mc cp myminio/test-bucket/test.txt ./downloaded.txt  # Download
mc rm myminio/test-bucket/test.txt           # Remove object

# Sync operations
mc mirror ./local-folder myminio/test-bucket/remote-folder/  # Upload sync
mc mirror myminio/test-bucket/remote-folder/ ./sync-folder/  # Download sync

# Bucket policy configuration
mc anonymous set download myminio/test-bucket  # Allow public read
mc anonymous set none myminio/test-bucket      # Disable public access

# Enable versioning
mc version enable myminio/test-bucket
mc version info myminio/test-bucket

# Bucket notification configuration
mc event add myminio/test-bucket arn:minio:sqs::1:webhook --event put,delete
mc event list myminio/test-bucket

Programming Examples with Python SDK

from minio import Minio
from minio.error import S3Error
import io
import json
from datetime import datetime, timedelta

# Initialize MinIO client
client = Minio(
    "localhost:9000",
    access_key="minioadmin",
    secret_key="minioadmin123",
    secure=False  # True for HTTPS
)

def basic_operations():
    """Basic bucket and object operations"""
    bucket_name = "python-test-bucket"
    object_name = "test-object.txt"
    
    try:
        # Check bucket existence and create
        if not client.bucket_exists(bucket_name):
            client.make_bucket(bucket_name)
            print(f"Created bucket '{bucket_name}'")
        
        # Upload object (from string)
        data = "Hello from MinIO Python SDK!"
        client.put_object(
            bucket_name,
            object_name,
            io.BytesIO(data.encode('utf-8')),
            len(data.encode('utf-8')),
            content_type="text/plain"
        )
        print(f"Uploaded object '{object_name}'")
        
        # Download object
        response = client.get_object(bucket_name, object_name)
        content = response.read().decode('utf-8')
        print(f"Downloaded content: {content}")
        response.close()
        response.release_conn()
        
        # List objects
        objects = client.list_objects(bucket_name)
        print("Object list:")
        for obj in objects:
            print(f"  - {obj.object_name} (Size: {obj.size}, Modified: {obj.last_modified})")
        
    except S3Error as e:
        print(f"Error: {e}")

def advanced_operations():
    """Advanced operations (metadata, presigned URLs, etc.)"""
    bucket_name = "advanced-test-bucket"
    
    try:
        # Create bucket
        if not client.bucket_exists(bucket_name):
            client.make_bucket(bucket_name)
        
        # Upload object with metadata
        data = json.dumps({"message": "Hello", "timestamp": datetime.now().isoformat()})
        metadata = {
            "x-amz-meta-author": "Python-SDK",
            "x-amz-meta-version": "1.0",
            "x-amz-meta-category": "test"
        }
        
        client.put_object(
            bucket_name,
            "metadata-object.json",
            io.BytesIO(data.encode('utf-8')),
            len(data.encode('utf-8')),
            content_type="application/json",
            metadata=metadata
        )
        
        # Get object info (including metadata)
        stat = client.stat_object(bucket_name, "metadata-object.json")
        print(f"Object information:")
        print(f"  Size: {stat.size}")
        print(f"  Modified: {stat.last_modified}")
        print(f"  ETag: {stat.etag}")
        print(f"  Metadata: {stat.metadata}")
        
        # Generate presigned URL (download)
        download_url = client.presigned_get_object(
            bucket_name, 
            "metadata-object.json",
            expires=timedelta(hours=1)
        )
        print(f"Download presigned URL: {download_url}")
        
        # Generate presigned URL (upload)
        upload_url = client.presigned_put_object(
            bucket_name,
            "upload-via-url.txt",
            expires=timedelta(hours=1)
        )
        print(f"Upload presigned URL: {upload_url}")
        
        # File upload
        with open("test.txt", "w") as f:
            f.write("Test file for MinIO")
        
        client.fput_object(
            bucket_name,
            "uploaded-file.txt",
            "test.txt",
            content_type="text/plain"
        )
        print("File upload complete")
        
        # File download
        client.fget_object(
            bucket_name,
            "uploaded-file.txt",
            "downloaded-file.txt"
        )
        print("File download complete")
        
    except S3Error as e:
        print(f"Error: {e}")

def lifecycle_management():
    """Lifecycle management and versioning"""
    bucket_name = "lifecycle-test-bucket"
    
    try:
        if not client.bucket_exists(bucket_name):
            client.make_bucket(bucket_name)
        
        # Enable versioning (requires mc command)
        print("Please enable versioning with mc command:")
        print(f"mc version enable myminio/{bucket_name}")
        
        # Create multiple versions of object
        for version in range(1, 4):
            data = f"Version {version} of the document"
            client.put_object(
                bucket_name,
                "versioned-document.txt",
                io.BytesIO(data.encode('utf-8')),
                len(data.encode('utf-8')),
                content_type="text/plain"
            )
            print(f"Uploaded version {version}")
        
        # List object versions (mc command example)
        print("\nCheck object versions:")
        print(f"mc ls --versions myminio/{bucket_name}/versioned-document.txt")
        
    except S3Error as e:
        print(f"Error: {e}")

# Usage examples
if __name__ == "__main__":
    print("=== MinIO Python SDK Basic Operations ===")
    basic_operations()
    
    print("\n=== MinIO Python SDK Advanced Operations ===")
    advanced_operations()
    
    print("\n=== MinIO Python SDK Lifecycle Management ===")
    lifecycle_management()

Distributed Cluster Configuration (4-Node Example)

# 4-node distributed MinIO cluster setup
# Execute the following configuration on each node

# Node 1 (192.168.1.10)
export MINIO_ROOT_USER=minioadmin
export MINIO_ROOT_PASSWORD=minioadmin123
minio server \
  http://192.168.1.10/mnt/disk{1...4} \
  http://192.168.1.11/mnt/disk{1...4} \
  http://192.168.1.12/mnt/disk{1...4} \
  http://192.168.1.13/mnt/disk{1...4} \
  --console-address ":9001"

# Execute the same command on Node 2-4

# Check cluster status
mc admin info myminio
mc admin cluster info myminio

# Add nodes (expand existing cluster)
# When adding new node sets
export MINIO_ROOT_USER=minioadmin
export MINIO_ROOT_PASSWORD=minioadmin123
minio server \
  http://192.168.1.{10...13}/mnt/disk{1...4} \
  http://192.168.1.{14...17}/mnt/disk{1...4} \
  --console-address ":9001"

# Health check
mc admin heal myminio
mc admin health myminio

High Availability Configuration in Kubernetes Environment

# minio-operator.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: minio-system
---
# Install MinIO Operator
# kubectl apply -k "github.com/minio/operator"

# MinIO Tenant configuration example
apiVersion: minio.min.io/v2
kind: Tenant
metadata:
  name: minio-cluster
  namespace: minio-system
spec:
  image: quay.io/minio/minio:latest
  credsSecret:
    name: minio-creds-secret
  pools:
  - servers: 4
    name: pool-0
    volumesPerServer: 4
    volumeClaimTemplate:
      metadata:
        name: data
      spec:
        accessModes:
        - ReadWriteOnce
        resources:
          requests:
            storage: 1Ti
        storageClassName: fast-ssd
  requestAutoCert: false
  console:
    image: quay.io/minio/console:latest
    replicas: 2
    consoleSecret:
      name: minio-console-secret
---
apiVersion: v1
kind: Secret
metadata:
  name: minio-creds-secret
  namespace: minio-system
type: Opaque
data:
  accesskey: bWluaW9hZG1pbg==  # minioadmin (base64)
  secretkey: bWluaW9hZG1pbjEyMw==  # minioadmin123 (base64)
---
apiVersion: v1
kind: Secret
metadata:
  name: minio-console-secret
  namespace: minio-system
type: Opaque
data:
  CONSOLE_PBKDF_PASSPHRASE: c2VjcmV0  # secret (base64)
  CONSOLE_PBKDF_SALT: c2FsdA==  # salt (base64)
  CONSOLE_ACCESS_KEY: bWluaW9hZG1pbg==  # minioadmin (base64)
  CONSOLE_SECRET_KEY: bWluaW9hZG1pbjEyMw==  # minioadmin123 (base64)

Monitoring, Operations Management, and Performance Optimization

# System information and statistics
mc admin info myminio
mc admin prometheus info myminio
mc admin prometheus generate myminio

# Storage usage check
mc admin storage-info myminio
mc du myminio --recursive

# User and policy management
mc admin user add myminio newuser newpassword
mc admin user list myminio

# Create custom policy
cat > readwrite-policy.json << 'EOF'
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::test-bucket/*",
        "arn:aws:s3:::test-bucket"
      ]
    }
  ]
}
EOF

mc admin policy create myminio readwrite-policy readwrite-policy.json
mc admin policy attach myminio readwrite-policy --user newuser

# Service account management
mc admin user svcacct add myminio newuser
mc admin user svcacct list myminio newuser

# Configuration backup and restore
mc admin config export myminio > minio-config-backup.json
mc admin config import myminio < minio-config-backup.json

# Performance testing
mc admin speedtest myminio --duration 60s --size 1GiB

# Prometheus metrics configuration
mc admin prometheus info myminio
mc admin prometheus generate myminio

# Log level configuration
mc admin config set myminio logger_webhook:1 endpoint="http://elasticsearch:9200/logs/_doc"
mc admin service restart myminio

# Encryption configuration (KMS)
mc admin kms key create myminio my-key
mc admin kms key list myminio