Why MinIO?

AWS S3 is powerful but expensive and locked to Amazon’s cloud. MinIO gives you the same S3 API — on your own hardware. It’s used by organizations like:

  • Development teams who need a local S3 mock that uses the real S3 protocol.
  • On-premises enterprises with data sovereignty requirements.
  • Homelab enthusiasts who want object storage without cloud bills.

Prerequisites

  • Linux server (Ubuntu 22.04 or RHEL 9).
  • At least 4 GB RAM and a dedicated data disk.
  • Root or sudo access.

Step 1: Install MinIO

Single-Node Setup (Quickest)

# Download the binary
wget https://dl.min.io/server/minio/release/linux-amd64/minio
chmod +x minio
sudo mv minio /usr/local/bin/

# Create data directory
sudo mkdir -p /data/minio
sudo chown $(whoami):$(whoami) /data/minio

# Set root credentials
export MINIO_ROOT_USER=minioadmin
export MINIO_ROOT_PASSWORD=StrongPassword123!

# Start MinIO
minio server /data/minio --console-address ":9001"
  • API endpoint: http://your-server:9000
  • Web Console: http://your-server:9001

Systemd Service (Production)

# /etc/systemd/system/minio.service
[Unit]
Description=MinIO Object Storage
After=network.target

[Service]
User=minio-user
EnvironmentFile=/etc/default/minio
ExecStart=/usr/local/bin/minio server /data/minio --console-address ":9001"
Restart=always

[Install]
WantedBy=multi-user.target

Environment file /etc/default/minio:

MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=StrongPassword123!
MINIO_VOLUMES="/data/minio"
sudo systemctl daemon-reload
sudo systemctl enable --now minio

Step 2: Install the MinIO Client (mc)

wget https://dl.min.io/client/mc/release/linux-amd64/mc
chmod +x mc
sudo mv mc /usr/local/bin/

# Configure an alias pointing to your MinIO instance
mc alias set myminio http://localhost:9000 minioadmin StrongPassword123!

Common mc Commands

CommandWhat it does
mc mb myminio/my-bucketCreate a new bucket
mc cp file.txt myminio/my-bucket/Upload a file
mc ls myminio/my-bucketList bucket contents
mc mirror /local/dir myminio/my-bucketSync a local directory to a bucket
mc anonymous set download myminio/my-bucketMake a bucket publicly readable

Step 3: Connect Applications (S3 SDK)

Any S3-compatible SDK works with MinIO. Here’s a Python (boto3) example:

import boto3

s3 = boto3.client(
    's3',
    endpoint_url='http://minio-server:9000',
    aws_access_key_id='minioadmin',
    aws_secret_access_key='StrongPassword123!',
    config=boto3.session.Config(signature_version='s3v4'),
)

# Upload a file
s3.upload_file('local-file.pdf', 'my-bucket', 'remote-file.pdf')

# List objects
for obj in s3.list_objects_v2(Bucket='my-bucket')['Contents']:
    print(obj['Key'])

Key point: Always set force_path_style: true (or equivalent) when using non-AWS S3 endpoints, and use Signature Version 4.


Troubleshooting

ProblemSolution
SignatureDoesNotMatchVerify access/secret keys match; ensure client uses S3v4 signatures
Connection refused on port 9000Check MinIO is running (systemctl status minio); verify firewall allows 9000/9001
Slow uploads/downloadsUse mc mirror with --multi-threaded for parallelism; check disk I/O with iotop
”Bucket already exists” errorBucket names are global within the instance; choose a unique name
TLS certificate errorsPlace public.crt + private.key in ~/.minio/certs/; restart MinIO

Summary

  • MinIO is a drop-in S3 replacement you can host yourself.
  • Use mc (MinIO Client) for CLI operations and boto3/aws-cli for application integration.
  • Always use S3v4 signatures and force_path_style: true.
  • Run as a systemd service in production with credentials in /etc/default/minio.