MinIO S3-Compatible Object Storage Installation
MinIO is a high-performance, S3-compatible object storage platform that delivers enterprise-grade features for modern data workloads. Built from the ground up as a container-native application, MinIO runs on any infrastructure—from single servers to distributed clusters—making it the ideal choice for organizations requiring flexible, scalable object storage without vendor lock-in. This guide covers installation, configuration, and operation of MinIO in both single-node and distributed architectures.
Table of Contents
- Prerequisites and Planning
- Single Node Installation
- Distributed Cluster Setup
- MinIO Client Configuration
- Bucket Management
- Access Control and Policies
- Versioning and Lifecycle Management
- Monitoring and Maintenance
- Conclusion
Prerequisites and Planning
Before deploying MinIO, ensure your infrastructure meets these requirements:
- Linux kernel 4.4 or later
- At least 4 vCPU cores for production deployments
- Minimum 8 GB RAM, 16 GB recommended
- Direct attached storage (NVMe or SAS SSDs for optimal performance)
- Network connectivity between nodes (minimum 1 Gbps, 10 Gbps recommended)
- Firewall configured to allow MinIO API and console ports
For distributed deployments, plan your erasure coding scheme. MinIO's standard configuration uses 4 data drives and 2 parity drives (EC:4 scheme), requiring a minimum of 6 drives per node across multiple nodes.
# Check kernel version
uname -r
# Verify available CPU cores
nproc
# Check available memory
free -h
# List available block devices
lsblk
Single Node Installation
Installation from Binary
Download the latest MinIO binary directly from the official repository:
# Download MinIO binary
curl -o minio https://dl.min.io/server/minio/release/linux-amd64/minio
# Make it executable
chmod +x minio
# Move to system path
sudo mv minio /usr/local/bin/
# Verify installation
minio --version
Creating Storage Directory
MinIO requires a dedicated directory for data storage. This directory should be on a high-performance storage device:
# Create MinIO data directory
sudo mkdir -p /mnt/minio/data
# Create MinIO user and group
sudo useradd -r minio-user || true
sudo usermod -a -G disk minio-user
# Set appropriate permissions
sudo chown -R minio-user:minio-user /mnt/minio
sudo chmod -R 700 /mnt/minio
Configuring as Systemd Service
Create a systemd service unit for automatic startup and management:
# Create configuration directory
sudo mkdir -p /etc/minio
sudo mkdir -p /etc/default
# Create environment file
sudo tee /etc/default/minio > /dev/null <<EOF
MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=StrongPassword123!
MINIO_VOLUMES="/mnt/minio/data"
MINIO_SERVER_URL="https://minio.example.com"
MINIO_BROWSER_REDIRECT_URL="https://console.example.com"
MINIO_OPTS="--address :9000 --console-address :9001"
EOF
# Set appropriate permissions
sudo chmod 600 /etc/default/minio
Create the systemd service file:
sudo tee /etc/systemd/system/minio.service > /dev/null <<EOF
[Unit]
Description=MinIO
Documentation=https://docs.min.io
Wants=network-online.target
After=network-online.target
AssertFileNotEmpty=/etc/default/minio
[Service]
Type=notify
User=minio-user
Group=minio-user
ProtectProcfs=yes
NoNewPrivileges=yes
PrivateDevices=yes
SecureBits=keep-caps
SecureFlags=keep-caps
StandardOutput=journal
StandardError=journal
SyslogIdentifier=minio
TimeoutStartSec=infinity
TimeoutStopSec=infinity
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}
ExecStop=/bin/kill -SIGTERM $MAINPID
Restart=on-failure
RestartSec=5s
[Install]
WantedBy=multi-user.target
EOF
# Reload systemd and enable service
sudo systemctl daemon-reload
sudo systemctl enable minio
sudo systemctl start minio
# Verify service status
sudo systemctl status minio
Distributed Cluster Setup
Architecture Planning
For a distributed deployment across 4 nodes with 6 drives each, use this topology:
Node 1: /mnt/disk1 /mnt/disk2 /mnt/disk3 /mnt/disk4 /mnt/disk5 /mnt/disk6
Node 2: /mnt/disk1 /mnt/disk2 /mnt/disk3 /mnt/disk4 /mnt/disk5 /mnt/disk6
Node 3: /mnt/disk1 /mnt/disk2 /mnt/disk3 /mnt/disk4 /mnt/disk5 /mnt/disk6
Node 4: /mnt/disk1 /mnt/disk2 /mnt/disk3 /mnt/disk4 /mnt/disk5 /mnt/disk6
Configuring Each Node
On each node, prepare the storage infrastructure:
# Install MinIO on all nodes
curl -o /tmp/minio https://dl.min.io/server/minio/release/linux-amd64/minio
chmod +x /tmp/minio
sudo mv /tmp/minio /usr/local/bin/
# Format and mount drives (repeat for each drive)
sudo mkfs.ext4 /dev/nvme0n1p1
sudo mkdir -p /mnt/disk1
sudo mount /dev/nvme0n1p1 /mnt/disk1
# Create fstab entries for persistence
echo '/dev/nvme0n1p1 /mnt/disk1 ext4 defaults,nofail 0 2' | sudo tee -a /etc/fstab
# Create MinIO user
sudo useradd -r minio-user || true
Configure the distributed deployment environment file:
sudo tee /etc/default/minio > /dev/null <<EOF
MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=ComplexPassword123!@
MINIO_VOLUMES="http://node1:9000/mnt/disk{1...6} http://node2:9000/mnt/disk{1...6} http://node3:9000/mnt/disk{1...6} http://node4:9000/mnt/disk{1...6}"
MINIO_SERVER_URL="https://minio.example.com"
MINIO_BROWSER_REDIRECT_URL="https://console.example.com"
MINIO_OPTS="--address :9000 --console-address :9001"
EOF
sudo chmod 600 /etc/default/minio
Use the same systemd service file as single-node and start the service on all nodes simultaneously:
# Start on all nodes (use Ansible or similar for bulk operations)
sudo systemctl restart minio
sudo systemctl status minio
Verifying Cluster Health
Monitor cluster formation:
# Check logs
sudo journalctl -u minio -f
# Access MinIO console at https://your-domain:9001
# Login with MINIO_ROOT_USER and MINIO_ROOT_PASSWORD
# Verify cluster is operational
curl -k https://localhost:9000/minio/health/live
MinIO Client Configuration
Installing mc (MinIO Client)
The MinIO Client tool enables command-line interaction with MinIO clusters:
# Download and install mc
curl -o /tmp/mc https://dl.min.io/client/mc/release/linux-amd64/mc
chmod +x /tmp/mc
sudo mv /tmp/mc /usr/local/bin/
# Verify installation
mc --version
Adding MinIO Alias
Configure alias to connect to your MinIO cluster:
# Add MinIO alias
mc alias set minio-prod https://minio.example.com:9000 minioadmin YourPassword123! --api S3v4
# List available aliases
mc alias list
# Test connectivity
mc ls minio-prod/
Advanced mc Operations
# Mirror local directory to bucket
mc mirror /data/upload minio-prod/my-bucket/uploads
# Sync data (only copies changed files)
mc cp --attr "Cache-Control=max-age=90000" /data/ minio-prod/my-bucket/
# Monitor bandwidth usage
mc du minio-prod/my-bucket
# List objects with size and date
mc ls --recursive minio-prod/my-bucket
# Remove objects matching pattern
mc rm --recursive --force minio-prod/my-bucket/temp/
Bucket Management
Creating and Managing Buckets
# Create bucket
mc mb minio-prod/my-bucket
# Create bucket with specific region
mc mb --region us-east-1 minio-prod/regional-bucket
# List all buckets
mc ls minio-prod
# Remove empty bucket
mc rb minio-prod/my-bucket
# Remove bucket with contents
mc rb --force minio-prod/my-bucket
Bucket Configuration
Configure bucket-level settings through the MinIO console or API:
# Upload file to bucket
mc cp /path/to/file.txt minio-prod/my-bucket/
# Set bucket quota
mc quota set --hard 1TB minio-prod/my-bucket
# View bucket quota
mc quota info minio-prod/my-bucket
# Configure CORS policy
mc cors set minio-prod/my-bucket "Origin|Methods|Headers"
Access Control and Policies
Creating IAM Users and Credentials
Implement least-privilege access through dedicated IAM users:
# Create IAM user for application
# Using MinIO console at https://your-domain:9001
# Navigate to: Identity > Users > Create User
# Or use mc admin user commands
mc admin user add minio-prod appuser appuserpassword
# List users
mc admin user list minio-prod
# Change user password
mc admin user change minio-prod appuser newpassword
# Delete user
mc admin user remove minio-prod appuser
Policy Management
Create policies to control bucket access:
# Create policy file
cat > /tmp/read-only-policy.json <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
]
}
]
}
EOF
# Add policy to MinIO
mc admin policy create minio-prod readonly /tmp/read-only-policy.json
# Attach policy to user
mc admin policy attach minio-prod readonly --user appuser
# List policies
mc admin policy list minio-prod
# Detach policy
mc admin policy detach minio-prod readonly --user appuser
Versioning and Lifecycle Management
Enabling Versioning
Protect against accidental deletions with object versioning:
# Enable versioning on bucket (via console or API)
# Using mc:
mc version enable minio-prod/my-bucket
# Check versioning status
mc version info minio-prod/my-bucket
# Upload multiple versions
echo "Version 1" > /tmp/file.txt
mc cp /tmp/file.txt minio-prod/my-bucket/document.txt
echo "Version 2" > /tmp/file.txt
mc cp /tmp/file.txt minio-prod/my-bucket/document.txt
# List all versions
mc ls --versions minio-prod/my-bucket/
Lifecycle Policies
Configure automatic data retention and archival:
# Create lifecycle configuration file
cat > /tmp/lifecycle.json <<EOF
{
"Rules": [
{
"ID": "archive-old-uploads",
"Status": "Enabled",
"Filter": {
"Prefix": "uploads/"
},
"Expiration": {
"Days": 90
},
"NoncurrentVersionTransition": {
"NoncurrentDays": 30
}
},
{
"ID": "delete-temp",
"Status": "Enabled",
"Filter": {
"Prefix": "temp/"
},
"Expiration": {
"Days": 1
}
}
]
}
EOF
# Apply lifecycle policy
mc ilm import minio-prod/my-bucket < /tmp/lifecycle.json
# View lifecycle policy
mc ilm export minio-prod/my-bucket
Monitoring and Maintenance
Health Checks and Diagnostics
# Check cluster health
curl -s https://minio.example.com:9000/minio/health/live
# Get detailed metrics
curl -s https://minio.example.com:9000/minio/v2/metrics/cluster
# Monitor real-time operations
mc watch minio-prod/my-bucket
# Check disk usage
mc du --recursive minio-prod/my-bucket
# Generate diagnostics bundle
mc support diag minio-prod > diagnostics.zip
Backup and Recovery
# Backup bucket data
mc mirror minio-prod/my-bucket /backup/my-bucket/
# Backup bucket configuration
mc ilm export minio-prod/my-bucket > /backup/lifecycle.json
mc policy export minio-prod/my-bucket > /backup/policy.json
# Restore from backup
mc mirror /backup/my-bucket/ minio-prod/my-bucket-restore/
# List all objects with their versions
mc ls --versions --recursive minio-prod/my-bucket > /backup/object-manifest.txt
Performance Tuning
# Monitor bandwidth per node
mc admin trace minio-prod
# Enable debug logging
mc admin config set minio-prod logger_http minio logs
# Set connection pool sizes in environment
MINIO_API_LISTENING_PORT=9000
MINIO_BROWSER_LISTENING_PORT=9001
MINIO_OPTS="--address :9000 --console-address :9001 --https-key /etc/ssl/private/key.pem --https-cert /etc/ssl/certs/cert.pem"
Conclusion
MinIO provides a production-grade S3-compatible object storage solution that scales from single-node deployments to large distributed clusters. By following this guide's configuration patterns and best practices, you can establish a reliable, secure object storage platform supporting diverse workload requirements. Regular monitoring, appropriate access controls, and lifecycle policies ensure your MinIO deployment maintains data integrity while optimizing storage efficiency. Whether deploying for container registries, data lakes, or backup targets, MinIO's flexibility and performance make it an excellent choice for modern infrastructure environments.


