MinIO Distributed Storage
MinIO distributed object storage cluster.
Overview
MinIO is a high-performance, S3-compatible object storage server originally developed to provide cloud-native storage for modern applications. Born from the need for a lightweight yet powerful alternative to Amazon S3, MinIO delivers enterprise-grade object storage with exceptional performance, supporting throughput speeds of multiple GB/s while maintaining full compatibility with the S3 API. This makes it an ideal choice for organizations seeking to reduce cloud storage costs or maintain complete control over their data infrastructure.
This distributed MinIO cluster configuration deploys four MinIO server instances behind an Nginx load balancer, creating a fault-tolerant object storage system with automatic erasure coding. The four-node setup provides optimal data protection through MinIO's distributed erasure coding algorithm, which can tolerate up to two node failures while maintaining data availability. Nginx acts as the frontend proxy, distributing API requests across all healthy MinIO nodes and providing a single endpoint for both S3 API calls and web console access.
This stack is perfect for organizations running data-intensive applications, AI/ML workloads, or those requiring a self-hosted S3 replacement with high availability guarantees. The distributed architecture ensures that your object storage remains operational even during node maintenance or unexpected failures, while the S3 compatibility allows existing applications to work without modification. Development teams benefit from having a production-like S3 environment for testing, while enterprises gain the ability to store petabytes of data without vendor lock-in or egress fees.
Key Features
- 100% Amazon S3 API compatibility for drop-in replacement of S3 services
- Distributed erasure coding across four nodes with tolerance for up to two node failures
- High-performance object storage delivering multi-GB/s throughput for large file operations
- Built-in web console for bucket management, user administration, and monitoring
- Automatic data protection with configurable retention policies and object versioning
- Enterprise-grade encryption at rest and in transit using AES-256 and TLS
- Load-balanced access through Nginx proxy for optimal request distribution
- Active health checking and automatic failover for uninterrupted service availability
Common Use Cases
- 1Self-hosted S3 replacement for organizations wanting to eliminate cloud storage costs and data egress fees
- 2AI/ML data lakes requiring high-throughput storage for training datasets and model artifacts
- 3Media and content delivery platforms needing scalable storage for videos, images, and static assets
- 4Backup and archival systems for enterprises with long-term data retention requirements
- 5Development and testing environments requiring S3-compatible storage without cloud dependencies
- 6Edge computing deployments where data sovereignty and local storage control are critical
- 7Kubernetes-native applications requiring persistent object storage with S3 API compatibility
Prerequisites
- Minimum 8GB RAM (2GB per MinIO node) with 16GB+ recommended for production workloads
- Available ports 9000 and 9001 on the host system for S3 API and web console access
- Nginx configuration file (nginx.conf) created in the same directory as docker-compose.yml
- At least 100GB of available disk space per node for meaningful object storage capacity
- Understanding of S3 API concepts including buckets, objects, and access key management
- Basic knowledge of load balancers and distributed storage concepts for troubleshooting
For development & testing. Review security settings, change default credentials, and test thoroughly before production use. See Terms
docker-compose.yml
docker-compose.yml
1services: 2 minio1: 3 image: minio/minio:latest4 container_name: minio15 restart: unless-stopped6 command: server --console-address ":9001" http://minio{1...4}/data7 environment: 8 MINIO_ROOT_USER: ${MINIO_USER:-minioadmin}9 MINIO_ROOT_PASSWORD: ${MINIO_PASSWORD:-minioadmin}10 volumes: 11 - minio1_data:/data12 networks: 13 - minio-network1415 minio2: 16 image: minio/minio:latest17 container_name: minio218 restart: unless-stopped19 command: server --console-address ":9001" http://minio{1...4}/data20 environment: 21 MINIO_ROOT_USER: ${MINIO_USER:-minioadmin}22 MINIO_ROOT_PASSWORD: ${MINIO_PASSWORD:-minioadmin}23 volumes: 24 - minio2_data:/data25 networks: 26 - minio-network2728 minio3: 29 image: minio/minio:latest30 container_name: minio331 restart: unless-stopped32 command: server --console-address ":9001" http://minio{1...4}/data33 environment: 34 MINIO_ROOT_USER: ${MINIO_USER:-minioadmin}35 MINIO_ROOT_PASSWORD: ${MINIO_PASSWORD:-minioadmin}36 volumes: 37 - minio3_data:/data38 networks: 39 - minio-network4041 minio4: 42 image: minio/minio:latest43 container_name: minio444 restart: unless-stopped45 command: server --console-address ":9001" http://minio{1...4}/data46 environment: 47 MINIO_ROOT_USER: ${MINIO_USER:-minioadmin}48 MINIO_ROOT_PASSWORD: ${MINIO_PASSWORD:-minioadmin}49 volumes: 50 - minio4_data:/data51 networks: 52 - minio-network5354 nginx: 55 image: nginx:alpine56 container_name: minio-lb57 restart: unless-stopped58 ports: 59 - "${MINIO_PORT:-9000}:9000"60 - "${CONSOLE_PORT:-9001}:9001"61 volumes: 62 - ./nginx.conf:/etc/nginx/nginx.conf:ro63 depends_on: 64 - minio165 - minio266 - minio367 - minio468 networks: 69 - minio-network7071volumes: 72 minio1_data: 73 minio2_data: 74 minio3_data: 75 minio4_data: 7677networks: 78 minio-network: 79 driver: bridge.env Template
.env
1# MinIO Distributed2MINIO_PORT=90003CONSOLE_PORT=90014MINIO_USER=minioadmin5MINIO_PASSWORD=minioadminUsage Notes
- 1API at http://localhost:9000
- 2Console at http://localhost:9001
- 3Create nginx.conf for load balancing
- 4Erasure coded for data protection
Individual Services(5 services)
Copy individual services to mix and match with your existing compose files.
minio1
minio1:
image: minio/minio:latest
container_name: minio1
restart: unless-stopped
command: server --console-address ":9001" http://minio{1...4}/data
environment:
MINIO_ROOT_USER: ${MINIO_USER:-minioadmin}
MINIO_ROOT_PASSWORD: ${MINIO_PASSWORD:-minioadmin}
volumes:
- minio1_data:/data
networks:
- minio-network
minio2
minio2:
image: minio/minio:latest
container_name: minio2
restart: unless-stopped
command: server --console-address ":9001" http://minio{1...4}/data
environment:
MINIO_ROOT_USER: ${MINIO_USER:-minioadmin}
MINIO_ROOT_PASSWORD: ${MINIO_PASSWORD:-minioadmin}
volumes:
- minio2_data:/data
networks:
- minio-network
minio3
minio3:
image: minio/minio:latest
container_name: minio3
restart: unless-stopped
command: server --console-address ":9001" http://minio{1...4}/data
environment:
MINIO_ROOT_USER: ${MINIO_USER:-minioadmin}
MINIO_ROOT_PASSWORD: ${MINIO_PASSWORD:-minioadmin}
volumes:
- minio3_data:/data
networks:
- minio-network
minio4
minio4:
image: minio/minio:latest
container_name: minio4
restart: unless-stopped
command: server --console-address ":9001" http://minio{1...4}/data
environment:
MINIO_ROOT_USER: ${MINIO_USER:-minioadmin}
MINIO_ROOT_PASSWORD: ${MINIO_PASSWORD:-minioadmin}
volumes:
- minio4_data:/data
networks:
- minio-network
nginx
nginx:
image: nginx:alpine
container_name: minio-lb
restart: unless-stopped
ports:
- ${MINIO_PORT:-9000}:9000
- ${CONSOLE_PORT:-9001}:9001
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- minio1
- minio2
- minio3
- minio4
networks:
- minio-network
Quick Start
terminal
1# 1. Create the compose file2cat > docker-compose.yml << 'EOF'3services:4 minio1:5 image: minio/minio:latest6 container_name: minio17 restart: unless-stopped8 command: server --console-address ":9001" http://minio{1...4}/data9 environment:10 MINIO_ROOT_USER: ${MINIO_USER:-minioadmin}11 MINIO_ROOT_PASSWORD: ${MINIO_PASSWORD:-minioadmin}12 volumes:13 - minio1_data:/data14 networks:15 - minio-network1617 minio2:18 image: minio/minio:latest19 container_name: minio220 restart: unless-stopped21 command: server --console-address ":9001" http://minio{1...4}/data22 environment:23 MINIO_ROOT_USER: ${MINIO_USER:-minioadmin}24 MINIO_ROOT_PASSWORD: ${MINIO_PASSWORD:-minioadmin}25 volumes:26 - minio2_data:/data27 networks:28 - minio-network2930 minio3:31 image: minio/minio:latest32 container_name: minio333 restart: unless-stopped34 command: server --console-address ":9001" http://minio{1...4}/data35 environment:36 MINIO_ROOT_USER: ${MINIO_USER:-minioadmin}37 MINIO_ROOT_PASSWORD: ${MINIO_PASSWORD:-minioadmin}38 volumes:39 - minio3_data:/data40 networks:41 - minio-network4243 minio4:44 image: minio/minio:latest45 container_name: minio446 restart: unless-stopped47 command: server --console-address ":9001" http://minio{1...4}/data48 environment:49 MINIO_ROOT_USER: ${MINIO_USER:-minioadmin}50 MINIO_ROOT_PASSWORD: ${MINIO_PASSWORD:-minioadmin}51 volumes:52 - minio4_data:/data53 networks:54 - minio-network5556 nginx:57 image: nginx:alpine58 container_name: minio-lb59 restart: unless-stopped60 ports:61 - "${MINIO_PORT:-9000}:9000"62 - "${CONSOLE_PORT:-9001}:9001"63 volumes:64 - ./nginx.conf:/etc/nginx/nginx.conf:ro65 depends_on:66 - minio167 - minio268 - minio369 - minio470 networks:71 - minio-network7273volumes:74 minio1_data:75 minio2_data:76 minio3_data:77 minio4_data:7879networks:80 minio-network:81 driver: bridge82EOF8384# 2. Create the .env file85cat > .env << 'EOF'86# MinIO Distributed87MINIO_PORT=900088CONSOLE_PORT=900189MINIO_USER=minioadmin90MINIO_PASSWORD=minioadmin91EOF9293# 3. Start the services94docker compose up -d9596# 4. View logs97docker compose logs -fOne-Liner
Run this command to download and set up the recipe in one step:
terminal
1curl -fsSL https://docker.recipes/api/recipes/minio-distributed/run | bashTroubleshooting
- MinIO nodes fail to start with 'Invalid command line arguments': Ensure all four container names (minio1-4) are resolvable within the Docker network and the server command syntax matches the node count
- Web console shows 'MinIO Console is loaded but API is not reachable': Verify that Nginx is properly forwarding requests and all MinIO containers are healthy using docker-compose ps
- S3 operations fail with 'NoSuchBucket' after cluster restart: MinIO distributed mode requires consistent node ordering - ensure containers always start with the same names and network configuration
- High memory usage and performance degradation: MinIO caches frequently accessed objects in RAM - monitor memory usage and consider increasing container memory limits or reducing concurrent operations
- Nginx returns 502 Bad Gateway errors: Check if all four MinIO nodes are running and accessible on port 9000 within the Docker network using docker exec commands
- Data inconsistency after node failure: Allow MinIO's healing process to complete automatically - this can take time depending on data volume and may require manual triggering via mc admin heal command
Community Notes
Loading...
Loading notes...
Download Recipe Kit
Get all files in a ready-to-deploy package
Includes docker-compose.yml, .env template, README, and license
Ad Space
Shortcuts: C CopyF FavoriteD Download