Software & Configuration

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 -d

MINIO_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/mc

Configure an alias:

mc alias set myminio http://localhost:9000 admin secure_password_here

Bucket 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 --force

Access 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=myappuser

Create 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/path

MinIO 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.txt

Bucket Versioning and Lifecycle Policies

Enable versioning to keep object history:

mc version enable myminio/mybucket

Configure 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.json

Example 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/live

Use 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: 10s

MinIO 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.

On this page