Why Self-Host S3-Compatible Storage with MinIO?
Modern cloud-native applications decouple compute from file storage. Storing user media uploads, PDF documents, database backups, and machine learning models in AWS S3 or Google Cloud Storage is standard practice. However, enterprise cloud providers charge steep monthly storage rates ($0.023/GB) and aggressive egress bandwidth fees ($0.09/GB) that quickly become exorbitant for media-heavy platforms.
MinIO is a high-performance, open-source S3-compatible object storage server written in Go. Capable of saturating 10GbE network interfaces with read/write throughput exceeding 10 GB/sec, self-hosting MinIO on an NVMe Cloud VPS provides 100% S3 API compatibility with existing SDKs (AWS SDK, Boto3, Strapi, Next.js) at zero egress bandwidth costs.
In this technical implementation guide, we will install MinIO as a systemd service on Ubuntu 24.04/22.04 LTS, secure storage with Let’s Encrypt TLS certificates, configure the MinIO Web Console, and manage buckets with the MinIO Client (mc) utility.
Step 1: Installing MinIO Server Binary on Ubuntu VPS
Download the official pre-compiled Linux deb package for MinIO:
# Download latest MinIO Debian package
cd /tmp
wget https://dl.min.io/server/minio/release/linux-amd64/archive/minio_20240803043323.0.0_amd64.deb
# Install package
sudo dpkg -i minio_20240803043323.0.0_amd64.deb
# Verify installation
minio --version
Step 2: Creating Dedicated User & Data Storage Directory
# Create system user and group
sudo useradd -r minio-user -s /sbin/nologin
sudo groupadd minio-user
# Create persistent storage directories
sudo mkdir -p /mnt/data /etc/minio
sudo chown -R minio-user:minio-user /mnt/data /etc/minio
Step 3: Configuring MinIO Environment Variables
Create the configuration file at /etc/default/minio with strong cryptographic credentials:
# Storage Volume Path
MINIO_VOLUMES="/mnt/data"
# API and Web Console Listening Addresses
MINIO_OPTS="--address 127.0.0.1:9000 --console-address 127.0.0.1:9001"
# Root Administrator Credentials (Minimum 8 chars)
MINIO_ROOT_USER="minio_admin_user"
MINIO_ROOT_PASSWORD="UltraSecureMinioPassword2026!"
# Public Base Server URL
MINIO_SERVER_URL="https://s3.example.com"
MINIO_BROWSER_REDIRECT_URL="https://console-s3.example.com"
Enable and start the MinIO systemd service:
sudo systemctl enable --now minio
sudo systemctl status minio --no-pager
Step 4: Nginx Reverse Proxy with TLS for S3 API & Web Console
Create /etc/nginx/sites-available/minio.conf to route API traffic and Console management:
# 1. MinIO S3 API Endpoint (s3.example.com)
server {
listen 80;
server_name s3.example.com;
client_max_body_size 1000M;
location / {
proxy_pass http://127.0.0.1:9000;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 300;
proxy_http_version 1.1;
chunked_transfer_encoding off;
}
}
# 2. MinIO Web Console GUI (console-s3.example.com)
server {
listen 80;
server_name console-s3.example.com;
location / {
proxy_pass http://127.0.0.1:9001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Enable the site and issue SSL certificates:
sudo ln -s /etc/nginx/sites-available/minio.conf /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
sudo certbot --nginx -d s3.example.com -d console-s3.example.com
Step 5: Managing Buckets with MinIO Client (mc)
# Download and install mc client
curl https://dl.min.io/client/mc/release/linux-amd64/mc -o /usr/local/bin/mc
chmod +x /usr/local/bin/mc
# Configure local alias
mc alias set local https://s3.example.com minio_admin_user UltraSecureMinioPassword2026!
# Create a public bucket for website uploads
mc mb local/media-uploads
mc anonymous set download local/media-uploads
MinIO vs AWS S3 Cost and Performance Matrix
| Metric / Feature | Self-Hosted MinIO on NVMe VPS | AWS S3 Standard |
|---|---|---|
| Egress Bandwidth Cost | $0.00 / Unmetered | $0.09 per GB transferred |
| Read/Write Throughput | Direct NVMe Bus (> 1,000 MB/s) | Network-throttled API requests |
| API Compatibility | 100% S3 Compliant (v4 signatures) | Native AWS S3 API |
Configuring Bucket Lifecycle Policies & Auto-Expiration
Avoid accumulating terabytes of temporary log files or old database backup archives by defining automated bucket lifecycle retention policies using the MinIO Client (mc):
# Create lifecycle rule: Auto-delete files older than 30 days in 'backups' bucket
mc ilm add --expiry-days 30 local/backups
# Inspect active lifecycle rules
mc ilm ls local/backups
Enabling Server-Side Encryption (SSE-S3) for Compliance
Protect sensitive financial documents or client backups with automated AES-256 server-side encryption:
# Enable automatic encryption on bucket
mc encrypt set sse-s3 local/secure-documents
# Verify encryption configuration
mc encrypt info local/secure-documents
Connecting MinIO to WordPress with Offload Media Plugin
Seamlessly offload WordPress media library uploads to MinIO by installing the WP Offload Media or Media Cloud plugin, specifying your custom endpoint (https://s3.example.com) and IAM credentials. All image thumbnails are served directly from MinIO NVMe storage!
Configuring MinIO Prometheus Metrics & Grafana Dashboards
MinIO exports comprehensive real-time storage metrics—including active S3 read/write IOPS, network transfer rates, bucket capacity utilization, and API error codes—via native Prometheus endpoints:
# Scrape MinIO metrics in Prometheus configuration (/etc/prometheus/prometheus.yml)
scrape_configs:
- job_name: 'minio'
bearer_token: 'YourMinioMetricsJwtToken'
metrics_path: '/minio/v2/metrics/cluster'
static_configs:
- targets: ['127.0.0.1:9000']
Setting Up Multi-Site Active-Active Bucket Replication
For disaster recovery across multiple geographic regions, MinIO supports automated, asynchronous bucket-to-bucket replication over HTTPS:
# Configure replication target between two MinIO instances
mc admin bucket remote add local/media-uploads https://minio-backup.example.com/media-uploads --service "replication" --access-key "KEY" --secret-key "SECRET"
# Enable bidirectional site replication
mc replicate add local/media-uploads --priority "1"
Recommended Related Technical Guides
Deploy High-Speed S3 Object Storage on CpanelFree
Scale your media files and backups with pure NVMe storage arrays, unmetered bandwidth, and 100% free hosting and VPS options.
🔗 Recommended Related Technical Guides:
- How to Host a Website for Free Forever: Complete Beginner Guide (2026)
- Top 5 Free WordPress Hosting Services with 1-Click Softaculous Installer
- How to Automatically Backup Your Linux VPS to Cloud Storage (S3 / Rclone Guide)
- How to Configure Mailcow: Dockerized Email Server on Ubuntu VPS (2026)
- Explore $0 Free cPanel Web Hosting Plans (NVMe SSD, AutoSSL)
Deploy Fast, Reliable Web Hosting on CpanelFree
Get genuine cPanel control, unmetered NVMe SSD storage, and free AutoSSL at $0 cost forever.

