Table of Contents
What is MinIO?
MinIO is an object storage system released under the GNU Affero General Public License v3.0. It is API-compatible with the Amazon S3 cloud storage service, capable of handling unstructured data like photos, videos, log files, backups, and container images, with a maximum supported object size of 50TB.
Key Components:
- MinIO Server: The main object storage application
- MinIO Client (mc): Command-line tool for management
- MinIO SDKs: Application integration libraries
Understanding Your Deployment Options
Standalone MinIO
- Use Case: Development, testing, single-server deployments
- Pros: Simple setup, minimal overhead
- Cons: No fault tolerance, limited features
- Best For: Non-production environments
Distributed MinIO (Recommended for Production)
Use Case: High availability, data protection, production systems
Distributed mode provides high availability and data protection through erasure coding, distributing data across multiple drives and nodes. MinIO's simplicity, performance, and complete S3 compatibility make it an excellent choice for self-hosted object storage in Kubernetes environments. MinIO distributed mode requires at least 4 drives to enable erasure coding.
Benefits: Automatic healing, drive failure tolerance
Pre-Deployment Planning
Hardware Requirements
For high-storage dedicated servers, follow these guidelines:
- CPU & RAM: Modern multi-core processor (16+ cores recommended). Minimum 16GB RAM; 32GB+ recommended for high concurrency.
- Storage: MinIO recommends using flash-based storage (NVMe or SSD) for all workload types and scales. Workloads that require high performance should prefer NVMe over SSD. MinIO does not recommend HDD storage for production environments.
- Minimum: 4 drives per server for erasure coding
- Recommended: 8-12 NVMe/SSD drives
- Topology: Same capacity drives across all nodes
- File System: XFS format for best performance
- Network: Minimum 1Gbps network connection. Configure the switch connecting MinIO servers for maximum throughput: Jumbo Frames: Configure MTU 9100+ on all switch ports connected to MinIO servers and clients.
System Requirements
- Operating System: Linux (Ubuntu 24.04 LTS recommended)
- Kernel Version: Linux 6.8 or later
User Account: Create a dedicated MinIO system user:
sudo useradd -r -s /bin/false minio-user
Disk Preparation
Check available drives:
lsblk
df -h
Mount additional storage (if needed):
# Format new drive (example: /dev/sdb)
sudo mkfs.xfs /dev/sdb1
# Create mount point
sudo mkdir -p /mnt/minio-data
# Mount the drive
sudo mount /dev/sdb1 /mnt/minio-data
# Add to /etc/fstab for persistent mounting
echo "/dev/sdb1 /mnt/minio-data xfs defaults 0 0" | sudo tee -a /etc/fstab
Step-by-Step Installation
Step 1: Download MinIO Server
For Ubuntu/Debian (AMD64):
cd /tmp
curl --progress-bar -L https://dl.min.io/server/minio/release/linux-amd64/minio -o minio
For Ubuntu/Debian (ARM64):
cd /tmp
curl --progress-bar -L https://dl.min.io/server/minio/release/linux-arm64/minio -o minio
Alternatively, use the package manager:
# For .deb installations
curl --progress-bar -L https://dl.min.io/server/minio/release/linux-amd64/minio.deb -o minio.deb
sudo dpkg -i minio.deb
Step 2: Install MinIO Binary
If using the binary:
chmod +x minio
sudo mv minio /usr/local/bin/
Verify installation:
minio --version
Step 3: Create Data Directory
# Create directory with proper permissions
sudo mkdir -p /mnt/minio-data
sudo chown minio-user:minio-user /mnt/minio-data
sudo chmod 755 /mnt/minio-data
For distributed mode with multiple drives:
sudo mkdir -p /mnt/disk1 /mnt/disk2 /mnt/disk3 /mnt/disk4
sudo chown -R minio-user:minio-user /mnt/disk*
Step 4: Create MinIO Configuration File
Create /etc/default/minio:
sudo tee /etc/default/minio > /dev/null <<EOF
# MinIO user and group
MINIO_USER=minio-user
MINIO_GROUP=minio-user
# MinIO configuration directory
MINIO_CONFIG_DIR=/home/minio-user/.minio
# MinIO data directory (single server)
MINIO_VOLUMES="/mnt/minio-data"
# Root credentials
MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=YourStrongPasswordHere123!@#
# Server configuration
MINIO_OPTS="--address :9000 --console-address :9001"
# Enable browser
MINIO_BROWSER="on"
EOF
- Replace YourStrongPasswordHere123!@# with your own strong credentials.
- Write down your password before starting the service.
- You'll need these credentials to login to the Web UI at step 7.
- Example strong password format: MinIO@Secure#2024-Production
For distributed mode, specify multiple drives:
MINIO_VOLUMES="/mnt/disk1 /mnt/disk2 /mnt/disk3 /mnt/disk4"
Step 5: Create Systemd Service File
Create /etc/systemd/system/minio.service:
sudo tee /etc/systemd/system/minio.service > /dev/null <<EOF
[Unit]
Description=MinIO Object Storage Server
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
ProtectIdentity=yes
PrivateDevices=yes
PrivateTmp=yes
ProtectHostname=yes
ProtectClock=yes
ProtectKernelTunables=yes
LimitNOFILE=65536
LimitNPROC=65536
TimeoutStartSec=3min
Restart=on-failure
RestartSec=5s
EnvironmentFile=-/etc/default/minio
ExecStartPre=/bin/bash -c 'if [ -z "\${MINIO_VOLUMES}" ]; then echo "MINIO_VOLUMES not set in /etc/default/minio"; exit 1; fi'
ExecStart=/usr/local/bin/minio server \$MINIO_OPTS \$MINIO_VOLUMES
StandardOutput=journal
StandardError=journal
SyslogIdentifier=minio
[Install]
WantedBy=multi-user.target
EOF
Step 6: Enable and Start the Service
# Reload systemd daemon
sudo systemctl daemon-reload
# Enable MinIO to start on boot
sudo systemctl enable minio
# Start the service
sudo systemctl start minio
# Check status
sudo systemctl status minio
# View logs
sudo journalctl -u minio -f
Step 7: Verify Installation
# Check if MinIO is running
curl http://localhost:9000/minio/health/live
# Access the web UI via browser
# http://your-server-ip:9001
Configuration for High Storage
1. Performance Tuning
Set File Descriptor Limits:
# Add to /etc/security/limits.conf
echo "minio-user soft nofile 65536" | sudo tee -a /etc/security/limits.conf
echo "minio-user hard nofile 65536" | sudo tee -a /etc/security/limits.conf
Optimize Network:
# Enable jumbo frames for better throughput
sudo ip link set dev eth0 mtu 9000
Kernel Optimization:
# Add to /etc/sysctl.conf
echo "net.core.rmem_max=268435456" | sudo tee -a /etc/sysctl.conf
echo "net.core.wmem_max=268435456" | sudo tee -a /etc/sysctl.conf
echo "net.ipv4.tcp_rmem=4096 87380 268435456" | sudo tee -a /etc/sysctl.conf
echo "net.ipv4.tcp_wmem=4096 65536 268435456" | sudo tee -a /etc/sysctl.conf
# Apply changes
sudo sysctl -p
2. Storage Monitoring
First, ensure you've configured the MinIO Client alias (see Bucket Management section):
# Check disk usage
df -h /mnt/minio-data
# Monitor I/O performance
iostat -x 1
# Check MinIO statistics (after setting up alias)
mc admin info minio-local
3. Distributed Deployment Example
For a 4-node cluster with 8 drives each:
# Node 1 Config:
MINIO_VOLUMES="/mnt/disk1 /mnt/disk2 /mnt/disk3 /mnt/disk4 /mnt/disk5 /mnt/disk6 /mnt/disk7 /mnt/disk8"
# Command (same on all nodes):
minio server \
http://node1.example.com:9000/mnt/disk{1..8} \
http://node2.example.com:9000/mnt/disk{1..8} \
http://node3.example.com:9000/mnt/disk{1..8} \
http://node4.example.com:9000/mnt/disk{1..8}
SSL/TLS Configuration (Optional)
Step 1: Generate Certificates
Using Let's Encrypt with Certbot:
sudo apt-get install certbot python3-certbot-dns-* -y
sudo certbot certonly --standalone -d minio.example.com -d console.example.com
Step 2: Place Certificates in MinIO Directory
sudo mkdir -p /home/minio-user/.minio/certs
# Copy certificates
sudo cp /etc/letsencrypt/live/minio.example.com/fullchain.pem /home/minio-user/.minio/certs/public.crt
sudo cp /etc/letsencrypt/live/minio.example.com/privkey.pem /home/minio-user/.minio/certs/private.key
# Set proper permissions
sudo chown -R minio-user:minio-user /home/minio-user/.minio/certs
sudo chmod 600 /home/minio-user/.minio/certs/private.key
Step 3: Update Service Configuration
Modify /etc/default/minio:
MINIO_OPTS="--address :9000 --console-address :9001 --certs-dir /home/minio-user/.minio/certs"
Step 4: Restart MinIO
sudo systemctl restart minio
Access Control & Security
1. Change Default Credentials
If you need to change your credentials later, simply update /etc/default/minio with your new secure credentials:
MINIO_ROOT_USER="your-new-secure-username"
MINIO_ROOT_PASSWORD="your-new-secure-password"
(After modifying the file, restart the service: sudo systemctl restart minio)
2. Configure Firewall
# UFW (Ubuntu)
sudo ufw allow 9000/tcp # API port
sudo ufw allow 9001/tcp # Console port
3. Enable Access Logging
Add to /etc/default/minio:
MINIO_LOG_QUERY_STRING=on
Bucket Management
Using MinIO Console (Web UI)
- With SSL/TLS: https://your-server-ip:9001
- Without SSL/TLS: http://your-server-ip:9001
Using MinIO Client (mc)
Install MinIO Client:
curl --progress-bar -L https://dl.min.io/client/mc/release/linux-amd64/mc -o mc
chmod +x mc
sudo mv mc /usr/local/bin/
Configure alias:
Run this as sudo so that the alias is configured for the root user, which is required for our automated cron backups in the next section.
# If you completed SSL/TLS Configuration:
sudo mc alias set minio-local https://your-server-ip:9000 minioadmin your-password
# If you skipped SSL/TLS (development only):
sudo mc alias set minio-local http://your-server-ip:9000 minioadmin your-password
(Replace minioadmin and your-password with the credentials you set in Step 4).
Create bucket & Upload files:
sudo mc mb minio-local/my-bucket
sudo mc cp /local/path/file.txt minio-local/my-bucket/
sudo mc ls minio-local
Monitoring & Maintenance
1. Monitor MinIO Health
sudo mc admin health info minio-local
2. Regular Backups
# Create a dedicated backup directory
sudo mkdir -p /backup/
# Automated daily backup (correct method using explicit paths & escaped date)
sudo tee /etc/cron.daily/minio-backup > /dev/null <<EOF
#!/bin/bash
# Use explicit absolute paths and specify the config directory
# The date variable is escaped (\$) to prevent premature evaluation during file creation
/usr/local/bin/mc --config-dir /root/.mc mirror minio-local /backup/minio-\$(date +\%Y\%m\%d)
EOF
# Make the cron job executable
sudo chmod +x /etc/cron.daily/minio-backup
Why this matters:
- /mnt/minio-data contains raw data blocks, XL metadata, and erasure coding parity.
- Direct copying/mirroring of the raw directory will result in unrecoverable backups.
- Using mc mirror ensures backups are pulled correctly through the API.
3. Log Monitoring
sudo journalctl -u minio -f
sudo journalctl -u minio | grep ERROR
4. Update MinIO
Check for available updates (Modern MinIO uses mc to update the server):
# Using MinIO Client (recommended method)
sudo mc admin update minio-local
(Note: The minio update command is deprecated in modern MinIO releases. Always use mc admin update).
Troubleshooting
Common Issues
1. Permission Denied Errors
sudo chown -R minio-user:minio-user /mnt/minio-data
sudo chmod 755 /mnt/minio-data
2. "Address already in use" Error
sudo lsof -i :9000
sudo kill -9 <PID>
3. Connection Refused
sudo systemctl status minio
sudo netstat -tuln | grep -E '9000|9001'
4. SSL Certificate Issues
# Verify certificate validity
openssl x509 -in /home/minio-user/.minio/certs/public.crt -text -noout
Best Practices Summary
- Security: Change default credentials, use strong access keys, enable TLS/SSL.
- Performance: Use NVMe/SSD drives, configure jumbo frames (MTU 9000).
- Reliability: Deploy in distributed mode for production, never backup raw directories directly.
- Maintenance: Schedule regular updates via mc admin update, monitor disk space.
Verification Checklist
Before moving this deployment to production, verify:
- No raw directory backup commands (/mnt/minio-data) are used in scripts.
- Manual password was set explicitly (not auto-generated/lost in shell).
- Daily backup cron job uses escaped bash variables \$(date) and absolute paths.
- Using mc admin update for server updates.
- All mc commands reference the consistent minio-local alias.
- HTTP/HTTPS URLs match your SSL completion status.
Conclusion
MinIO provides a powerful, S3-compatible object storage solution that you can deploy on dedicated servers. By following this guide and referencing the official documentation, you'll have a reliable, high-performance storage infrastructure ready for production workloads.
Need High-Performance Storage Hardware?
Self-hosting MinIO allows you to build massive scalable data lakes without the extreme egress fees of public clouds. However, object storage is only as good as the drives and network backbone it runs on.
Explore Fit Servers for high-capacity, cost-effective dedicated storage servers tailored for data-heavy workloads. Whether you need a single large-capacity node or a multi-server cluster with lightning-fast NVMe arrays, Fit Servers gives you the raw disk I/O and dedicated bandwidth required to keep your S3 storage fast, secure, and always online.
Configure your storage server today