Skip to main content
โšก Calmops

MinIO Basics: Getting Started with S3-Compatible Object Storage

Introduction

Object storage has become the foundation for modern data infrastructure. Unlike traditional file systems that organize data in hierarchies, object storage treats data as objects with unique identifiers, metadata, and the data itself. This approach enables massive scalability, cost-effectiveness, and simplicity for storing unstructured data like photos, videos, backups, and analytics datasets.

MinIO is a high-performance, S3-compatible object storage system that can be deployed anywhere - from a single laptop to multi-petabyte distributed clusters. Its API compatibility with Amazon S3 means you can use familiar tools and libraries while running storage on-premises or in any environment you choose.

This article explores MinIO fundamentals: core concepts, bucket management, object operations, the S3 API, and practical examples to get you started with object storage.

Understanding Object Storage

Object storage organizes data differently than traditional file systems:

Core Concepts

  • Objects: The fundamental unit of storage. Each object includes:

    • Data: The actual content (file, image, video)
    • Metadata: Descriptive information about the data
    • Key: Unique identifier within a bucket
  • Buckets: Containers that hold objects. Similar to top-level folders but with flat structure.

  • Keys: Unique identifiers for objects within a bucket (e.g., photos/vacation/2024/image.jpg)

Object Storage vs File Systems

Aspect Object Storage File System
Structure Flat namespace Hierarchical
Scale Unlimited Limited
Access HTTP REST API POSIX
Metadata Rich, custom Limited
Consistency Eventual Strong

Installing MinIO

Standalone Installation

For development and testing:

# Download MinIO binary
wget https://dl.min.io/server/minio/release/linux-amd64/minio

# Make executable
chmod +x minio

# Start MinIO server
./minio server /data

# Or with custom settings
./minio server /data \
  --address ":9000" \
  --console-address ":9001"

Docker Installation

# Start MinIO container
docker run -p 9000:9000 -p 9001:9001 \
  -e MINIO_ROOT_USER=minioadmin \
  -e MINIO_ROOT_PASSWORD=minioadmin \
  -v minio-data:/data \
  --name minio \
  minio/minio server /data --console-address ":9001"

# Access:
# API: http://localhost:9000
# Console: http://localhost:9001

Configuration

# Environment file (minio.env)
MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=minioadmin
MINIO_REGION_NAME=us-east-1

# Start with environment file
source minio.env && minio server /data

Using the MinIO Client (mc)

The MinIO Client provides a familiar ls, cp, mv interface:

# Install mc
wget https://dl.min.io/client/mc/release/linux-amd64/mc
chmod +x mc

# Add MinIO host
mc alias set myminio http://localhost:9000 minioadmin minioadmin

# List buckets
mc ls myminio/

# Create bucket
mc mb myminio/mybucket

# List objects
mc ls myminio/mybucket/

Working with Buckets

Buckets are the top-level containers in MinIO:

# Create bucket
mc mb myminio/mybucket

# Create with region
mc mb myminio/mybucket --region us-west-2

# Delete bucket (must be empty)
mc rb myminio/mybucket

# List buckets with info
mc ls myminio/ --verbose

# Set bucket policy
mc anonymous set download myminio/mybucket

# Enable versioning
mc version enable myminio/mybucket

Working with Objects

Upload Objects

# Upload file
mc cp myfile.txt myminio/mybucket/

# Upload with custom key
mc cp myfile.txt myminio/mybucket/backup/myfile.txt

# Upload directory
mc cp -r myfolder/ myminio/mybucket/

# Upload with encryption
mc encrypt set AES256 myminio/mybucket
mc cp secret.txt myminio/mybucket/

Download Objects

# Download object
mc cp myminio/mybucket/myfile.txt ./

# Download to specific name
mc cp myminio/mybucket/data.csv ./output.csv

# Download entire bucket
mc cp --recursive myminio/mybucket/ ./downloads/

Manage Objects

# List objects
mc ls myminio/mybucket/

# View object info
mc stat myminio/mybucket/myfile.txt

# Move/rename
mc mv myminio/mybucket/old.txt myminio/mybucket/new.txt

# Copy
mc cp myminio/mybucket/source.txt myminio/mybucket/dest.txt

# Delete
mc rm myminio/mybucket/myfile.txt

# Delete with prefix
mc rm --recursive myminio/mybucket/temp/

S3 API Operations

MinIO is fully S3-compatible. Use AWS SDKs or any S3-compatible client:

Python with boto3

import boto3
from botocore.config import Config

# Connect to MinIO
s3 = boto3.resource(
    's3',
    endpoint_url='http://localhost:9000',
    aws_access_key_id='minioadmin',
    aws_secret_access_key='minioadmin',
    config=Config(signature_version='s3v4')
)

# Create bucket
s3.create_bucket(Bucket='mybucket')

# Upload file
s3.Bucket('mybucket').upload_file('local.txt', 'remote.txt')

# Download file
s3.Bucket('mybucket').download_file('remote.txt', 'local.txt')

# List objects
for obj in s3.Bucket('mybucket').objects.all():
    print(obj.key, obj.size)

Using AWS CLI with MinIO

# Configure AWS CLI for MinIO
aws configure
# Enter MinIO credentials and region

# Or use environment variables
export AWS_ACCESS_KEY_ID=minioadmin
export AWS_SECRET_ACCESS_KEY=minioadmin

# List buckets
aws --endpoint-url=http://localhost:9000 s3 ls

# Upload
aws --endpoint-url=http://localhost:9000 s3 cp myfile.txt s3://mybucket/

REST API Direct Access

# List buckets
curl -X GET http://localhost:9000/ \
  -H "Authorization: AWS minioadmin:minioadmin"

# Upload object (multipart)
curl -X PUT http://localhost:9000/mybucket/myfile.txt \
  -H "Authorization: AWS minioadmin:minioadmin" \
  -H "Content-Type: text/plain" \
  --data-binary "Hello MinIO"

# Download object
curl -X GET http://localhost:9000/mybucket/myfile.txt \
  -H "Authorization: AWS minioadmin:minioadmin"

Bucket Policies

Control access to buckets and objects:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": "*",
      "Action": ["s3:GetObject"],
      "Resource": ["arn:aws:s3:::mybucket/*"]
    }
  ]
}

Apply the policy:

mc policy set download myminio/mybucket
mc policy set public myminio/mybucket

Versioning and Retention

Enable Versioning

# Enable versioning
mc version enable myminio/mybucket

# Check versioning status
mc version info myminio/mybucket

Object Locking

# Enable object locking (requires versioning)
mc mb myminio/locked-bucket
mc version enable myminio/locked-bucket

# Set default retention
mc retention set --mode GOVERNANCE --days 30 myminio/locked-bucket

Lifecycle Rules

Automate object transitions and expiration:

# Add lifecycle rule - transition to different tier after 30 days
mc ilm add myminio/mybucket \
  --transition-days 30 \
  --storage-class STANDARD-IA \
  --transition-days 90 \
  --storage-class GLACIER

# Add expiration rule
mc ilm add myminio/mybucket --expiry-days 365

# List lifecycle rules
mc ilm list myminio/mybucket

Metrics and Monitoring

# Server info
mc admin info myminio

# Performance metrics
mc admin prometheus metrics myminio

# View audit logs
mc admin audit info myminio

Conclusion

MinIO provides a powerful, S3-compatible object storage solution that works anywhere. Its simple deployment model, combined with full S3 API compatibility, makes it ideal for modern cloud-native applications. Key takeaways: understand the bucket/object model, use mc for CLI operations, leverage S3 SDKs for applications, and implement proper access controls with bucket policies.

In the next article, we’ll explore MinIO operations - production deployment, configuration, scaling, and monitoring.

Resources

Comments