TL;DR — Quick Summary
Deploy MinIO as a self-hosted S3-compatible object store. Configure buckets, access policies, TLS encryption, and troubleshoot common connectivity errors.
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
| Command | What it does |
|---|---|
mc mb myminio/my-bucket | Create a new bucket |
mc cp file.txt myminio/my-bucket/ | Upload a file |
mc ls myminio/my-bucket | List bucket contents |
mc mirror /local/dir myminio/my-bucket | Sync a local directory to a bucket |
mc anonymous set download myminio/my-bucket | Make 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
| Problem | Solution |
|---|---|
SignatureDoesNotMatch | Verify access/secret keys match; ensure client uses S3v4 signatures |
Connection refused on port 9000 | Check MinIO is running (systemctl status minio); verify firewall allows 9000/9001 |
| Slow uploads/downloads | Use mc mirror with --multi-threaded for parallelism; check disk I/O with iotop |
| ”Bucket already exists” error | Bucket names are global within the instance; choose a unique name |
| TLS certificate errors | Place 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 andboto3/aws-clifor application integration. - Always use S3v4 signatures and
force_path_style: true. - Run as a systemd service in production with credentials in
/etc/default/minio.