MinIO
Self-hosted S3-compatible object storage with MinIO, Docker installation, bucket management, access keys and Nginx reverse proxy
MinIO is self-hosted object storage compatible with AWS S3 APIs. Ideal for Restic/Borg backups, application storage, and S3 replacement for development and production environments. Fully compatible with AWS SDK.
Installation with Docker Compose
Create a docker-compose.yml file:
services:
minio:
image: minio/minio:latest
container_name: minio
restart: unless-stopped
ports:
- "127.0.0.1:9000:9000" # S3 API
- "127.0.0.1:9001:9001" # Web Console
environment:
MINIO_ROOT_USER: admin
MINIO_ROOT_PASSWORD: secure_password_here
volumes:
- /opt/minio/data:/data
command: server /data --console-address ":9001"Start the service:
docker compose up -dMINIO_ROOT_PASSWORD must be at least 8 characters, otherwise MinIO will not start.
Web Console Access
Access the MinIO console at http://IP:9001 with credentials:
- Username:
admin - Password:
secure_password_here
Nginx Reverse Proxy Configuration
Expose MinIO on your domain with SSL support. Configure both S3 API (port 9000) and console (port 9001):
upstream minio_api {
server 127.0.0.1:9000;
}
upstream minio_console {
server 127.0.0.1:9001;
}
server {
listen 80;
server_name s3.yourdomain.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name s3.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/s3.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/s3.yourdomain.com/privkey.pem;
location / {
proxy_pass http://minio_api;
proxy_set_header Host $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;
}
}
server {
listen 443 ssl http2;
server_name console.yourdomain.com;
ssl_certificate /etc/letsencrypt/live/console.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/console.yourdomain.com/privkey.pem;
location / {
proxy_pass http://minio_console;
proxy_set_header Host $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;
}
}MinIO Client (mc) CLI
Install the MinIO command-line client:
curl https://dl.min.io/client/mc/release/linux-amd64/mc -o /usr/local/bin/mc
chmod +x /usr/local/bin/mcConfigure an alias:
mc alias set myminio http://localhost:9000 admin secure_password_hereBucket Operations
# List buckets
mc ls myminio
# Create bucket
mc mb myminio/mybucket
# Upload file
mc cp file.txt myminio/mybucket/
# Mirror local folder to bucket
mc mirror /local/folder myminio/mybucket/
# List bucket contents
mc ls myminio/mybucket/
# Remove bucket (must be empty)
mc rb myminio/mybucket
# Remove bucket with contents
mc rb myminio/mybucket --forceAccess Keys for Applications
Create access keys for applications via the web console or CLI:
mc admin user add myminio myappuser myapppassword
mc admin policy attach myminio readwrite --user=myappuserCreate a policy with limited permissions (single bucket access):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
],
"Resource": "arn:aws:s3:::mybucket/*"
},
{
"Effect": "Allow",
"Action": ["s3:ListBucket"],
"Resource": "arn:aws:s3:::mybucket"
}
]
}MinIO as Backend for Restic
Use MinIO as an S3 backend for Restic backups:
export AWS_ACCESS_KEY_ID=myaccesskey
export AWS_SECRET_ACCESS_KEY=mysecretkey
# Initialize repository
restic -r s3:http://localhost:9000/restic-bucket init
# Backup directory
restic -r s3:http://localhost:9000/restic-bucket backup /home
# List snapshots
restic -r s3:http://localhost:9000/restic-bucket snapshots
# Restore
restic -r s3:http://localhost:9000/restic-bucket restore latest --target /restore/pathMinIO with AWS CLI
Use the AWS CLI with MinIO by specifying the endpoint:
# List buckets
aws --endpoint-url http://localhost:9000 s3 ls
# Copy file
aws --endpoint-url http://localhost:9000 s3 cp file.txt s3://mybucket/
# Sync directory
aws --endpoint-url http://localhost:9000 s3 sync /local/path s3://mybucket/
# Remove object
aws --endpoint-url http://localhost:9000 s3 rm s3://mybucket/file.txtBucket Versioning and Lifecycle Policies
Enable versioning to keep object history:
mc version enable myminio/mybucketConfigure lifecycle policies to auto-delete old versions after N days. In the web console, go to Bucket > Lifecycle > Add Lifecycle Rule or use mc:
mc ilm import myminio/mybucket < lifecycle.jsonExample lifecycle policy (keep versions for 30 days):
{
"Rules": [
{
"ID": "delete-old-versions",
"Status": "Enabled",
"NoncurrentVersionExpiration": {
"NoncurrentDays": 30
}
}
]
}Monitoring and Health Check
MinIO provides a health check endpoint:
curl http://localhost:9000/minio/health/liveUse this for container health checks in docker-compose:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 30s
timeout: 10s
retries: 3
start_period: 10sMinIO is compatible with any SDK supporting AWS S3 (boto3 for Python, AWS SDK for JavaScript, Go SDK, etc.). Simply point your application to the MinIO endpoint instead of AWS S3.