NEWS Earn Money with Onidel Cloud! Affiliate Program Details - Check it out

How to Deploy a Highly Available MinIO Cluster on 4 Ubuntu 24.04 VPS with Docker Compose, Erasure Coding, S3‑Compatible API, and TLS (2025 Tutorial)

Introduction

Building a highly available object storage solution requires distributed storage that can survive node failures while maintaining data integrity. MinIO provides enterprise-grade object storage with S3 compatibility, making it an excellent self-hosted alternative to cloud storage services.

In this comprehensive tutorial, you’ll learn how to deploy a production-ready MinIO cluster across four Ubuntu 24.04 VPS instances using Docker Compose. We’ll implement erasure coding for data redundancy, configure TLS encryption, and establish a fully distributed object storage cluster that can tolerate multiple node failures.

By the end of this guide, you’ll have a robust, S3-compatible storage cluster suitable for VPS backups, application data, and enterprise workloads.

Prerequisites

Before starting this deployment, ensure you have:

  • Four VPS instances running Ubuntu 24.04 LTS with minimum 4GB RAM and 50GB storage each
  • Root or sudo access on all servers
  • Docker and Docker Compose installed on all nodes
  • Network connectivity between all nodes on ports 9000 and 9001
  • Domain name or static IPs for cluster access
  • SSL certificates (Let’s Encrypt or your CA)

Resource Requirements:

  • CPU: 2+ cores per node
  • RAM: 4GB minimum, 8GB recommended per node
  • Storage: 50GB+ per node for data drives
  • Network: 1Gbps interconnect preferred

Step-by-Step Tutorial

Step 1: Install Docker on All Nodes

Execute these commands on each of your four Ubuntu 24.04 servers:

# Update system packages
sudo apt update && sudo apt upgrade -y

# Install Docker
sudo apt install -y apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

# Enable Docker service
sudo systemctl enable --now docker
sudo usermod -aG docker $USER

Step 2: Configure Cluster Networking

Set hostnames and configure /etc/hosts on all nodes. Replace IPs with your actual server addresses:

# Configure /etc/hosts on all nodes
sudo tee -a /etc/hosts << 'EOF'
10.0.1.10 minio-01
10.0.1.11 minio-02
10.0.1.12 minio-03
10.0.1.13 minio-04
EOF

Step 3: Create Directory Structure

Create the necessary directories on each node:

# Create MinIO directories
sudo mkdir -p /opt/minio/{data1,data2,config,certs}
sudo chown -R 1001:1001 /opt/minio
sudo chmod -R 755 /opt/minio

Step 4: Generate TLS Certificates

For production environments, use proper certificates. For testing, generate self-signed certificates:

# Generate self-signed certificates (replace with your domain)
sudo openssl req -new -x509 -days 365 -nodes \
  -out /opt/minio/certs/public.crt \
  -keyout /opt/minio/certs/private.key \
  -subj "/C=US/ST=CA/L=SF/O=MinIO/OU=IT/CN=minio.example.com"

# Set proper permissions
sudo chmod 644 /opt/minio/certs/public.crt
sudo chmod 600 /opt/minio/certs/private.key
sudo chown -R 1001:1001 /opt/minio/certs

Step 5: Create Docker Compose Configuration

Create the following Docker Compose file on each node, adjusting the server addresses:

# /opt/minio/docker-compose.yml
version: '3.8'

services:
  minio:
    image: quay.io/minio/minio:RELEASE.2024-12-13T22-19-12Z
    hostname: minio-01  # Change per node: minio-01, minio-02, etc.
    container_name: minio
    command: >
      server --console-address ':9001'
      http://minio-01/opt/minio/data1 http://minio-01/opt/minio/data2
      http://minio-02/opt/minio/data1 http://minio-02/opt/minio/data2
      http://minio-03/opt/minio/data1 http://minio-03/opt/minio/data2
      http://minio-04/opt/minio/data1 http://minio-04/opt/minio/data2
    environment:
      - MINIO_ROOT_USER=minioadmin
      - MINIO_ROOT_PASSWORD=your_secure_password_here
      - MINIO_SERVER_URL=https://minio.example.com:9000
      - MINIO_BROWSER_REDIRECT_URL=https://minio.example.com:9001
    volumes:
      - /opt/minio/data1:/opt/minio/data1
      - /opt/minio/data2:/opt/minio/data2
      - /opt/minio/certs:/root/.minio/certs
    ports:
      - "9000:9000"
      - "9001:9001"
    networks:
      - minio-cluster
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
      interval: 30s
      timeout: 20s
      retries: 3

networks:
  minio-cluster:
    driver: bridge

Step 6: Configure Firewall Rules

Configure UFW to allow cluster communication:

# Enable UFW and allow SSH
sudo ufw --force enable
sudo ufw allow ssh

# Allow MinIO ports from cluster nodes
sudo ufw allow from 10.0.1.0/24 to any port 9000
sudo ufw allow from 10.0.1.0/24 to any port 9001

# Allow public access (adjust as needed)
sudo ufw allow 9000/tcp
sudo ufw allow 9001/tcp

Step 7: Deploy the MinIO Cluster

Start the cluster on all nodes simultaneously:

# Start MinIO on all nodes (run on each server)
cd /opt/minio
sudo docker compose up -d

# Verify cluster status
sudo docker compose logs -f

Step 8: Verify Cluster Health

Check cluster connectivity and health:

# Check container status
sudo docker compose ps

# Test cluster health
curl -k https://minio-01:9000/minio/health/cluster

# Access MinIO Console
echo "MinIO Console: https://your-domain:9001"
echo "Username: minioadmin"
echo "Password: your_secure_password_here"

Best Practices

Security Hardening

  • Change default credentials: Always use strong, unique passwords for MinIO root user
  • Use proper TLS certificates: Deploy Let’s Encrypt or CA-signed certificates for production
  • Network segmentation: Place MinIO nodes in a private network when possible
  • Access policies: Implement least-privilege IAM policies for applications

Performance Optimization

  • Storage backend: Use NVMe SSDs for optimal performance
  • Network bandwidth: Ensure adequate inter-node connectivity
  • Memory allocation: Allocate sufficient RAM for caching and metadata operations
  • Monitoring: Implement Prometheus metrics for cluster monitoring

Backup and Disaster Recovery

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

# Configure backup destination
mc alias set local https://minio.example.com:9000 minioadmin your_password
mc alias set remote https://backup-location.com access_key secret_key

# Create backup script
mc mirror local/bucket-name remote/backup-bucket

Conclusion

You’ve successfully deployed a highly available MinIO cluster with erasure coding across four Ubuntu 24.04 servers. This configuration provides excellent data durability, S3 compatibility, and can survive multiple node failures while maintaining service availability.

The cluster offers enterprise-grade features including TLS encryption, distributed storage, and automatic healing capabilities. Consider integrating this setup with your existing backup strategies or as a cost-effective alternative to commercial object storage services.

For production deployments requiring high-performance infrastructure, explore our Singapore VPS or Amsterdam VPS solutions with NVMe storage and high-availability features that complement your MinIO cluster deployment.

Share your love