How to Set Up Self-Hosted S3-Compatible Object Storage with MinIO

MinIO is a high-performance, self-hosted object storage server compatible with the S3 API — letting you run your own object storage on a VPS instead of paying for third-party storage, while keeping compatibility with S3-compatible tools and libraries.

Why Self-Host Object Storage

  • Full control over data location and retention
  • Potentially lower cost at scale compared to hosted providers
  • S3-compatible API means most existing tools/SDKs work without modification

Prerequisites

  • A VPS with adequate storage for your needs
  • Docker Engine installed

Step 1 — Run MinIO

docker run -d \
  --name minio \
  --restart unless-stopped \
  -p 9000:9000 \
  -p 9001:9001 \
  -e MINIO_ROOT_USER=admin \
  -e MINIO_ROOT_PASSWORD=CHANGE_ME_STRONG_PASSWORD \
  -v minio_data:/data \
  minio/minio server /data --console-address ":9001"

Port 9000 is the S3 API endpoint, port 9001 is the web console.

Step 2 — Allow the Required Ports

sudo ufw allow from YOUR_TRUSTED_IP to any port 9001
sudo ufw allow 9000/tcp

Restrict the console (9001) to trusted IPs; the API port (9000) needs broader access if your applications connect from elsewhere.

Step 3 — Access the Web Console

http://YOUR_SERVER_IP:9001

Log in with the root credentials set above.

Step 4 — Create a Bucket

In the console: Buckets → Create Bucket, name it (e.g. myapp-uploads).

Step 5 — Create an Access Key for Applications

Under Access Keys → Create access key — use this for application connections rather than the root credentials.

Step 6 — Add HTTPS

Route both the API and console through Nginx Proxy Manager (see How to Install Nginx Proxy Manager with Docker) with valid SSL — critical since credentials and data transfer over this connection.

Step 7 — Test with the AWS CLI

aws configure --profile minio
aws s3 ls --profile minio --endpoint-url https://storage.yourdomain.com

Uploading a Test File

aws s3 cp test.txt s3://myapp-uploads/ --profile minio --endpoint-url https://storage.yourdomain.com

Setting Bucket Policies

Configure public/private access per bucket through the console under bucket settings — keep buckets private by default, only making specific buckets/paths public if genuinely needed.

Setting Up Lifecycle Rules

In the console, configure automatic expiration/deletion rules per bucket — useful for temporary uploads or enforcing retention policies without manual cleanup scripts.

Backing Up MinIO Data

docker run --rm -v minio_minio_data:/data -v $(pwd):/backup alpine tar czf /backup/minio-backup.tar.gz /data

Alternatively, use MinIO's own replication features to sync to a second MinIO instance for redundancy.

Common Errors

"Access Denied" — verify you're using an access key with appropriate bucket permissions, not attempting an operation the key isn't authorized for.

Slow uploads/downloads — check your VPS's disk I/O performance and network bandwidth; object storage performance is directly tied to underlying disk speed.

Best Practices

  • Never use root credentials for application connections — create scoped access keys
  • Always run behind HTTPS
  • Keep buckets private by default, exposing only what's genuinely needed publicly

Continue Reading

Browse more articles in Object Storage, Messaging & APIs.

  • minio, self hosted s3, object storage, s3 compatible storage
  • 0 Users Found This Useful
Was this answer helpful?

Related Articles

How to Use Object Storage for Application File Uploads

Storing user-uploaded files directly on your application server's disk creates scaling and...

How to Install and Configure RabbitMQ on a VPS

RabbitMQ is a widely-used, robust message broker — enabling applications to communicate...

How to Install and Configure Redis as a Message Queue

Redis, primarily known as a cache, also works well as a lightweight message queue for simpler use...

How to Build and Secure a REST API on a VPS

This guide covers the essential security and architecture practices for deploying a REST API on...

How to Design and Secure Webhook Endpoints

Webhooks let external services notify your application of events in real time. Since they accept...